Android電源管理系列之PowerManagerService(一)
PowerManagerService提供Android系統的電源管理服務,主要功能是控制系統待機狀態,螢幕顯示,亮度調節,光線/距離感測器的控制等。
相關程式碼在以下檔案中:
frameworks/base/services/java/com/android/server/SystemServer.java frameworks/base/core/java/android/os/PowerManager.java frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp frameworks/base/core/java/android/os/PowerManagerInternal.java frameworks/base/services/core/java/com/android/server/power/Notifier.java device/qcom/common/power/power.c system/core/libsuspend/autosuspend.c hardware/libhardware_legacy/power/power.c
初始化流程
跟其他系統服務一樣,PowerManagerService也是繼承於SystemService並通過SystemServer啟動。
SystemServer
frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices() { ...... mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); ...... }
PowerManagerService
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public final class PowerManagerService extends SystemService implements Watchdog.Monitor { ...... }
在SystemServer的startBootstrapServices中,通過SystemServiceManager.startService啟動了PowerManagerService,下面首先來看PowerManagerService構造方法。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public PowerManagerService(Context context) { super(context); // mContext賦值為SystemContext mContext = context; // 建立訊息處理執行緒並啟動,建立關聯訊息處理執行緒的handler物件 mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/); mHandlerThread.start(); mHandler = new PowerManagerHandler(mHandlerThread.getLooper()); qcNsrmPowExt = new QCNsrmPowerExtension(this); synchronized (mLock) { // 建立"PowerManagerService.WakeLocks"的SuspendBlocker mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks"); // 建立"PowerManagerService.Display"的SuspendBlocker mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display"); // 請求DisplaySuspendBlocker,禁止系統進入休眠 mDisplaySuspendBlocker.acquire(); mHoldingDisplaySuspendBlocker = true; mHalAutoSuspendModeEnabled = false; mHalInteractiveModeEnabled = true; // 設定mWakefulness為喚醒狀態 mWakefulness = WAKEFULNESS_AWAKE; // 進入到native層初始化 nativeInit(); nativeSetAutoSuspend(false); nativeSetInteractive(true); nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0); } }
PowerManagerService建構函式中首先建立了處理訊息的程序及對應的handler物件以進行訊息處理,然後建立SuspendBlocker物件,用於WakeLocks與Display,並設定mWakefulness的初始狀態為WAKEFULNESS_AWAKE,最後進入到native層初始化。下面先看一下關於mWakefulness的定義。
>>> frameworks/base/core/java/android/os/PowerManagerInternal.java /** * 裝置處於休眠狀態,只能被wakeUp()喚醒. */ public static final int WAKEFULNESS_ASLEEP = 0; /** * 裝置處於正常工作(fully awake)狀態. */ public static final int WAKEFULNESS_AWAKE = 1; /** * 裝置處於播放屏保狀態. */ public static final int WAKEFULNESS_DREAMING = 2; /** * 裝置處於doze狀態,只有低耗電的屏保可以執行,其他應用被掛起. */ public static final int WAKEFULNESS_DOZING = 3;
繼續回到PowerManagerService建構函式的native初始化中,首先來看nativeInit的實現。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
static const JNINativeMethod gPowerManagerServiceMethods[] = { /* name, signature, funcPtr */ { "nativeInit", "()V", (void*) nativeInit }, { "nativeAcquireSuspendBlocker", "(Ljava/lang/String;)V", (void*) nativeAcquireSuspendBlocker }, { "nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V", (void*) nativeReleaseSuspendBlocker }, { "nativeSetInteractive", "(Z)V", (void*) nativeSetInteractive }, { "nativeSetAutoSuspend", "(Z)V", (void*) nativeSetAutoSuspend }, { "nativeSendPowerHint", "(II)V", (void*) nativeSendPowerHint }, { "nativeSetFeature", "(II)V", (void*) nativeSetFeature }, };
PowerManagerService中的native方法定義如上,nativeInit即呼叫nativeInit()。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
static void nativeInit(JNIEnv* env, jobject obj) { // 建立一個全域性物件,引用PMS gPowerManagerServiceObj = env->NewGlobalRef(obj); // 利用hw_get_module載入power模組 status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID, (hw_module_t const**)&gPowerModule); if (!err) { gPowerModule->init(gPowerModule); } else { ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err)); } }
nativeInit的主要任務時裝載power模組,該模組由廠商實現,以高通為例,如下。
device/qcom/common/power/power.c
tatic struct hw_module_methods_t power_module_methods = { .open = NULL, }; struct power_module HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = POWER_MODULE_API_VERSION_0_2, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = POWER_HARDWARE_MODULE_ID, .name = "QCOM Power HAL", .author = "Qualcomm", .methods = &power_module_methods, }, .init = power_init, .powerHint = power_hint, .setInteractive = set_interactive, };
power_module中實現了init,powerHint,setInteractive,nativeInit最終呼叫到HAL power模組的power_init具體實現中。接著看native初始化nativeSetAutoSuspend的實現。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { if (enable) { ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off"); autosuspend_enable(); } else { ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on"); autosuspend_disable(); } }
system/core/libsuspend/autosuspend.c
int autosuspend_disable(void) { int ret; ret = autosuspend_init(); if (ret) { return ret; } ALOGV("autosuspend_disable\n"); if (!autosuspend_enabled) { return 0; } ret = autosuspend_ops->disable(); if (ret) { return ret; } autosuspend_enabled = false; return 0; }
nativeSetAutoSuspend最終呼叫到libsuspend(參考Android電源管理系列之libsuspend)的autosuspend_disable禁止系統休眠。繼續看native初始化nativeSetInteractive,nativeSetFeature的實現
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) { if (gPowerModule) { if (enable) { ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on"); gPowerModule->setInteractive(gPowerModule, true); } else { ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off"); gPowerModule->setInteractive(gPowerModule, false); } } } static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) { int data_param = data; if (gPowerModule && gPowerModule->setFeature) { gPowerModule->setFeature(gPowerModule, (feature_t)featureId, data_param); } }
同nativeInit一樣,最終都是呼叫到HAL power模組的具體實現中。以上是建構函式的分析流程,下面繼續看PowerManagerService在系統啟動過程中回撥onStart(),onBootPhase(),systemReady()的實現。
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 { ...... } private final class LocalService extends PowerManagerInternal { ...... }
onStart()中釋出了BinderService,LocalService分別供其他程序,程序內其他服務呼叫,並將PowerManagerService加入到Watchdog監控中。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public void onBootPhase(int phase) { synchronized (mLock) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { ...... } else if (phase == PHASE_BOOT_COMPLETED) { final long now = SystemClock.uptimeMillis(); // 設定mBootCompleted狀態 mBootCompleted = true; mDirty |= DIRTY_BOOT_COMPLETED; // 更新userActivity及PowerState,後面分析 userActivityNoUpdateLocked( now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); updatePowerStateLocked(); // 執行mBootCompletedRunnables中的runnable方法 if (!ArrayUtils.isEmpty(mBootCompletedRunnables)) { Slog.d(TAG, "Posting " + mBootCompletedRunnables.length + " delayed runnables"); for (Runnable r : mBootCompletedRunnables) { BackgroundThread.getHandler().post(r); } } mBootCompletedRunnables = null; } } }
onBootPhase中主要設定mBootCompleted狀態,更新PowerState狀態,並執行mBootCompletedRunnables中的runnables方法(低電量模式會設定)。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public void systemReady(IAppOpsService appOps) { synchronized (mLock) { mSystemReady = true; // 獲取AppOpsService mAppOps = appOps; // 獲取DreamManager mDreamManager = getLocalService(DreamManagerInternal.class); // 獲取DisplayManagerService mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class); mPolicy = getLocalService(WindowManagerPolicy.class); // 獲取mBatteryService mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); // 獲取螢幕預設,最大,最小亮度 mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting(); mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting(); mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting(); // 獲取SensorManager SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper()); mBatteryStats = BatteryStatsService.getService(); // 建立Notifier物件,用於廣播power state的變化 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 settings changes. final ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.SCREENSAVER_ENABLED), ...... IVrManager vrManager = (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE); try { vrManager.registerListener(mVrStateCallbacks); } catch (RemoteException e) { Slog.e(TAG, "Failed to register VR mode state listener: " + e); } // 讀取配置 readConfigurationLocked(); updateSettingsLocked(); mDirty |= DIRTY_BATTERY_STATE; updatePowerStateLocked(); } // 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); }
userActivity
userActivity是定義在PowerManager中的SystemApi,使用者向PowerManagerService報告使用者活動,以更新PowerManagerService內部時間/狀態值,推遲系統休眠的時間。下面首先來看userActivity的定義。
frameworks/base/core/java/android/os/PowerManager.java
/** * User activity event type: Unspecified event type. */ public static final int USER_ACTIVITY_EVENT_OTHER = 0; /** * User activity event type: Button or key pressed or released. */ public static final int USER_ACTIVITY_EVENT_BUTTON = 1; /** * User activity event type: Touch down, move or up. */ public static final int USER_ACTIVITY_EVENT_TOUCH = 2; /** * User activity event type: Accessibility taking action on behalf of user. */ public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; @SystemApi public void userActivity(long when, int event, int flags) { try { mService.userActivity(when, event, flags); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private final class BinderService extends IPowerManager.Stub { ...... public void userActivity(long eventTime, int event, int flags) { final long now = SystemClock.uptimeMillis(); ...... if (eventTime > now) { throw new IllegalArgumentException("event time must not be in the future"); } final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { userActivityInternal(eventTime, event, flags, uid); } finally { Binder.restoreCallingIdentity(ident); } } ...... }
PowerManager中userActivity請求呼叫服務端PowerManagerService BinderService的userActivity,即呼叫內部方法userActivityInternal。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private void userActivityInternal(long eventTime, int event, int flags, int uid) { synchronized (mLock) { if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) { updatePowerStateLocked(); } } }
userActivityInternal中首先呼叫userActivityNoUpdateLocked更新相關資料及狀態(***NoUpdateLocked僅僅更新內部狀態並不採取任何操作),然後呼叫updatePowerStateLocked更新所有PowerState,下面分析userActivityNoUpdateLocked的實現,updatePowerStateLocked是PowerManagerService的核心方法,在最後進行分析。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) { // 如果發生時間是上一次休眠或喚醒前,或當前沒有開機完成到systemReady,不採取操作直接返回 if (eventTime < mLastSleepTime || eventTime < mLastWakeTime || !mBootCompleted || !mSystemReady) { return false; } try { // 更新mLastInteractivePowerHintTime時間 if (eventTime > mLastInteractivePowerHintTime) { powerHintInternal(POWER_HINT_INTERACTION, 0); mLastInteractivePowerHintTime = eventTime; } // 通過mNotifier通知BatteryStats UserActivity事件 mNotifier.onUserActivity(event, uid); if (mUserInactiveOverrideFromWindowManager) { mUserInactiveOverrideFromWindowManager = false; mOverriddenTimeout = -1; } // 如果系統處於休眠狀態,不進行處理 if (mWakefulness == WAKEFULNESS_ASLEEP || mWakefulness == WAKEFULNESS_DOZING || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) { return false; } // 根據flag是否在已變暗的情況下是否重啟活動超時更新mLastUserActivityTimeNoChangeLights或mLastUserActivityTime // 並且設定mDirty DIRTY_USER_ACTIVITY if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) { 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; }
gotoSleep
gotoSleep在PowerManager中的定義如下:
frameworks/base/core/java/android/os/PowerManager.java
public void goToSleep(long time) { goToSleep(time, GO_TO_SLEEP_REASON_APPLICATION, 0); } public void goToSleep(long time, int reason, int flags) { try { mService.goToSleep(time, reason, flags); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
與userActivity一樣,gotoSleep最終將呼叫到goToSleepInternal。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private final class BinderService extends IPowerManager.Stub { ...... public void goToSleep(long eventTime, int reason, int flags) { if (eventTime > SystemClock.uptimeMillis()) { throw new IllegalArgumentException("event time must not be in the future"); } mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DEVICE_POWER, null); final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { goToSleepInternal(eventTime, reason, flags, uid); } finally { Binder.restoreCallingIdentity(ident); } } ...... } private void goToSleepInternal(long eventTime, int reason, int flags, int uid) { synchronized (mLock) { if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) { updatePowerStateLocked(); } } }
goToSleepInternal中將執行goToSleepNoUpdateLocked更新內部狀態,同樣在updatePowerStateLocked中更新PowerState的操作。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) { // 當不處於awake狀態或未開機systemReady,不處理 if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP || mWakefulness == WAKEFULNESS_DOZING || !mBootCompleted || !mSystemReady) { return false; } try { ...... // 更新mLastSleepTime時間,設定DIRTY_WAKEFULNESS標誌位 mLastSleepTime = eventTime; mSandmanSummoned = true; setWakefulnessLocked(WAKEFULNESS_DOZING, reason); // 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; } } // 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; }
goToSleepNoUpdateLocked中更新mLastSleepTime,mWakefulness,mDirty狀態。
至此,本篇已結束,如有不對的地方,歡迎您的建議與指正。期待您的關注,
感謝您的閱讀,謝謝!
如有侵權,請聯絡小編,小編對此深感抱歉,同時小編會立即停止侵權行為。
公眾號ID:ProgramAndroid
獲取更多資訊
微信公眾號:ProgramAndroid
我們不是牛逼的程式設計師,我們只是程式開發中的墊腳石。
我們不傳送紅包,我們只是紅包的搬運工。
點選閱讀原文,獲取更多福利