这个类在PowerManagerService中是非常重要的,当PowerManagerService的状态改变时,都是靠这个类通知。比如常用的灭屏和亮屏广播,也是在这个类中发送的。
首先我们来看它在PowerManagerService构造函数中的初始化:
mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
mPolicy);
PowerManagerService把自己的main looper传进去了,说明在Notifier的消息处理是在PowerManagerService的主线程中,还有一点和之前的WakeLocks,和Display锁一样,这里也为Notifier创建了一个Broadcasts锁。
public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
IAppOpsService appOps, SuspendBlocker suspendBlocker,
WindowManagerPolicy policy) {
mContext = context;
mBatteryStats = batteryStats;
mAppOps = appOps;
mSuspendBlocker = suspendBlocker;
mPolicy = policy;
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
mHandler = new NotifierHandler(looper);
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
...
// Initialize interactive state for battery stats.
try {
mBatteryStats.noteInteractive(true);
} catch (RemoteException ex) { }
}
//
private final class NotifierHandler extends Handler {
public NotifierHandler(Looper looper) {
super(looper, null, true /*async*/);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_USER_ACTIVITY:
sendUserActivity();
break;
case MSG_BROADCAST:
sendNextBroadcast();
break;
case MSG_WIRELESS_CHARGING_STARTED:
playWirelessChargingStartedSound();
break;
case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
sendBrightnessBoostChangedBroadcast();
break;
}
}
}
在PowerManagerService的wakeUpNoUpdateLocked函数会调用如下函数:
mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);
再看下Notifier处理:
public void onWakeUp(String reason, int reasonUid, String opPackageName, int opUid) {
try {
mBatteryStats.noteWakeUp(reason, reasonUid);
if (opPackageName != null) {
mAppOps.noteOperation(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
}
} catch (RemoteException ex) {
// Ignore
}
}
在userActivityNoUpdateLocked函数中也会调用如下函数:
mNotifier.onUserActivity(event, uid);
我们看下Notifier的处理
public void onUserActivity(int event, int uid) {
try {
mBatteryStats.noteUserActivity(uid, event);
} catch (RemoteException ex) {
// Ignore
}
synchronized (mLock) {
if (!mUserActivityPending) {
mUserActivityPending = true;
Message msg = mHandler.obtainMessage(MSG_USER_ACTIVITY);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
}
}
消息处理函数为:sendUserActivity
private void sendUserActivity() {
synchronized (mLock) {
if (!mUserActivityPending) {
return;
}
mUserActivityPending = false;
}
mPolicy.userActivity();
}
最后是在PhoneWindowManager中处理好像是在keyguard中处理。
我们再来看updateScreenBrightnessBoostLocked函数,也会调用mNotifier.onScreenBrightnessBoostChanged函数
private void updateScreenBrightnessBoostLocked(int dirty) {
if ((dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0) {
if (mScreenBrightnessBoostInProgress) {
final long now = SystemClock.uptimeMillis();
mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
final long boostTimeout = mLastScreenBrightnessBoostTime +
SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
if (boostTimeout > now) {
Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, boostTimeout);
return;
}
}
mScreenBrightnessBoostInProgress = false;
mNotifier.onScreenBrightnessBoostChanged();
userActivityNoUpdateLocked(now,
PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
}
}
}
onScreenBrightnessBoostChanged函数,发送了消息
public void onScreenBrightnessBoostChanged() {
mSuspendBlocker.acquire();// 持锁了
Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
最后在sendBrightnessBoostChangedBroadcast处理了消息,发送广播。
private void sendBrightnessBoostChangedBroadcast() {
if (DEBUG) {
Slog.d(TAG, "Sending brightness boost changed broadcast.");
}
mContext.sendOrderedBroadcastAsUser(mScreenBrightnessBoostIntent, UserHandle.ALL, null,
mScreeBrightnessBoostChangedDone, mHandler, 0, null, null);
}
mScreeBrightnessBoostChangedDone函数是所有广播收到后处理mScreeBrightnessBoostChangedDone函数,mScreeBrightnessBoostChangedDone函数是在mHandler中进行处理。
mScreeBrightnessBoostChangedDone 中就是把之前的Broadcast锁释放了。
private final BroadcastReceiver mScreeBrightnessBoostChangedDone = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mSuspendBlocker.release();
}
};
在PowerManagerService的每个setWakefulnessLocked,都会调用mNotifier.onWakefulnessChangeStarted函数
private void setWakefulnessLocked(int wakefulness, int reason) {
if (mWakefulness != wakefulness) {
mWakefulness = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
}
}
Notifier的onWakefulnessChangeStarted函数:
public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
mHandler.post(new Runnable() {
@Override
public void run() {
mActivityManagerInternal.onWakefulnessChanged(wakefulness);//调用AMS的onWakefulnessChanged函数
}
});
// Handle any early interactive state changes.
// Finish pending incomplete ones from a previous cycle.
if (mInteractive != interactive) {//屏幕状态改变
// Finish up late behaviors if needed.
if (mInteractiveChanging) {
handleLateInteractiveChange();
}
// Start input as soon as we start waking up or going to sleep.
mInputManagerInternal.setInteractive(interactive);
mInputMethodManagerInternal.setInteractive(interactive);
// Notify battery stats.
try {
mBatteryStats.noteInteractive(interactive);
} catch (RemoteException ex) { }
// Handle early behaviors.
mInteractive = interactive;
mInteractiveChangeReason = reason;
mInteractiveChanging = true;
handleEarlyInteractiveChange();
}
}
我们先来看handleEarlyInteractiveChange函数
private void handleEarlyInteractiveChange() {
synchronized (mLock) {
if (mInteractive) {
// Waking up...
mHandler.post(new Runnable() {
@Override
public void run() {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0);
mPolicy.startedWakingUp();//调用PhoneWindowManager
}
});
// Send interactive broadcast.
mPendingInteractiveState = INTERACTIVE_STATE_AWAKE;
mPendingWakeUpBroadcast = true;
updatePendingBroadcastLocked();//发送亮屏广播
} else {
// Going to sleep...
// Tell the policy that we started going to sleep.
final int why = translateOffReason(mInteractiveChangeReason);
mHandler.post(new Runnable() {
@Override
public void run() {
mPolicy.startedGoingToSleep(why);//调用PhoneWindowManager
}
});
}
}
}
updatePendingBroadcastLocked发送消息处理广播,并且持锁Broadcast
private void updatePendingBroadcastLocked() {
if (!mBroadcastInProgress
&& mPendingInteractiveState != INTERACTIVE_STATE_UNKNOWN
&& (mPendingWakeUpBroadcast || mPendingGoToSleepBroadcast
|| mPendingInteractiveState != mBroadcastedInteractiveState)) {
mBroadcastInProgress = true;
mSuspendBlocker.acquire();//持锁
Message msg = mHandler.obtainMessage(MSG_BROADCAST);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
}
在PowerManagerService的updatePowerState中会调用finishWakefulnessChangeIfNeededLocked函数,这个函数最后调用了mNotifier.onWakefulnessChangeFinished
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
if (mWakefulness == WAKEFULNESS_DOZING
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
return; // wait until dream has enabled dozing
}
mWakefulnessChanging = false;
mNotifier.onWakefulnessChangeFinished();
}
}
onWakefulnessChangeFinished函数:
public void onWakefulnessChangeFinished() {
if (mInteractiveChanging) {
mInteractiveChanging = false;
handleLateInteractiveChange();
}
}
这个函数调用了handleLateInteractiveChange函数
private void handleLateInteractiveChange() {
synchronized (mLock) {
if (mInteractive) {
// Finished waking up...
mHandler.post(new Runnable() {
@Override
public void run() {
mPolicy.finishedWakingUp();//PhoneWindowManager的finish wakeingUp
}
});
} else {
// Finished going to sleep...
// This is a good time to make transitions that we don't want the user to see,
// such as bringing the key guard to focus. There's no guarantee for this
// however because the user could turn the device on again at any time.
// Some things may need to be protected by other mechanisms that defer screen on.
// Cancel pending user activity.
if (mUserActivityPending) {
mUserActivityPending = false;
mHandler.removeMessages(MSG_USER_ACTIVITY);
}
// Tell the policy we finished going to sleep.
final int why = translateOffReason(mInteractiveChangeReason);
mHandler.post(new Runnable() {
@Override
public void run() {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0);
mPolicy.finishedGoingToSleep(why);// phoneWindowManager的finsh goToSleep
}
});
// Send non-interactive broadcast.
mPendingInteractiveState = INTERACTIVE_STATE_ASLEEP;
mPendingGoToSleepBroadcast = true;
updatePendingBroadcastLocked();//发送广播
}
}
}
这第五和第六需要结合起来看,onWakefulnessChangeStarted是刚设置状态,onWakefulnessChangeFinished是设置状态结束了。onWakefulnessChangeStarted函数中先调用handleEarlyInteractiveChange,然后onWakefulnessChangeFinished调用handleLateInteractiveChange,并且用mInteractiveChanging变量来控制。
而handleEarlyInteractiveChange处理亮屏,先发广播调用mPolicy.startedWakingUp,然后在handleLateInteractiveChange函数中mPolicy.finishedWakingUp
而处理灭屏事件,现在handleEarlyInteractiveChange函数中mPolicy.startedGoingToSleep,然后在handleLateInteractiveChange函数中mPolicy.finishedGoingToSleep,然后发送灭屏广播。
我们主要在这篇博客分析了,PowerManagerService的各个状态变化后用Notifier类做一些通知,比如发送广播,通知PhoneWindowManager,AMS的一些接口等。