PowerManagerService提供Android系統的電源管理服務,主要功能是控制系統的待機狀態,控制顯示屏的開關和亮度調節等。
PowerManagerService在systemserver中建立,加入到serviceManager中:
[java] view plain copy
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
先從構造函數分析,代碼以下:
public PowerManagerService(Context context) {
super(context);
mContext = context;
//建立處理消息的線程
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
mHandlerThread.start();
//建立Handler,注意mHandlerThread.getLooper(),每個線程都只有一個looper,這樣消息的處理會放在這個線程中
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
synchronized (mLock) {
mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
//防止cpu進入睡眠狀態
mDisplaySuspendBlocker.acquire();
mHoldingDisplaySuspendBlocker = true;
mHalAutoSuspendModeEnabled = false;
mHalInteractiveModeEnabled = true;
//當前系統狀態正常運行狀態
mWakefulness = WAKEFULNESS_AWAKE;
nativeInit();
nativeSetAutoSuspend(false);
nativeSetInteractive(true);
}
} java
構造函數比較簡單,建立了一個接受消息處理的線程,cpu持鎖不讓手機睡眠,以及一些變量的初始化。
SystemServer建立完PowerManagerService後,繼續調用SystemReady方法,再作一些初始化的工做,代碼以下:
[java] view plain copy
public void systemReady(IAppOpsService appOps) {
synchronized (mLock) {
mSystemReady = true;
mAppOps = appOps;
//android5.0後的新方法,localService能夠直接取,在4.4中這樣service是在init中傳對象進來的
mDreamManager = getLocalService(DreamManagerInternal.class);
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
mPolicy = getLocalService(WindowManagerPolicy.class);
mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
//獲取缺省、最大、最小屏幕亮度
mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
//建立sensorManager和sersorservice交互
SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
// The notifier runs on the system server's main looper so as not to interfere
// with the animations and other critical functions of the power manager.
mBatteryStats = BatteryStatsService.getService();
mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
mPolicy);
//建立檢測無線充電的對象
mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
mHandler);
mSettingsObserver = new SettingsObserver(mHandler);
mLightsManager = getLocalService(LightsManager.class);
mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);
// Initialize display power management.
mDisplayManagerInternal.initPowerManagement(
mDisplayPowerCallbacks, mHandler, sensorManager);
// Register for broadcasts from other components of the system.
//監聽其餘模塊的廣播
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DREAMING_STARTED);
filter.addAction(Intent.ACTION_DREAMING_STOPPED);
mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_DOCK_EVENT);
mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
// Register for settings changes.
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ENABLED),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SLEEP_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_BRIGHTNESS_MODE),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.THEATER_MODE_ON),
false, mSettingsObserver, UserHandle.USER_ALL);
// Go.
readConfigurationLocked();
updateSettingsLocked();
mDirty |= DIRTY_BATTERY_STATE;
updatePowerStateLocked();
}
} android
從在android5.1.1中,service通常都會繼承一個虛類SystemService,在其中定義了兩個接口onStart和onBootPhase,分別是PowerManagerService啓動的時候會調用,而onBootPhase會在系統啓動的各個階段來調用,下面咱們分別來看看在powerManagerService中這兩個函數的實現:
[java] view plain copy
@Override
public void onStart() {
publishBinderService(Context.POWER_SERVICE, new BinderService());
publishLocalService(PowerManagerInternal.class, new LocalService());
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
在onstart函數中,必須把一些接口publish,像在以前Binder的接口,都是經過PowerManagerService extends IPowerManager.Stub形式在PowerManagerService中實現接口
而在android5.1.1中都是經過方式從新定義一個類,而後把這個類publish出去。
[java] view plain copy
private final class BinderService extends IPowerManager.Stub {
@Override // Binder call
public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
String packageName, int uid) {
if (uid < 0) {
uid = Binder.getCallingUid();
}
acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);
}
@Override // Binder call
public void powerHint(int hintId, int data) {
if (!mSystemReady) {
// Service not ready yet, so who the heck cares about power hints, bah.
return;
}
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
powerHintInternal(hintId, data);
}
@Override // Binder call
public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
WorkSource ws, String historyTag) {
[java] view plain copy
。。。。。。。。。。。。。。
而localservice都是一些本地的服務,不是經過Binder實現的。app
咱們接下來從,powerManager中的wakeLock提及,在powerManager中調用newWakeLock接口會生成一個WakeLock對象,而調用器acqure方法,最終會調用PowerManagerService中的acquireWakeLock方法
而具體的WakeLock有幾種以下:
PARTIAL_WAKE_LOCK:只保持CPU運行,屏幕和鍵盤光關閉。
FULL_WAKE_LOCK:都不關閉
SCREEN_BRIGHT_WAKE_LOCK:屏幕背光不關閉,鍵盤光關閉
SCREEN_DIM_WAKE_LOCK:屏幕背光不關閉,鍵盤光關閉。可是屏幕背光能夠變暗
PROXIMITY_SCREEN_OFF_WAKE_LOCK當持有這種類型wakelock,當距離傳感器被遮擋,屏幕將被關閉。打電話時用這個功能
在PowerManagerService中的acquieWakeLock先要檢查權限而後調用acquireWakeLockInternal接口,代碼以下:
[java] view plain copy
private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
WorkSource ws, String historyTag, int uid, int pid) {
synchronized (mLock) {
WakeLock wakeLock;
//查找wakelock
int index = findWakeLockIndexLocked(lock);
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);
try {
lock.linkToDeath(wakeLock, 0);
} catch (RemoteException ex) {
throw new IllegalArgumentException("Wake lock is already dead.");
}
mWakeLocks.add(wakeLock);
notifyAcquire = true;
}
//看是否須要點亮屏幕
applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);
//整個PowermanagerService用來記錄各個狀態變化的一個標誌位
mDirty |= DIRTY_WAKE_LOCKS;
//更新各個狀態
updatePowerStateLocked();
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);
}
}
}
整個PowermanagerService都是靠一個mDirty的各個標誌位來記錄各個狀態的變化,隨後會調用一個updatePowerStateLocked來更新各個狀態。
一樣解鎖會調用到releaseWakeLockInternal,代碼以下:
[java] view plain copy
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
wakeLock.mLock.unlinkToDeath(wakeLock, 0);
removeWakeLockLocked(wakeLock, index);
}
}
PowerManagerService中最終各個接口都會調一個函數updatePowerStateLocked,主要用來更新power的各個狀態
private void updatePowerStateLocked() {
if (!mSystemReady || mDirty == 0) {各個狀態沒有變化
return;
}
if (!Thread.holdsLock(mLock)) {
Slog.wtf(TAG, "Power manager lock was not held when calling updatePowerStateLocked");
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
try {
// Phase 0: Basic state updates.
//更新充電的各個狀態(是否充電、電池電量、充電方式、是否低電量),以及更新低功耗模式(android5.0增長的)
updateIsPoweredLocked(mDirty);
//更新mStayOn狀態,爲true,屏幕常亮
updateStayOnLocked(mDirty);
//更新屏幕是否最亮的狀態是否持續
updateScreenBrightnessBoostLocked(mDirty);
// Phase 1: Update wakefulness.
// Loop because the wake lock and user activity computations are influenced
// by changes in wakefulness.
final long now = SystemClock.uptimeMillis();
int dirtyPhase2 = 0;
for (;;) {
int dirtyPhase1 = mDirty;
dirtyPhase2 |= dirtyPhase1;
mDirty = 0;
//更新mWakeLockSummary的狀態
updateWakeLockSummaryLocked(dirtyPhase1);
//更新mUserActivitySummary狀態
updateUserActivitySummaryLocked(now, dirtyPhase1);
if (!updateWakefulnessLocked(dirtyPhase1)) {
break;
}
}
// Phase 2: Update display power state.
boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);//更新display狀態,在displaypowercontrol中會控制亮度,滅屏等
// Phase 3: Update dream state (depends on display ready signal).
//更新夢的狀態,用dreammanager控制夢,powermanagerservice中記錄mWakefulness
updateDreamLocked(dirtyPhase2, displayBecameReady);
// Phase 4: Send notifications, if needed.
if (mDisplayReady) {
finishWakefulnessChangeLocked();
}
// Phase 5: Update suspend blocker.
// Because we might release the last suspend blocker here, we need to make sure
// we finished everything else first!
//更新睡眠鎖,以及是否持鎖和釋放鎖
updateSuspendBlockerLocked();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
} less
updateIsPoweredLocked、updateStayOnLocked、updateScreenBrightnessBoostLocked、updateWakeLockSummaryLocked、updateUserActivitySummaryLocked都是比較簡單、在上面的函數註釋中都有介紹。下面咱們先看下updateWakefulnessLocked函數,代碼以下:
[java] view plain copy
private boolean updateWakefulnessLocked(int dirty) {
boolean changed = false;
if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
| DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
| DIRTY_DOCK_STATE)) != 0) {
//當前狀態是醒着,而且準備開始睡眠了
if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
}
final long time = SystemClock.uptimeMillis();
//是應該開始作夢,仍是先睡眠
if (shouldNapAtBedTimeLocked()) {
//當前狀態設置爲睡眠狀態
changed = napNoUpdateLocked(time, Process.SYSTEM_UID);
} else {
//當前狀態設置爲假寐狀態
changed = goToSleepNoUpdateLocked(time,
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
}
}
}
return changed;
}
[java] view plain copy
private boolean isBeingKeptAwakeLocked() {
return mStayOn
|| mProximityPositive//距離傳感器
|| (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0//wakelock鎖
|| (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
| USER_ACTIVITY_SCREEN_DIM)) != 0//用戶行爲、和用戶點擊屏幕、自動滅屏時間等有關
|| mScreenBrightnessBoostInProgress;\\是否要保持處於最亮狀態
}
private boolean isItBedTimeYetLocked() {
//當啓動完成、而且設備沒必要保持喚醒狀態是的時候返回true
return mBootCompleted && !isBeingKeptAwakeLocked();
} ide
updateDreamLocked函數經過發送消息,最終會調用handleSandman:函數
[java] view plain copy
private void handleSandman() { // runs on handler thread
// Handle preconditions.
final boolean startDreaming;
final int wakefulness;
synchronized (mLock) {
mSandmanScheduled = false;
wakefulness = mWakefulness;
if (mSandmanSummoned && mDisplayReady) {
startDreaming = canDreamLocked() || canDozeLocked();
mSandmanSummoned = false;
} else {
startDreaming = false;
}
}
// Start dreaming if needed.
// We only control the dream on the handler thread, so we don't need to worry about
// concurrent attempts to start or stop the dream.
final boolean isDreaming;
if (mDreamManager != null) {
// Restart the dream whenever the sandman is summoned.
if (startDreaming) {
mDreamManager.stopDream(false /*immediate*/);
mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
}
isDreaming = mDreamManager.isDreaming();
} else {
isDreaming = false;
}
// Update dream state.
synchronized (mLock) {
// Remember the initial battery level when the dream started.
if (startDreaming && isDreaming) {
mBatteryLevelWhenDreamStarted = mBatteryLevel;
if (wakefulness == WAKEFULNESS_DOZING) {
Slog.i(TAG, "Dozing...");
} else {
Slog.i(TAG, "Dreaming...");
}
}
// If preconditions changed, wait for the next iteration to determine
// whether the dream should continue (or be restarted).
if (mSandmanSummoned || mWakefulness != wakefulness) {
return; // wait for next cycle
}
// Determine whether the dream should continue.
if (wakefulness == WAKEFULNESS_DREAMING) {
if (isDreaming && canDreamLocked()) {
//在作夢中
if (mDreamsBatteryLevelDrainCutoffConfig >= 0
&& mBatteryLevel < mBatteryLevelWhenDreamStarted
- mDreamsBatteryLevelDrainCutoffConfig
&& !isBeingKeptAwakeLocked()) {
// If the user activity timeout expired and the battery appears
// to be draining faster than it is charging then stop dreaming
// and go to sleep.
Slog.i(TAG, "Stopping dream because the battery appears to "
+ "be draining faster than it is charging. "
+ "Battery level when dream started: "
+ mBatteryLevelWhenDreamStarted + "%. "
+ "Battery level now: " + mBatteryLevel + "%.");
} else {
//繼續作夢
return; // continue dreaming
}
}
// Dream has ended or will be stopped. Update the power state.
//結束作夢,要麼喚醒、要麼繼續goToSleep
if (isItBedTimeYetLocked()) {
goToSleepNoUpdateLocked(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
updatePowerStateLocked();
} else {
wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);
updatePowerStateLocked();
}
} else if (wakefulness == WAKEFULNESS_DOZING) {
if (isDreaming) {
return; // continue dozing
}
//直接睡眠,跳過作夢
// Doze has ended or will be stopped. Update the power state.
reallyGoToSleepNoUpdateLocked(SystemClock.uptimeMillis(), Process.SYSTEM_UID);
updatePowerStateLocked();
}
}
// Stop dream.能走到這說明,確定結束作夢
if (isDreaming) {
mDreamManager.stopDream(false /*immediate*/);
}
}
updateSuspendBlockerLocked函數是是否要Cpu持鎖。oop
[java] view plain copy
private void updateSuspendBlockerLocked() {
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);//是否要cpu持鎖
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();//是否display要持鎖
final boolean autoSuspend = !needDisplaySuspendBlocker;
final boolean interactive = mDisplayPowerRequest.isBrightOrDim();
// Disable auto-suspend if needed.
// FIXME We should consider just leaving auto-suspend enabled forever since
// we already hold the necessary wakelocks.
if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(false);
}
// First acquire suspend blockers if needed.
if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.acquire();
mHoldingWakeLockSuspendBlocker = true;
}
if (needDisplaySuspendBlocker && !mHoldingDisplaySuspendBlocker) {
mDisplaySuspendBlocker.acquire();
mHoldingDisplaySuspendBlocker = true;
}
// Inform the power HAL about interactive mode.
// Although we could set interactive strictly based on the wakefulness
// as reported by isInteractive(), it is actually more desirable to track
// the display policy state instead so that the interactive state observed
// by the HAL more accurately tracks transitions between AWAKE and DOZING.
// Refer to getDesiredScreenPolicyLocked() for details.
if (mDecoupleHalInteractiveModeFromDisplayConfig) {
// When becoming non-interactive, we want to defer sending this signal
// until the display is actually ready so that all transitions have
// completed. This is probably a good sign that things have gotten
// too tangled over here...
if (interactive || mDisplayReady) {//當屏幕亮着|| 當屏幕暗着,displayPowerControl準備好了,進入該條件設置
setHalInteractiveModeLocked(interactive);
}
}
// Then release suspend blockers if needed.
if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.release();
mHoldingWakeLockSuspendBlocker = false;
}
if (!needDisplaySuspendBlocker && mHoldingDisplaySuspendBlocker) {
mDisplaySuspendBlocker.release();
mHoldingDisplaySuspendBlocker = false;
}
// Enable auto-suspend if needed.
if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
setHalAutoSuspendModeLocked(true);
}
} ui
下來介紹下powermanager中其餘的接口,
一、gotosleep,讓設備睡眠,按power鍵會調用這個函數
private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {
synchronized (mLock) {
//返回true,才更新狀態
if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
updatePowerStateLocked();
}
}
}
@SuppressWarnings("deprecation")
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
|| 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;
。。。。。。。。。。。。
}
mLastSleepTime = eventTime;
mSandmanSummoned = true;
setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
// Report the number of wake locks that will be cleared by going to sleep.
//統計wakelock的數量
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) {
reallyGoToSleepNoUpdateLocked(eventTime, uid);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
return true;
}
二、useractivity是當用戶點擊屏幕等行爲,會從新計算自動滅屏的時間等,而後回去updatepowerstate
三、wakeup喚醒設備,與gotosleep對應。
四、nap,使設備處於一種假寐的狀態
五、boostScreenBrightness,是屏幕達到最亮持續一段時間
這其中每一個函數都會調用updatepowerstatethis