<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近遇到一些關於省電模式、電量消耗、Doze模式,等等相關問題。於是,我決定對它們進行徹底分析,那就先從省電模式開啟。
可以在 Settings->Battery->Battery Saver 介面進行省電模式的操作,如下圖:
介面中有三個開關,它們的意思如下:
由於省電模式的功能涉及的程式碼比較多,本文只分析省電模式環境的初始化,涉及的檔案路徑如下
省電模式屬於 PowerManagerService 的一部分功能,下面列出與省電模式環境相關的程式碼:
PowerManagerService(Context context, Injector injector) { super(context); // ... // Class to decide whether to turn on battery saver mode for specific services. mBatterySaverPolicy = mInjector.createBatterySaverPolicy(mLock, mContext, mBatterySavingStats); // Responsible for battery saver mode transition logic. mBatterySaverController = mInjector.createBatterySaverController(mLock, mContext, mBatterySaverPolicy, mBatterySavingStats); // Decides when to enable / disable battery saver. mBatterySaverStateMachine = mInjector.createBatterySaverStateMachine(mLock, mContext, mBatterySaverController); // ... }
與省電模式相關的類有三個,BatterySaverPolicy, BatterySaverController, BatterySaverStateMachine。
介紹下三個類的作用:
這裡建立三個類物件的方式,就是呼叫建構函式,下面大致看下這幾個建構函式
public BatterySaverPolicy(Object lock, Context context, BatterySavingStats batterySavingStats) { super(BackgroundThread.getHandler()); mLock = lock; mHandler = BackgroundThread.getHandler(); mContext = context; mContentResolver = context.getContentResolver(); mBatterySavingStats = batterySavingStats; } public BatterySaverController(Object lock, Context context, Looper looper, BatterySaverPolicy policy, BatterySavingStats batterySavingStats) { mLock = lock; mContext = context; mHandler = new MyHandler(looper); mBatterySaverPolicy = policy; // 注意,監聽了 policy change mBatterySaverPolicy.addListener(this); // FileUpdater 負責向底層檔案節點寫值,例如向CPU頻率的節點寫值,控制CPU頻率 mFileUpdater = new FileUpdater(context); mBatterySavingStats = batterySavingStats; // 重新整理獲取省電模式的快取 PowerManager.invalidatePowerSaveModeCaches(); } public BatterySaverStateMachine(Object lock, Context context, BatterySaverController batterySaverController) { mLock = lock; mContext = context; mBatterySaverController = batterySaverController; mState = STATE_OFF; // Whether or not battery saver should be "sticky" when manually enabled. // false // 注意了,值為 false,表明這個 battery saver sticky 功能是開啟的 mBatterySaverStickyBehaviourDisabled = mContext.getResources().getBoolean( com.android.internal.R.bool.config_batterySaverStickyBehaviourDisabled); // Config flag to track default disable threshold for Dynamic power savings enabled battery saver. // 80 mDynamicPowerSavingsDefaultDisableThreshold = mContext.getResources().getInteger( com.android.internal.R.integer.config_dynamicPowerSavingsDefaultDisableThreshold); }
BatterySaverController 的建構函式,只需要注意一點,那就是它監聽了省電模式策略的改變,因為這個策略會影響省電模式。
BatterySaverStateMachine 的建構函式,需要注意 mBatterySaverStickyBehaviourDisabled,它表示是否支援 battery saver sticky 功能。注意了,它的值 false,但是表示支援這個功能,而不是不支援。mDynamicPowerSavingsDefaultDisableThreshold 是與動態省電模式相關,讀者可自行分析。
繼續看 PowerManagerService 對省電模式環境的初始化程式碼
public void systemReady(IAppOpsService appOps) { synchronized (mLock) { // ... mBatterySaverController.systemReady(); mBatterySaverPolicy.systemReady(); // ... } }
首先看看 BatterySaverController#systemRead()
public void systemReady() { // 監聽這些東西,來控制 battery saver final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); filter.addAction(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED); mContext.registerReceiver(mReceiver, filter); // 如果 Runtime 重啟,那麼讀取 /data/system/battery-saver/default-values.xml 儲存的資料,否則刪除這個檔案。 mFileUpdater.systemReady(LocalServices.getService(ActivityManagerInternal.class) .isRuntimeRestarted()); // 這裡的處理邏輯為空 mHandler.postSystemReady(); }
BatterySaverController 會監聽螢幕亮滅以及 Doze 模式的廣播。
不過只有螢幕亮滅,會實際地影響省電模式,因為螢幕的亮滅會影響互動模式,而省電模式策略會根據手機是否處於互動模式而設定不同的策略。目前,在策略中,只有 CPU 頻率受影響。
再來看看 BatterySaverPolicy#systemReady()
public void systemReady() { ConcurrentUtils.wtfIfLockHeld(TAG, mLock); // 下面兩個欄位,目前沒有值,但是會控制省電模式策略,進而影響省電模式 mContentResolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.BATTERY_SAVER_CONSTANTS), false, this); mContentResolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS), false, this); // 無障礙相關 final AccessibilityManager acm = mContext.getSystemService(AccessibilityManager.class); acm.addAccessibilityStateChangeListener(enabled -> mAccessibilityEnabled.update(enabled)); mAccessibilityEnabled.initialize(acm.isEnabled()); // 汽車相關 UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class); uiModeManager.addOnProjectionStateChangedListener(UiModeManager.PROJECTION_TYPE_AUTOMOTIVE, mContext.getMainExecutor(), mOnProjectionStateChangedListener); mAutomotiveProjectionActive.initialize( uiModeManager.getActiveProjectionTypes() != UiModeManager.PROJECTION_TYPE_NONE); // 監聽 SettingProvider 的 config 表中,關於 battery_saver 名稱空間下的所有欄位值。 // 目前,這些欄位都為空,但是這些欄位會影響省電模式策略,進而控制省電模式 DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_BATTERY_SAVER, mContext.getMainExecutor(), this); mLastDeviceConfigProperties = DeviceConfig.getProperties(DeviceConfig.NAMESPACE_BATTERY_SAVER); onChange(true, null); }
BatterySaverPolicy 本身有一個預設的策略,但是可以通過 SettingsProvider 中的一些欄位來控制策略,從而控制省電模式影響的功能。但是目前,這些欄位的值都為空,因此並不影響分析,後面或許我另寫一篇文章,分析如何控制省電模式策略。
繼續看 PowerManagerService 對省電模式環境的初始化程式碼
public void onBootPhase(int phase) { synchronized (mLock) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { incrementBootCount(); } else if (phase == PHASE_BOOT_COMPLETED) { // ... mBatterySaverStateMachine.onBootCompleted(); // ... } } }
BatterySaverStateMachine.onBootCompleted() 程式碼如下:
public void onBootCompleted() { putGlobalSetting(Settings.Global.LOW_POWER_MODE, 0); runOnBgThread(() -> { // 監聽資料庫欄位 final ContentResolver cr = mContext.getContentResolver(); // Settings.Global.LOW_POWER_MODE 代表省電模式是否開啟 cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE), false, mSettingsObserver, UserHandle.USER_SYSTEM); // Settings.Global.LOW_POWER_MODE_STICKY 代表 battery saver sticky 功能是否開啟 cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_STICKY), false, mSettingsObserver, UserHandle.USER_SYSTEM); // Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL 代表觸發省電模式的電量百分比 cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), false, mSettingsObserver, UserHandle.USER_SYSTEM); // Settings.Global.AUTOMATIC_POWER_SAVE_MODE 代表自動省電模式的型別 // 型別有三個,根據電量百分比觸發,動態省電模式模式,或者none cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.AUTOMATIC_POWER_SAVE_MODE), false, mSettingsObserver, UserHandle.USER_SYSTEM); // Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED 代表是否開啟動態省電模式 cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED), false, mSettingsObserver, UserHandle.USER_SYSTEM); // Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD 代表動態省電模式關閉的閾值 cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD), false, mSettingsObserver, UserHandle.USER_SYSTEM); // Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED 表示是否開啟了 battery saver sticky auto disable // 對應於 Settings->Battery->Battery Saver->Turn off when charging cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED), false, mSettingsObserver, UserHandle.USER_SYSTEM); // Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL 表示 battery saver sticky auto disable 的閾值 cr.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL), false, mSettingsObserver, UserHandle.USER_SYSTEM); synchronized (mLock) { /** * If 1, battery saver ({@link #LOW_POWER_MODE}) will be re-activated after the device * is unplugged from a charger or rebooted. */ // battery saver sticky 功能是否被開啟 final boolean lowPowerModeEnabledSticky = getGlobalSetting( Settings.Global.LOW_POWER_MODE_STICKY, 0) != 0; if (lowPowerModeEnabledSticky) { mState = STATE_PENDING_STICKY_ON; } mBootCompleted = true; // 讀取資料庫欄位,並根據情況,開啟/關閉省電模式 refreshSettingsLocked(); // 自動開啟/關閉省電模式 doAutoBatterySaverLocked(); } }); }
這裡主要是監聽並讀取與省電模式相關的資料庫欄位,由於現在是分析初始化環境,因此這裡不分析觸發省電模式的程式碼。這些欄位值是什麼意思,請注意看註釋。
至此,省電模式環境的初始化程式碼已經分析完畢,你可能對程式碼中提到的一些概念非常迷惑,我剛開啟接觸的時候也是一樣。為了後面程式碼分析的順利進行,現在預備幾個知識
到此這篇關於初識Android PowerManagerService省電模式的文章就介紹到這了,更多相關Andorra PowerManagerService內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45