1. 程式人生 > >Android5.1 系統之省電模式探索一啟動流程

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);
                }
            });
        }
    }