上一篇博客把PMS里的构造函数和sytemReady分析了下:
今天主要从PowerManager中的接口入手去分析PowerManagerService.
先分析PowerManager中的一个内部类WakeLock,可以使用这个类持睡眠锁。
下面是PowerManager中WakeLock内部类来里面的代码:
public void acquire() { synchronized (mToken) { acquireLocked(); } } /** * Acquires the wake lock with a timeout. * <p> * Ensures that the device is on at the level requested when * the wake lock was created. The lock will be released after the given timeout * expires. * </p> * * @param timeout The timeout after which to release the wake lock, in milliseconds. */ public void acquire(long timeout) { synchronized (mToken) { acquireLocked(); mHandler.postDelayed(mReleaser, timeout);//利用消息机制做一个timeout的持锁,mReleaser中是对该锁释放了 } } private void acquireLocked() { if (!mRefCounted || mCount++ == 0) { // Do this even if the wake lock is already thought to be held (mHeld == true) // because non-reference counted wake locks are not always properly released. // For example, the keyguard's wake lock might be forcibly released by the // power manager without the keyguard knowing. A subsequent call to acquire // should immediately acquire the wake lock once again despite never having // been explicitly released by the keyguard. mHandler.removeCallbacks(mReleaser); Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0); try { mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,//调用PMS的acquireWakeLock mHistoryTag); } catch (RemoteException e) { } mHeld = true; } }
先看PMS里的acquireWakeLock函数,先做一些权限的检查,然后就调用acquireWakeLockInternal函数。
@Override // Binder call public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, WorkSource ws, String historyTag) { if (lock == null) { throw new IllegalArgumentException("lock must not be null"); } if (packageName == null) { throw new IllegalArgumentException("packageName must not be null"); } PowerManager.validateWakeLockParameters(flags, tag); mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null); if ((flags & PowerManager.DOZE_WAKE_LOCK) != 0) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); } if (ws != null && ws.size() != 0) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.UPDATE_DEVICE_STATS, null); } else { ws = null; } final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); final long ident = Binder.clearCallingIdentity(); try { acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid); } finally { Binder.restoreCallingIdentity(ident); } }
acquireWakeLockInternal函数
private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName, WorkSource ws, String historyTag, int uid, int pid) { synchronized (mLock) { if (DEBUG_SPEW) { Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock) + ", flags=0x" + Integer.toHexString(flags) + ", tag=\"" + tag + "\", ws=" + ws + ", uid=" + uid + ", pid=" + pid); } WakeLock wakeLock; int index = findWakeLockIndexLocked(lock);//查找这个IBinder的锁。因为每个应用都是一个进程,通过binder通信与PMS交互。IBinder是唯一的 boolean notifyAcquire; if (index >= 0) {//找到 wakeLock = mWakeLocks.get(index); if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {//如果属性不一样就更新 // Update existing wake lock. This shouldn't happen but is harmless. notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,//通知电池统计 uid, pid, ws, historyTag); wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid); } notifyAcquire = false; } else {//没找到 wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);//新建一个WakeLock加入列表 try { lock.linkToDeath(wakeLock, 0); } catch (RemoteException ex) { throw new IllegalArgumentException("Wake lock is already dead."); } mWakeLocks.add(wakeLock); notifyAcquire = true; } applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);//下面详细分析 mDirty |= DIRTY_WAKE_LOCKS;//mDirty 标志位置位 updatePowerStateLocked();//更新power状态 if (notifyAcquire) { // This needs to be done last so we are sure we have acquired the // kernel wake lock. Otherwise we have a race where the system may // go to sleep between the time we start the accounting in battery // stats and when we actually get around to telling the kernel to // stay awake. notifyWakeLockAcquiredLocked(wakeLock);//通知电池统计那块 } } }
findWakeLockIndexLocked函数
private int findWakeLockIndexLocked(IBinder lock) { final int count = mWakeLocks.size(); for (int i = 0; i < count; i++) { if (mWakeLocks.get(i).mLock == lock) { return i; } } return -1; }applyWakeLockFlagsOnAcquireLocked函数
private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) { if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0//如果持的锁有ACQUIRE_CAUSES_WAKEUP,还有屏幕锁的话,会wakeup设备 && isScreenLock(wakeLock)) { wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), uid); } }
@SuppressWarnings("deprecation") private static boolean isScreenLock(final WakeLock wakeLock) { switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) { case PowerManager.FULL_WAKE_LOCK: case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: case PowerManager.SCREEN_DIM_WAKE_LOCK: return true; } return false; }
updatePowerStateLocked这个函数是所有的地方都会调用,因此我们最后分析。
下面看下释放锁,releaseWakeLockInternal函数:
private void releaseWakeLockInternal(IBinder lock, int flags) { synchronized (mLock) { int index = findWakeLockIndexLocked(lock); if (index < 0) {//没找到,直接退出 if (DEBUG_SPEW) { Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock) + " [not found], flags=0x" + Integer.toHexString(flags)); } return; } WakeLock wakeLock = mWakeLocks.get(index); if (DEBUG_SPEW) { Slog.d(TAG, "releaseWakeLockInternal: lock=" + Objects.hashCode(lock) + " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags)); } if ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) { mRequestWaitForNegativeProximity = true;//和距离传感器有关 } wakeLock.mLock.unlinkToDeath(wakeLock, 0); removeWakeLockLocked(wakeLock, index); } }removeWakeLockLocked函数
private void removeWakeLockLocked(WakeLock wakeLock, int index) { mWakeLocks.remove(index);//列表中去除 notifyWakeLockReleasedLocked(wakeLock);//通知电池统计 applyWakeLockFlagsOnReleaseLocked(wakeLock); mDirty |= DIRTY_WAKE_LOCKS;//mDirty置标志位 updatePowerStateLocked(); }
applyWakeLockFlagsOnReleaseLocked函数
private void applyWakeLockFlagsOnReleaseLocked(WakeLock wakeLock) { if ((wakeLock.mFlags & PowerManager.ON_AFTER_RELEASE) != 0//当有这个标志位的锁,释放的时候。需要触发useractivity,因此会延长亮屏时间 && isScreenLock(wakeLock)) {//是否是屏幕锁 userActivityNoUpdateLocked(SystemClock.uptimeMillis(),//触发userActivity事件,后面详细分析 PowerManager.USER_ACTIVITY_EVENT_OTHER, PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS, wakeLock.mOwnerUid); } }
接下来我们来分析下gotoSleep函数:
调用PowerManger的gotoSleep函数,最后会到PMS的goToSleepInternal函数
private void goToSleepInternal(long eventTime, int reason, int flags, int uid) { synchronized (mLock) { if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) { updatePowerStateLocked(); } } }goToSleepNoUpdateLocked函数
private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) { if (DEBUG_SPEW) { Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime + ", reason=" + reason + ", flags=" + flags + ", uid=" + uid); } if (eventTime < mLastWakeTime//如果时间不对,状态已经是WAKEFULNESS_ASLEEP或者WAKEFULNESS_DOZING,或者系统没准备好直接出去 || mWakefulness == WAKEFULNESS_ASLEEP || mWakefulness == WAKEFULNESS_DOZING || !mBootCompleted || !mSystemReady) { return false; } Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep"); try { switch (reason) {//打印下原因 case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN: Slog.i(TAG, "Going to sleep due to device administration policy " + "(uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT: Slog.i(TAG, "Going to sleep due to screen timeout (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH: Slog.i(TAG, "Going to sleep due to lid switch (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON: Slog.i(TAG, "Going to sleep due to power button (uid " + uid +")..."); break; case PowerManager.GO_TO_SLEEP_REASON_HDMI: Slog.i(TAG, "Going to sleep due to HDMI standby (uid " + uid +")..."); break; default: Slog.i(TAG, "Going to sleep by application request (uid " + uid +")..."); reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION; break; } mLastSleepTime = eventTime; mSandmanSummoned = true;//和做梦有关 setWakefulnessLocked(WAKEFULNESS_DOZING, reason);//设置mWakefulness的状态 // Report the number of wake locks that will be cleared by going to sleep. int numWakeLocksCleared = 0; final int numWakeLocks = mWakeLocks.size(); for (int i = 0; i < numWakeLocks; i++) { final WakeLock wakeLock = mWakeLocks.get(i); switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) { case PowerManager.FULL_WAKE_LOCK: case PowerManager.SCREEN_BRIGHT_WAKE_LOCK: case PowerManager.SCREEN_DIM_WAKE_LOCK: numWakeLocksCleared += 1; break; } } EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numWakeLocksCleared);//打印当前屏幕锁的个数 // Skip dozing if requested. if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {//如果flags有这个状态,直接睡眠 reallyGoToSleepNoUpdateLocked(eventTime, uid); } } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } return true; }
我们先看下setWakefulnessLocked函数:
private void setWakefulnessLocked(int wakefulness, int reason) { if (mWakefulness != wakefulness) { finishWakefulnessChangeLocked(); mWakefulness = wakefulness;//将mWakefulness赋值 mWakefulnessChanging = true; mDirty |= DIRTY_WAKEFULNESS;//mDirty置位 mNotifier.onWakefulnessChangeStarted(wakefulness, reason);//第一次的时候先调onWakefulnessChangeStarted } } private void finishWakefulnessChangeLocked() { if (mWakefulnessChanging) { mNotifier.onWakefulnessChangeFinished(mWakefulness); mWakefulnessChanging = false; } }
然后我们看下notifier的onWakefulnessChangeStarted函数
public void onWakefulnessChangeStarted(int wakefulness, int reason) { if (DEBUG) { Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness + ", reason=" + reason); } // We handle interactive state changes once they start so that the system can // set everything up or the user to begin interacting with applications. final boolean interactive = PowerManagerInternal.isInteractive(wakefulness); if (interactive) { handleWakefulnessChange(wakefulness, interactive, reason);//如果当前是要点亮屏幕 } else { mLastReason = reason; } // Start input as soon as we start waking up or going to sleep. mInputManagerInternal.setInteractive(interactive);//在InputmanagerService中去调用JNI,没细跟 }
而onWakefulnessChangeFinished函数都是调用handleWakefulnessChange只是interactive参数相反
public void onWakefulnessChangeFinished(int wakefulness) { if (DEBUG) { Slog.d(TAG, "onWakefulnessChangeFinished: wakefulness=" + wakefulness); } // Handle interactive state changes once they are finished so that the system can // finish pending transitions (such as turning the screen off) before causing // applications to change state visibly. final boolean interactive = PowerManagerInternal.isInteractive(wakefulness); if (!interactive) { handleWakefulnessChange(wakefulness, interactive, mLastReason); } }
handleWakefulnessChange函数
private void handleWakefulnessChange(final int wakefulness, boolean interactive, final int reason) { // Tell the activity manager about changes in wakefulness, not just interactivity. // It needs more granularity than other components. mHandler.post(new Runnable() { @Override public void run() { mActivityManagerInternal.onWakefulnessChanged(wakefulness);//调用AMS的onWakefulnessChanged函数 } }); // Handle changes in the overall interactive state. boolean interactiveChanged = false; synchronized (mLock) { // Broadcast interactive state changes. if (interactive) { // Waking up... interactiveChanged = (mActualInteractiveState != INTERACTIVE_STATE_AWAKE); if (interactiveChanged) { mActualInteractiveState = INTERACTIVE_STATE_AWAKE; mPendingWakeUpBroadcast = true; mHandler.post(new Runnable() { @Override public void run() { EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, 0, 0, 0); mPolicy.wakingUp();//开启线程phoneWindowManager处理keyguard等 } }); updatePendingBroadcastLocked();//发送ACTION_SCREEN_ON广播 } } else { // 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. interactiveChanged = (mActualInteractiveState != INTERACTIVE_STATE_ASLEEP); if (interactiveChanged) { mActualInteractiveState = INTERACTIVE_STATE_ASLEEP; mPendingGoToSleepBroadcast = true; if (mUserActivityPending) { mUserActivityPending = false; mHandler.removeMessages(MSG_USER_ACTIVITY); } mHandler.post(new Runnable() { @Override public void run() { int why = WindowManagerPolicy.OFF_BECAUSE_OF_USER; switch (reason) { case PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN: why = WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN; break; case PowerManager.GO_TO_SLEEP_REASON_TIMEOUT: why = WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT; break; } EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, why, 0, 0); mPolicy.goingToSleep(why);//开启线程phoneWindowManager处理keyguard等 } }); updatePendingBroadcastLocked();//发送ACTION_SCREEN_OFF广播 } } } // Notify battery stats. if (interactiveChanged) { try { mBatteryStats.noteInteractive(interactive);//统计电池电量 } catch (RemoteException ex) { } } }
AMS的onWakefulnessChanged函数
void onWakefulnessChanged(int wakefulness) { synchronized(this) { mWakefulness = wakefulness; updateSleepIfNeededLocked(); } }
AMS的updateSleepIfNeededLocked函数
void updateSleepIfNeededLocked() { if (mSleeping && !shouldSleepLocked()) {//唤醒 mSleeping = false; mStackSupervisor.comeOutOfSleepIfNeededLocked();//显示activity } else if (!mSleeping && shouldSleepLocked()) {//睡眠 mSleeping = true; mStackSupervisor.goingToSleepLocked();//销毁LaunchingActivity等 // Initialize the wake times of all processes. checkExcessivePowerUsageLocked(false); mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); } }
继续分析gotoSleep函数:
如果flag是直接睡眠的,就调用reallyGoToSleepNoUpdateLocked函数,将mWakefulness的状态改成WAKEFULNESS_ASLEEP。
private boolean reallyGoToSleepNoUpdateLocked(long eventTime, int uid) { if (DEBUG_SPEW) { Slog.d(TAG, "reallyGoToSleepNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid); } if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP || !mBootCompleted || !mSystemReady) { return false; } Trace.traceBegin(Trace.TRACE_TAG_POWER, "reallyGoToSleep"); try { Slog.i(TAG, "Sleeping (uid " + uid +")..."); setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } return true; }
下面我们来看下wakeup:
会调用PMS的wakeUpInternal函数:
private void wakeUpInternal(long eventTime, int uid) { synchronized (mLock) { if (wakeUpNoUpdateLocked(eventTime, uid)) { updatePowerStateLocked(); } } }wakeUpNoUpdateLocked函数
private boolean wakeUpNoUpdateLocked(long eventTime, int uid) { if (true) { Slog.d(TAG, "kang wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid); } if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE//时间不对,当前状态已经是WAKEFULNESS_AWAKE,系统没起来就直接return || !mBootCompleted || !mSystemReady) { return false; } Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp"); try { switch (mWakefulness) {//打印当前的mWakefulness case WAKEFULNESS_ASLEEP: Slog.i(TAG, "Waking up from sleep (uid " + uid +")..."); //boost for quick screen on //boostForPerformance(2, 600); break; case WAKEFULNESS_DREAMING: Slog.i(TAG, "Waking up from dream (uid " + uid +")..."); break; case WAKEFULNESS_DOZING: Slog.i(TAG, "Waking up from dozing (uid " + uid +")..."); break; } mLastWakeTime = eventTime;//记录时间 setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);//改变状态 userActivityNoUpdateLocked(//触发useractivity事件 eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid); } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } return true; }
下面我们来看下userActivity事件,当点击屏幕的时候,就会触发这事件:
最终到PMS的userActivityInternal
private void userActivityInternal(long eventTime, int event, int flags, int uid) { synchronized (mLock) { if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) { updatePowerStateLocked(); } } }
userActivityNoUpdateLocked函数:
private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) { if (DEBUG_SPEW) { Slog.d(TAG, "userActivityNoUpdateLocked: eventTime=" + eventTime + ", event=" + event + ", flags=0x" + Integer.toHexString(flags) + ", uid=" + uid); } if (eventTime < mLastSleepTime || eventTime < mLastWakeTime || !mBootCompleted || !mSystemReady) { return false; } Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity"); try { if (eventTime > mLastInteractivePowerHintTime) { powerHintInternal(POWER_HINT_INTERACTION, 0);//powerHintInternal是通过JNI,底层是将cpu的频率提高等等,这里还有一个低功耗模式,在上一篇博客分析过。 mLastInteractivePowerHintTime = eventTime;//记录下时间 } mNotifier.onUserActivity(event, uid);//通知keyguard的锁屏时间 if (mWakefulness == WAKEFULNESS_ASLEEP || mWakefulness == WAKEFULNESS_DOZING || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) { return false; } if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {//延长dim的时间,不会变亮 if (eventTime > mLastUserActivityTimeNoChangeLights && eventTime > mLastUserActivityTime) { mLastUserActivityTimeNoChangeLights = eventTime;//记录时间 mDirty |= DIRTY_USER_ACTIVITY; return true; } } else { if (eventTime > mLastUserActivityTime) { mLastUserActivityTime = eventTime;//记录时间 mDirty |= DIRTY_USER_ACTIVITY; return true; } } } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } return false; }
nap事件
调用PMS的napNoUpdateLocked函数:
private boolean napNoUpdateLocked(long eventTime, int uid) { if (DEBUG_SPEW) { Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid); } if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE//当前的状态必须是醒的才有效 || !mBootCompleted || !mSystemReady) { return false; } Trace.traceBegin(Trace.TRACE_TAG_POWER, "nap"); try { Slog.i(TAG, "Nap time (uid " + uid +")..."); mSandmanSummoned = true;//这个变量和做梦有关 setWakefulnessLocked(WAKEFULNESS_DREAMING, 0);//mWakefulness置为WAKEFULNESS_DREAMING } finally { Trace.traceEnd(Trace.TRACE_TAG_POWER); } return true; }
boostScreenBrightness就是将屏幕变到最亮,持续一段时间:
最终会调到PMS的函数boostScreenBrightnessInternal
private void boostScreenBrightnessInternal(long eventTime, int uid) { synchronized (mLock) { if (!mSystemReady || mWakefulness == WAKEFULNESS_ASLEEP//状态是WAKEFULNESS_ASLEEP直接退出 || eventTime < mLastScreenBrightnessBoostTime) { return; } Slog.i(TAG, "Brightness boost activated (uid " + uid +")..."); mLastScreenBrightnessBoostTime = eventTime;//记录时间 mScreenBrightnessBoostInProgress = true; mDirty |= DIRTY_SCREEN_BRIGHTNESS_BOOST; userActivityNoUpdateLocked(eventTime,//触发userActivity事件 PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid); updatePowerStateLocked(); } }
setBacklightBrightness函数
最终调奥PMS的setTemporaryScreenBrightnessSettingOverrideInternal函数
private void setTemporaryScreenBrightnessSettingOverrideInternal(int brightness) { synchronized (mLock) { if (mTemporaryScreenBrightnessSettingOverride != brightness) { mTemporaryScreenBrightnessSettingOverride = brightness;//变量值修改了下 mDirty |= DIRTY_SETTINGS; updatePowerStateLocked(); } } }
isScreenOn函数:最后就调用下面这个函数,主要看是否是下面这两个状态
public static boolean isInteractive(int wakefulness) { return wakefulness == WAKEFULNESS_AWAKE || wakefulness == WAKEFULNESS_DREAMING; }
setLowPowerMode和isPowerSaveMode在上一篇PMS的博客里分析过了,这里就不看了。
下篇主要分析updatePowerStateLocked函数。