通知
frameworks\base\services\core\java\com\android\server\notification\NotificationManagerService.java
public class NotificationManagerService extends SystemService {
中定义一个私有变量实现了INotificationManager
private final IBinder mService = new INotificationManager.Stub() {
public void onStart() {
publishBinderService(Context.NOTIFICATION_SERVICE, mService);
publishLocalService(NotificationManagerInternal.class, mInternalService);
}
获取服务
frameworks\base\core\java\android\app\NotificationManager.java
public class NotificationManager
{
private static INotificationManager sService;
/** @hide */
static public INotificationManager getService()
{
if (sService != null) {
return sService;
}
IBinder b = ServiceManager.getService("notification");
sService = INotificationManager.Stub.asInterface(b);
return sService;
}
public static NotificationManager from(Context context) {
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
enqueueNotificationInternal --》
buzzBeepBlinkLocked --》
updateLightsLocked
StatusBarNotification.java
一个通知的唯一标识key
user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid
mNotificationList <---> NotificationRecord,index
mNotificationsByKey <---> NotificationRecord,key
frameworks\base\services\core\java\com\android\server\notification\NotificationUsageStats.java
notification_log.db
灯服务
public class LightsService extends SystemService {
private final class LightImpl extends Light {
private static native long init_native();
private static native void finalize_native(long ptr);
static native void setLight_native(long ptr, int light, int color, int mode,
int onMS, int offMS, int brightnessMode);
public void onStart() {
publishLocalService(LightsManager.class, mService);
}
private final LightsManager mService = new LightsManager() {
@Override
public Light getLight(int id) {
if (id < LIGHT_ID_COUNT) {
return mLights[id];
} else {
return null;
}
}
};
LightService内部类LightImpl继承Light,并通过native setLight_native
方法实现了灯操作。
frameworks\base\services\core\jni\com_android_server_lights_LightsService.cpp
Native 方法setLight_native 再调用Hal 层open_lights
vendor\mediatek\proprietary\hardware\liblights\lights.c
注册服务
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks\base\services\java\com\android\server\SystemServer.java
// Manages LEDs and display backlight so we need it to bring up the display.345 mSystemServiceManager.startService(LightsService.class);
mSystemServiceManager.startService(NotificationManagerService.class);
notification = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
frameworks\base\telephony\java\android\telephony\TelephonyManager.java
public static final String ACTION_PHONE_STATE_CHANGED =
"android.intent.action.PHONE_STATE";
frameworks/base/core/res/AndroidManifest.xml
<protected-broadcast android:name="android.intent.action.PHONE_STATE" />
锁屏
frameworks\base\packages\SystemUI\src\com\android\systemui\keyguard\KeyguardViewMediator.java
private void setupLocked() {
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWM = WindowManagerGlobal.getWindowManagerService();
mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
mShowKeyguardWakeLock.setReferenceCounted(false);
frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
{
public void onStart() {
publishBinderService(Context.POWER_SERVICE, new BinderService());
publishLocalService(PowerManagerInternal.class, new LocalService());
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
//内部类
private final class BinderService extends IPowerManager.Stub
{
。。。。
}
public void systemReady(IAppOpsService appOps) {
mLightsManager = getLocalService(LightsManager.class);
mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
mButtonLight = mLightsManager.getLight(LightsManager.LIGHT_ID_BUTTONS);
mBacklight = mLightsManager.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
}
private boolean updateDisplayPowerStateLocked(int dirty) {
// Button backlight begin
if ((mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT) && (mWakefulness == WAKEFULNESS_AWAKE) && !mIPOShutdown && !mShutdownFlag) {
if ( ( (mWakeLockSummary & WAKE_LOCK_BUTTON_BRIGHT) != 0 ) ||
( (mUserActivitySummary & USER_ACTIVITY_BUTTON_BRIGHT) != 0) ) {
mButtonLight.setBrightness(screenBrightness);
} else {
mButtonLight.turnOff();
}
} else {
mButtonLight.turnOff();
}
// Button backlight end
}
frameworks/base/core/res/AndroidManifest.xml
}
frameworks/base/core/res/AndroidManifest.xml
唤醒锁
frameworks\base\services\core\java\com\android\server\power\Notifier.java
电池指示灯相关
frameworks\base\services\core\java\com\android\server\BatteryService.java
Attention 灯相关
frameworks\base\core\java\android\os\IPowerManager.aidl
// sets the attention light (used by phone app only)
void setAttentionLight(boolean on, int color);
按键输入
frameworks/native/services/inputflinger/InputDispatcher.cpp
// Poke user activity for this event.
if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
pokeUserActivityLocked(mPendingEvent);
}
放入消息队列
void pokeUserActivityLocked(mPendingEvent){
case EventEntry::TYPE_KEY: {
const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
return;
}
eventType = USER_ACTIVITY_EVENT_BUTTON;
break;
}
}
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doPokeUserActivityLockedInterruptible);
commandEntry->eventTime = eventEntry->eventTime;
commandEntry->userActivityEventType = eventType;
}
回调函数
void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
mLock.unlock();
mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
mLock.lock();
}
// Poke user activity for this event.
if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
pokeUserActivityLocked(mPendingEvent);
}
构造函数
InputDispatcher::CommandEntry::CommandEntry(Command command) :
command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0),
seq(0), handled(false) {
}
struct KeyEntry : EventEntry {
keyCode
}
函数调用关系:
userActivityFromNative -->
frameworks\base\services\core\jni\com_android_server_power_PowerManagerService.cpp
android_server_PowerManagerService_userActivity
frameworks\base\services\core\jni\com_android_server_input_InputManagerService.cpp
pokeUserActivity
adb shell setprop sys.inputlog.enabled true
adb shell dumpsys input
屏膜状态判断
通过PowerManager的isScreenOn方法,代码如下
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();
//如果为true,则表示屏幕“亮”了,处于解锁状态或未解锁状态
否则屏幕“暗”了
通过KeyguardManager的inKeyguardRestrictedInputMode方法,代码如下:
KeyguardManager mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
boolean flag = mKeyguardManager.inKeyguardRestrictedInputMode();
如果flag为true,表示有两种状态:a、屏幕是黑的 b、亮屏未解锁状态
如果flag为false,表示目前未锁屏
注明:上面的两种方法,也可以通过反射机制来调用。
下面以第一个方法为例说明一下。
private static Method mReflectScreenState;
try {
mReflectScreenState = PowerManager.class.getMethod("isScreenOn", new Class[] {});
PowerManager pm = (PowerManager) context.getSystemService(Activity.POWER_SERVICE);
boolean isScreenOn= (Boolean) mReflectScreenState.invoke(pm);
} catch (Exception e) {
e.printStackTrace()
}
现在介绍第二类方法(接收系统的广播):
接收系统广播事件,屏幕在三种状态(开屏、锁屏、解锁)之间变换的时候,系统都会发送广播,我们只需要监听这些广播即可。
代码如下:
private ScreenBroadcastReceiver mScreenReceiver;
private class ScreenBroadcastReceiver extends BroadcastReceiver {
private String action = null;
@Override
public void onReceive(Context context, Intent intent) {
action = intent.getAction();
if (Intent.ACTION_SCREEN_ON.equals(action)) {
// 开屏
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
// 锁屏
} else if (Intent.ACTION_USER_PRESENT.equals(action)) {
// 解锁
}
}
}
private void startScreenBroadcastReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
context.registerReceiver(mScreenReceiver, filter);
}
settings\src\main\java\com\android\settings\SecuritySettings.java
createPreferenceHierarchy()
onPreferenceTreeClick