Android5.1 系統之省電模式探索一啟動流程
文章主要參考網址:http://www.th7.cn/Program/Android/201509/577840.shtml
android5.1 省電模式開啟位置:
設定——電池——節電助手(充電狀態下預設無法開啟,即強制關閉)
省電模式開啟後系統狀態:
不同於其他第三方省電app:除通知圖示外頂部狀態列、底部通知欄顏色全部變成亮橙色,大部分圖示等資源新增橙色,應用頂部欄也會變成橙色。
其他行為:
1.螢幕亮度調低;2.後臺(大部分)資料關閉;3.動畫全部取消;4.震動關閉。(即通過犧牲效能達到省電目的)。
涉及到廣播
POWERMANAGER.ACTION_POWER_SAVE_MODE_CHANGED
POWERMANAGER.ACTION_POWER_SAVE_MODE_CHANGING
相關程式碼:
設定應用入口檔案:
./packages/apps/Settings/src/com/android/settings/fuelgauge/BatterySaverSettings.java
托盤顯示:
./frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
托盤中callback回撥函式onPowerSaveChanged():
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
onPowerSaveChanged():(systemui內部處理):
./frameworks/base/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
GPS根據mode 更新處理:
./frameworks/base/services/core/java/com/android/server/location/GpsLocationProvider.java
傳送模式切換ing/切換廣播:
./frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
voice根據mode 更新處理:
./frameworks/base/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
流程分析
設定省電模式入口檔案
./packages/apps/Settings/src/com/android/settings/fuelgauge/BatterySaverSettings.java
關鍵程式碼:
節電助手開啟或關閉時,呼叫onSwitchChanged()方法,引數isChecked表示節電助手屬於開啟(true)或關閉(false)狀態。開啟時,傳送訊息mStartMode開啟新執行緒開始省電模式,否則關閉省電模式。
新執行緒開啟後主要執行trySetPowerSaveMode()方法。節電助手開啟時引數為true,關閉時引數為false。
提供呼叫介面檔案
./frameworks/base/core/java/android/os/PowerManager.java
PowerManager是個電源管理部分的基礎類,擁有多個子類繼承。
檢查是否開啟省電模式
註釋部分翻譯:如果裝置當前處於省電模式則返回值為true。當裝置處於此模式時,應用會盡可能的減少效能來達到增加電池續航的能力。使用者可以通過監聽事件ACTION_POWER_SAVE_MODE_CHANGED來獲取裝置狀態。
方法返回值:處於省電模式返回true,否則false。
./frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
設定省電模式
釋部分翻譯:設定省電模式,如果允許設定(即設定成功)返回true,否則返回flase。
省電模式詳細設定併發送廣播及修改資料庫
./frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
首先宣告幾個比較關鍵的全域性變數:
mIsPowered變量表示充電狀態,true表示正在充電(已接入電源),否則為false;
// If true, the device is in low power mode.
private boolean mLowPowerModeEnabled;
// Current state of the low power mode setting.
private boolean mLowPowerModeSetting;
// Current state of whether the settings are allowing auto low power mode.
private boolean mAutoLowPowerModeConfigured;
// The user turned off low power mode below the trigger level
private boolean mAutoLowPowerModeSnoozing;
// True if the battery level is currently considered low.
private boolean mBatteryLevelLow;
// True if theater mode is enabled
private boolean mTheaterModeEnabled;
mLowPowerModeSetting表示設定省電模式的當前狀態,從系統設定中獲取值,即資料庫欄位“low_power”的值是否為1的值,為1時表示處於省電模式,變數值為true;
/*
*if 1 low power mode enable
*資料庫欄位low_power的英文解釋
*/
mAutoLowPowerModeConfigured表示省電模式是否允許自動設定省電模式,即資料庫欄位“low_power_trigger_level”是否為0的值;不為0時表示允許自動設定省電模式,該變數為true;
/*資料庫欄位low_trigger_level的註釋
*Battery level [1-99]at which loe power mode autonmatically turns on
*if 0, it will not automatically turn on
*@hide
*/
mBatteryLevelLow表示電量是否處於低電量狀態,是為true否則false;
mAutoLowPowerModeSnoozing表示電量低於省電模式觸發點時,是否關閉省電模式,是為true,否則false;
該變數值是由mAutoLowPowerModeConfigured和mBatteryLevelLow這兩個變數決定的。當電量低並且允許自動設定省電模式時,如果此時省電模式是開啟的,就要設定mAutoLowPowerModeSnoozing的值為false;如果省電模式是關閉的,就要設定mAutoLowPowerModeSnoozing的值為true。就是要求mAutoLowPowerModeSnoozing變數與省電模式的邏輯保持一致。
mLowPowerModeEnbaled表示裝置是否處於省電模式,省電模式下為true,否則flase;
修改資料庫表示省電狀態欄位
SetLowPowerModeInternal()方法:
private boolean setLowPowerModeInternal(boolean mode) {
synchronized (mLock) {
if (DEBUG) Slog.d(TAG, "setLowPowerModeInternal " + mode + " mIsPowered=" + mIsPowered);
/*
*mIsPowered判斷裝置是否充電,充電狀態下預設不能開啟省電模式。
* */
if (mIsPowered) {
return false;
}
/*
*修改資料庫中表示省電模式狀態的欄位low_power,將其欄位根據mode值設為1或者0.
* 1 代表開啟,0 代表關閉省電模式。
* */
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE, mode ? 1 : 0);
mLowPowerModeSetting = mode;
if (mAutoLowPowerModeConfigured && mBatteryLevelLow) {
if (mode && mAutoLowPowerModeSnoozing) {
if (DEBUG_SPEW) {
Slog.d(TAG, "setLowPowerModeInternal: clearing low power mode snooze");
}
mAutoLowPowerModeSnoozing = false;
} else if (!mode && !mAutoLowPowerModeSnoozing) {
if (DEBUG_SPEW) {
Slog.d(TAG, "setLowPowerModeInternal: snoozing low power mode");
}
mAutoLowPowerModeSnoozing = true;
}
}
updateLowPowerModeLocked();
return true;
}
}
傳送開啟省電模式廣播
updateLowPowerModeLocked()方法:
void updateLowPowerModeLocked() {
if (mIsPowered && mLowPowerModeSetting) {//裝置正在充電並且已經開啟省電模式
if (DEBUG_SPEW) {
Slog.d(TAG, "updateLowPowerModeLocked: powered, turning setting off");
}
// Turn setting off if powered
//修改資料庫中代表省電模式狀態的欄位“low_power”,將欄位值設定為0,即關閉省電模式
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE, 0);
mLowPowerModeSetting = false;
}
/*
* 臨時變數:autoLowPowerModeEnabled。
* 當前沒有充電,自動開啟省電模式,電量低於省電模式的電量觸發點時不關閉省電模式,電池電量低,以上條件均滿足時為true。
* */
final boolean autoLowPowerModeEnabled = !mIsPowered && mAutoLowPowerModeConfigured
&& !mAutoLowPowerModeSnoozing && mBatteryLevelLow;
/*
* 臨時變數:lowPowerModeEnabled。
* 當mLowPowerModeSetting或autoLowPowerModeEnabled為真時,則設定為true。
* */
final boolean lowPowerModeEnabled = mLowPowerModeSetting || autoLowPowerModeEnabled;
/*
* 根據lowPowerModeEnabled臨時變數值和mLowPowerModeEnabled(true表示裝置處於省電模式,全域性變數)
* 判斷是否執行省電模式的功能。當兩者狀態不一致時,更新mLowPowerModeEnabled狀態值。
* */
if (mLowPowerModeEnabled != lowPowerModeEnabled) {
mLowPowerModeEnabled = lowPowerModeEnabled;
powerHintInternal(POWER_HINT_LOW_POWER, lowPowerModeEnabled ? 1 : 0);
/*
* 使用後臺執行緒BackgroundThread處理事件,會先後傳送action為ACTION_POWER_SAVE_MODE_CHANGING和
* ACTION_POWER_SAVE_MODE_CHANGED的廣播。
* */
BackgroundThread.getHandler().post(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)
.putExtra(PowerManager.EXTRA_POWER_SAVE_MODE, mLowPowerModeEnabled)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);//只有動態定義的廣播接收器才能接收到該廣播
mContext.sendBroadcast(intent);
ArrayList<PowerManagerInternal.LowPowerModeListener> listeners;
synchronized (mLock) {
listeners = new ArrayList<PowerManagerInternal.LowPowerModeListener>(
mLowPowerModeListeners);
}
for (int i=0; i<listeners.size(); i++) {
listeners.get(i).onLowPowerModeChanged(lowPowerModeEnabled);
}
intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);//只有動態定義的廣播接收器才能接收到該廣播
mContext.sendBroadcast(intent);
}
});
}
}