返回顶部
首页 > 资讯 > 移动开发 >Android PowerManagerService 打开省电模式
  • 192
分享到

Android PowerManagerService 打开省电模式

2024-04-02 19:04:59 192人浏览 泡泡鱼
摘要

目录概要打开省电模式BatterySaverStateMachine状态管理BatterySaverController切换省电模式BattterySaverPolicy控制省电策略

概要

初识Android PowerManagerService省电模式对省电模式进行了一个初步认识,介绍了一些概念,以及对省电模式环境初始化的代码进行了简单分析。读者需要仔细阅读第一篇文章,再来看这一篇文章。

打开省电模式,有三种方式:

  • 手动模式,也就是用户手动打开省电模式。
  • 自动模式,用户设置一个电量百分比阈值,当电量低于这个阈值,自动触发省电模式。
  • 动态模式,这种模式其实就是自动模式。根据文档,这个模式是提供给应用,根据情况自动调整触发省电模式的阈值。

本文只关注如下内容:

  • 省电模式的打开过程。
  • 什么是 battery saver sticky 模式。

只要掌握了上面2点内容,自动模式、动态模式,都可以自行分析。

打开省电模式

现在以手动打开省电模式为例,分析省电模式的打开过程。

从初识Android PowerManagerService省电模式可知,在 Settings->Battery->Battery Saver 界面,可以手动打开省电模式,调用代码如下

最终会调用 PowerManagerService 对应的方法:

public boolean setPowerSaveModeEnabled(boolean enabled) {
    if (mContext.checkCallinGorSelfPermission(android.Manifest.permission.POWER_SAVER)
            != PackageManager.PERMISSION_GRANTED) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.DEVICE_POWER, null);
    }
    final long ident = Binder.clearCallingIdentity();
    try {
        return setLowPowerModeInternal(enabled);
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}


private boolean setLowPowerModeInternal(boolean enabled) {
    synchronized (mLock) {
        // 充电状态下,不允许打开/关闭省电模式
        if (mIsPowered) {
            return false;
        }

        mBatterySaverStateMachine.setBatterySaverEnabledManually(enabled);

        return true;
    }
}

在 AOSP 的设计中,省电模式和充电状态是冲突的。如果设备处于省电模式状态,此时插入充电器,那么一定会关闭省电模式。如果设备处于充电状态,那么是不允许打开省电模式的。

说实话,我不是很认同这种设计。我认为省电模式是用户的强烈个人意愿,只能由用户自己决定打开或者关闭。

BatterySaverStateMachine状态管理

从上面代码可知,打开省电模式时,通过 BatterySaverStateMachine#setBatterySaverEnabledManually() 方法,把指令传给状态机

public void setBatterySaverEnabledManually(boolean enabled) {
    synchronized (mLock) {
        updateStateLocked(true, enabled);
    }
}

状态机通过 updateStateLocked() 更新内部状态,然后根据状态执行相应的操作。 注意,这里的第一个参数表示是否是用户手动打开省电模式,值为 true,第二个参数表示是否打开省电模式,根据我们分析的例子,这里的值为 true。

    private void updateStateLocked(boolean manual, boolean enable) {
        if (!manual && !(mBootCompleted && mSettingsLoaded && mBatteryStatusSet)) {
            return; // Not fully initialized yet.
        }

        switch (mState) {
            case STATE_OFF: {
                if (!mIsPowered) { // 非充电模式,才允许操作省电模式
                    if (manual) { // 手动操作
                        if (!enable) {
                            return;
                        }
                        // 用户手动打开省电模式
                        enableBatterySaverLocked( true,  true,
                                BatterySaverController.REASON_MANUAL_ON);
                        hideStickyDisabledNotification();
                        // 状态切换为 STATE_MANUAL_ON
                        mState = STATE_MANUAL_ON;
                    } else if (isAutomaticModeActiveLocked() && isInAutomaticLowZoneLocked()) {
                        // ... 自动模式
                    } else if (isDynamicModeActiveLocked() && isInDynamicLowZoneLocked()) { 
                        // ... 动态模式
                    }
                }
                break;
            }

            // ...
        }
    }

状态机里的默认状态是 STATE_OFF,表示省电模式默认关闭。

通过 enableBatterySaverLocked( true, true, BatterySaverController.REASON_MANUAL_ON); 打开省电模式,然后把状态切换为 STATE_MANUAL_ON。对于每一次状态切换,我们都要注意,因此这会影响下一次状态切换。

private void enableBatterySaverLocked(boolean enable, boolean manual, int intReason) {
    enableBatterySaverLocked(enable, manual, intReason, reasonToString(intReason));
}

private void enableBatterySaverLocked(boolean enable, boolean manual, int intReason,
        String strReason) {
    final boolean wasEnabled = mBatterySaverController.isFullEnabled();
    // 已经处于省电模式状态
    if (wasEnabled == enable) {
        return;
    }

    // 充电中,是不允许打开省电模式的
    if (enable && mIsPowered) {
        return;
    }

    mLastChangedIntReason = intReason;
    mLastChangedStrReason = strReason;

    mSettingBatterySaverEnabled = enable;
    // 1. 保存省电模式的状态
    putGlobalSetting(Settings.Global.LOW_POWER_MODE, enable ? 1 : 0);

    // 2. 打开 battery saver sticky 模式
    if (manual) { // 用户手动操作省电模式
        // mBatterySaverStickyBehaviourDisabled 默认为 false,表示支持 battery saver sticky 模式
        setStickyActive(!mBatterySaverStickyBehaviourDisabled && enable);
    }

    // 3. 通过 BatterySaverController 打开省电模式
    mBatterySaverController.enableBatterySaver(enable, intReason);

    // 动态省电模式相关
    if (intReason == BatterySaverController.REASON_DYNAMIC_POWER_SAVINGS_AUTOMATIC_ON) {
        triggerDynamicModeNotification();
    } else if (!enable) {
        hideDynamicModeNotification();
    }
}

在打开省电模式之前,首先把数据库 Settings.Global.LOW_POWER_MODE 字段的值保存为 1。

low power 应该翻译为低功耗,俗称省电模式,而 low battery 才应该翻译为低电量,不要混淆了。 源码中 BatteryManagerService#getBatteryLevelLow() 表示电量是否低于自动省电模式的电量百分比,这个函数的命名非常差劲,一度让我误以为是低电量(电量低于15%),其实它表示是否触发了自动省电模式。

第二步,我们要注意了,这里涉及了 battery saver sticky 功能。根据判断条件可知,只有在用户手动操作省电模式的情况下,才会触发 battery saver sticky 功能,来看下 setStickyActive()

private void setStickyActive(boolean active) {
    // 表示 battery saver sticky 模式已经打开
    mSettingBatterySaverEnabledSticky = active;
    // Settings.Global.LOW_POWER_MODE_STICKY 代表 battery saver sticky功能的状态
    putGlobalSetting(Settings.Global.LOW_POWER_MODE_STICKY,
            mSettingBatterySaverEnabledSticky ? 1 : 0);
}

很简单,就是保存状态,表示 battery saver sticky 功能已经打开。

第三步,把打开省电模式的实际操作,交给了省电模式控制器 BatterySaverController

BatterySaverController切换省电模式

现在来看下 BatterySaverController#enableBatterySaver() 如何打开省电模式

public void enableBatterySaver(boolean enable, int reason) {
    synchronized (mLock) {
        if (getFullEnabledLocked() == enable) {
            return;
        }
        // 1. 保存省电模式的状态
        setFullEnabledLocked(enable);

        // 2. 更新省电模式策略
        if (updatePolicyLevelLocked()) {
            // 3. 处理省电模式状态的改变
            mHandler.postStateChanged( true, reason);
        }
    }
}

private boolean getFullEnabledLocked() {
    return mFullEnabledRaw;
}
private void setFullEnabledLocked(boolean value) {
    if (mFullEnabledRaw == value) {
        return;
    }
    // 刷新省电模式的缓存,客户端可以通过 PowerManager 获取省电模式状态
    PowerManager.invalidatePowerSaveModeCaches();
    mFullEnabledRaw = value;
}

首先使用 mFullEnabledRaw 保存省电模式状态。

然后,更新省电模式的策略。省电模式会影响很多模块的功能,例如,最直观的就是影响屏幕亮度。因此打开省电模式,必须得有一个策略,这些策略影响某些模块的功能。

最后,处理省电模式状态的改变。其中包括切换省电模式,通知省电模式的监听者。

mFullEnabledRaw 表示 full battery saver,其实就是用户用到的省电模式。其实还有一种省电模式 adaptive battery saver,这种省电模式,是通过命令行设置的,应该是与测试相关,执行 adb shell power set-adaptive-power-saver-enabled true 来开启,具体可以参考 PowerManagerShellCommand 类。

BattterySaverPolicy控制省电策略

现在来看下 BatterySaverController#updatePolicyLevelLocked() 如何更新省电模式策略

private boolean updatePolicyLevelLocked() {
    if (getFullEnabledLocked()) {
        // 设置省电模式 policy level
        return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_FULL);
    } else if (getAdaptiveEnabledLocked()) {
        return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_ADAPTIVE);
    } else {
        return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_OFF);
    }
}

原来是给 BatterySaverPolicy 设置了 policy level,值为 BatterySaverPolicy.POLICY_LEVEL_FULL

boolean setPolicyLevel(@PolicyLevel int level) {
    synchronized (mLock) {
        if (mPolicyLevel == level) {
            return false;
        }
        if (mPolicyLevel == POLICY_LEVEL_FULL) {
            mFullPolicy = mDefaultFullPolicy;
        }
        switch (level) {
            case POLICY_LEVEL_FULL:
            case POLICY_LEVEL_ADAPTIVE:
            case POLICY_LEVEL_OFF:
                // 1. 保存 level
                mPolicyLevel = level;
                break;
            default:
                Slog.wtf(TAG, "setPolicyLevel invalid level given: " + level);
                return false;
        }
        // 2. 根据 level,更新有效的 policy
        updatePolicyDependenciesLocked();
        return true;
    }
}

BatterSaverPolicy 保存了 policy level,并且调用 updatePolicyDependenciesLocked() 来更新有效的 battery saver policy

private void updatePolicyDependenciesLocked() {
    // 1. 根据 policy level, 获取对应的 policy
    final Policy rawPolicy = getCurrentRawPolicyLocked();

    // 刷新省电模式缓存
    invalidatePowerSaveModeCaches();

    // 车载
    final int locationMode;
    if (mAutomotiveProjectionActive.get()
            && rawPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE
            && rawPolicy.locationMode != PowerManager.LOCATION_MODE_FOREGROUND_ONLY) {
        // If car projection is enabled, ensure that navigation works.
        locationMode = PowerManager.LOCATION_MODE_FOREGROUND_ONLY;
    } else {
        locationMode = rawPolicy.locationMode;
    }

    // 2. 根据获取的策略,来更新有效的策略
    // mEffectivePolicyRaw 表示实际生效的 policy
    // mEffectivePolicyRaw 的数据,基本上都是从 rawPolicy 中复制过来的
    // 只有几项是需要调整的,例如 车载 或者 无障碍,这两个特殊的情况,在使用时注意下即可
    mEffectivePolicyRaw = new Policy(
            rawPolicy.adjustBrightnessFactor,
            rawPolicy.advertiseIsEnabled,
            rawPolicy.cpuFrequenciesForInteractive,
            rawPolicy.cpuFrequenciesForNoninteractive,
            rawPolicy.deferFullBackup,
            rawPolicy.deferKeyValueBackup,
            rawPolicy.disableAnimation,
            rawPolicy.disableAod,
            rawPolicy.disableLaunchBoost,
            rawPolicy.disableOptionalSensors,
            // Don't disable vibration when accessibility is on.
            rawPolicy.disableVibration && !mAccessibilityEnabled.get(),
            rawPolicy.enableAdjustBrightness,
            rawPolicy.enableDataSaver,
            rawPolicy.enableFirewall,
            // Don't force night mode when car projection is enabled.
            rawPolicy.enableNightMode && !mAutomotiveProjectionActive.get(),
            rawPolicy.enableQuickDoze,
            rawPolicy.forceAllAppsStandby,
            rawPolicy.forceBackgroundCheck,
            locationMode,
            rawPolicy.soundTriggerMode
    );
    // ...
}

// 默认省电模式策略
private Policy mFullPolicy = DEFAULT_FULL_POLICY;

private Policy getCurrentRawPolicyLocked() {
    switch (mPolicyLevel) {
        case POLICY_LEVEL_FULL:
            return mFullPolicy;
        case POLICY_LEVEL_ADAPTIVE:
            return mAdaptivePolicy;
        case POLICY_LEVEL_OFF:
        default:
            return OFF_POLICY;
    }
}

getCurrentRawPolicyLocked() 会获取默认的省电模式策略 DEFAULT_FULL_POLICY,然后根据一些情况调整省电模式策略,最后形成有效的省电模式策略 mEffectivePolicyRaw

现在让我们看看这个默认的省电策略 DEFAULT_FULL_POLICY 到底是何方神圣

private static final Policy DEFAULT_FULL_POLICY = new Policy(
        0.5f,  
        true,  
        new CpuFrequencies(), 
        new CpuFrequencies(), 
        true,  
        true,  
        false, 
        true,  
        true,  
        true,  
        true,  
        false, 
        false, 
        true,  
        true, 
        true, 
        true, 
        true, 
        PowerManager.LOCATION_MODE_FOREGROUND_ONLY, 
        PowerManager.SOUND_TRIGGER_MODE_CRITICAL_ONLY 
);

Policy 就是一个数据封装类,看下它构造函数的参数,我们就能大致猜测出省电模式影响哪些模块的功能。

这里注意下第三个和第四个参数,它表示省电模式下,需要限制频率的 CPU 的编号以及限制的频率值,这里默认是空,后面会用到。

处理省电模式状态改变

现在让我们回到打开省电模式的代码

public void enableBatterySaver(boolean enable, int reason) {
    synchronized (mLock) {
        if (getFullEnabledLocked() == enable) {
            return;
        }
        // 1. 保存省电模式的状态
        setFullEnabledLocked(enable);

        // 2. 更新省电模式策略
        if (updatePolicyLevelLocked()) {
            // 3. 处理省电模式状态的改变
            mHandler.postStateChanged( true, reason);
        }
    }
}

前两步已经分析完毕,现在来看看第三步,它最终会调用 BatterySaverController#handleBatterySaverStateChanged() 来处理省电模式状态改变

void handleBatterySaverStateChanged(boolean sendBroadcast, int reason) {
    final LowPowerModeListener[] listeners;

    final boolean enabled;
    // 获取设备是否处于交互状态
    // 一般来说,如果屏幕熄灭,设备处于非交互状态,屏幕电量,设备处于交互状态
    final boolean isInteractive = getPowerManager().isInteractive();
    final ArrayMap<String, String> fileValues;

    synchronized (mLock) {
        // 获取省电模式的状态
        enabled = getFullEnabledLocked() || getAdaptiveEnabledLocked();

        // 保存前一个 full battery saver状态
        mFullPreviouslyEnabled = getFullEnabledLocked();
        // 保存前一个adaptive battery saver状态
        mAdaptivePreviouslyEnabled = getAdaptiveEnabledLocked();

        listeners = mListeners.toArray(new LowPowerModeListener[0]);

        mIsInteractive = isInteractive;

        if (enabled) {
            // 1. 打开省电模式情况下,获取频率受限的CPU的编号以及受限的值
            fileValues = mBatterySaverPolicy.getFileValues(isInteractive);
        } else {
            fileValues = null;
        }
    }

    // 2. 通过 PowerManagerService 向底层设置省电模式
    final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
    if (pmi != null) {
        pmi.setPowerMode(Mode.LOW_POWER, isEnabled());
    }

    // 用 BatterySavingStats 记录数据
    updateBatterySavingStats();

    // 3. 根据策略,限制或恢复CPU频率
    if (ArrayUtils.isEmpty(fileValues)) {
        // CPU 策略为空,表示需要恢复 CPU 之前的频率
        mFileUpdater.restoreDefault();
    } else {
        // CPU 频率策略不为空,表示需要限制 CPU 频率
        mFileUpdater.writeFiles(fileValues);
    }

    if (sendBroadcast) {
        // 4. 发送广播
        Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);

        // 可以在 frameworks-res 的配置文件中配置一个应用的包名
        // 这个应用可以在manifest.xml中注册广播接收器,接收省电模式状态改变
        if (getPowerSaveModeChangedListenerPackage().isPresent()) {
            intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)
                    .setPackage(getPowerSaveModeChangedListenerPackage().get())
                    .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
                            | Intent.FLAG_RECEIVER_FOREGROUND);
            mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
        }

        // 发送一个内部版本的广播,但是接收者需要权限
        intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED_INTERNAL);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
                Manifest.permission.DEVICE_POWER);

        // 5. 通知监听者
        for (LowPowerModeListener listener : listeners) {
            final PowerSaveState result =
                    mBatterySaverPolicy.getBatterySaverPolicy(listener.getServiceType());
            listener.onLowPowerModeChanged(result);
        }
    }
}

第一步和第三步,是在省电模式下限制 CPU 频率的。根据前面分析可知,目前默认策略是没有配置CPU频率的,因此这两步不分析了。我将在后面的文章中,分析如何控制省电模式策略,到时候再来分析这里的代码逻辑。

第二步,通过 PowerManagerService 向底层设置省电模式,底层称之为低功耗模式(low power mode)。

第四步,发送省电模式状态改变的广播。

第五步,通知监听者。谁会是监听者呢?当然是那些受省电模式影响的模块。

让我们看下返回给监听者的数据到底是什么?看下mBatterySaverPolicy.getBatterySaverPolicy(listener.getServiceType())

    public PowerSaveState getBatterySaverPolicy(@ServiceType int type) {
        synchronized (mLock) {
            final Policy currPolicy = getCurrentPolicyLocked();
            final PowerSaveState.Builder builder = new PowerSaveState.Builder()
                    .setGlobalBatterySaverEnabled(currPolicy.advertiseIsEnabled);
            switch (type) {
                case ServiceType.LOCATION:
                    boolean isEnabled = currPolicy.advertiseIsEnabled
                            || currPolicy.locationMode != PowerManager.LOCATION_MODE_NO_CHANGE;
                    return builder.setBatterySaverEnabled(isEnabled)
                            .setLocationMode(currPolicy.locationMode)
                            .build();
                case ServiceType.ANIMATION:
                    return builder.setBatterySaverEnabled(currPolicy.disableAnimation)
                            .build();
                // ...

                case ServiceType.VIBRATION:
                    return builder.setBatterySaverEnabled(currPolicy.disableVibration)
                            .build();
                case ServiceType.FORCE_ALL_APPS_STANDBY:
                    return builder.setBatterySaverEnabled(currPolicy.forceAllAppsStandby)
                            .build();
                case ServiceType.FORCE_BACKGROUND_CHECK:
                    return builder.setBatterySaverEnabled(currPolicy.forceBackgroundCheck)
                            .build();
                // ...
                default:
                    return builder.setBatterySaverEnabled(currPolicy.advertiseIsEnabled)
                            .build();
            }
        }
    }

原来,根据监听者的类型,返回一个 PowerSaveState 对象,这个对象中只包含了监听者关心的数据。

从这里,我们应该有所领悟,如果我们自己开发了一个功能模块

  • 如果受省电模式策略影响,必须注册一个监听器,获取省电模式下策略,然后调整模块的功能。
  • 如果这个模块是个耗电大户,那么必须监听省电模式,在省电模式下执行相应的操作。

现在很多项目都关注电量消耗问题,省电模式到底能让手机待机多长时间,也是一个考核的指标。

battery saver sticky 模式

根据前面的分析,只有在用户手动操作省电模式的时候,才会相应的打开或者关闭 battery saver sticky 模式。

我先总结下什么是 battery saver sticky 模式? 当手机已经处于省电模式,插入电源,系统会默认关闭省电模式,如果此时拔掉电源或者手机重启,当 battery saver sticky 功能已经打开的情况下,系统会重新打开省电模式。

现在让我们从代码角度分析,继续使用上面的例子分析,假如现在已经打开了省电模式,此时插入了电源,来看下状态机的切换动作 BatterySaverStateMachine#updateStateLocked()

    private void updateStateLocked(boolean manual, boolean enable) {
        if (!manual && !(mBootCompleted && mSettingsLoaded && mBatteryStatusSet)) {
            return; // Not fully initialized yet.
        }

        switch (mState) {
            case STATE_OFF: {
                if (!mIsPowered) { // 充电状态下,不允许打开省电模式
                    if (manual) { // 手动模式
                        if (!enable) {
                            Slog.e(TAG, "Tried to disable BS when it's already OFF");
                            return;
                        }
                        enableBatterySaverLocked( true,  true,
                                BatterySaverController.REASON_MANUAL_ON);
                        hideStickyDisabledNotification();
                        // 1. 用户打开省电模式,状态切换为 STATE_MANUAL_ON
                        mState = STATE_MANUAL_ON;
                    } else if (isAutomaticModeActiveLocked() && isInAutomaticLowZoneLocked()) {
                        // 自动模式 ...
                    } else if (isDynamicModeActiveLocked() && isInDynamicLowZoneLocked()) {
                        // 动态模式 ...
                    }
                }
                break;
            }

            case STATE_MANUAL_ON: {
                if (manual) {
                    // ...
                } else if (mIsPowered) { // 2. 插入电源
                    // 关闭省电模式
                    enableBatterySaverLocked( false,  false,
                            BatterySaverController.REASON_PLUGGED_IN);
                    // 手动打开省电模式时,mSettingBatterySaverEnabledSticky 设置为 true
                    // mBatterySaverStickyBehaviourDisabled 默认为 false,表示支持这个 feature
                    if (mSettingBatterySaverEnabledSticky
                            && !mBatterySaverStickyBehaviourDisabled) {
                        // 插入电源,状态切换为 STATE_PENDING_STICKY_ON
                        mState = STATE_PENDING_STICKY_ON;
                    } else {
                        mState = STATE_OFF;
                    }
                }
                break;
            }

            // ...

            case STATE_PENDING_STICKY_ON: { // 3. battery saver sticky 模式操作
                if (manual) {
                    return;
                }
                // mSettingBatterySaverStickyAutoDisableEnabled 对应 Battery Saver界面下的 Turn off when charging 开关
                // mSettingBatterySaverStickyAutoDisableThreshold 默认值为 90
                final boolean shouldTurnOffSticky = mSettingBatterySaverStickyAutoDisableEnabled
                        && mBatteryLevel >= mSettingBatterySaverStickyAutoDisableThreshold;
                // 手动打开省电模式,再插入电源,此时 isStickyDisabled 值为 false
                final boolean isStickyDisabled =
                        mBatterySaverStickyBehaviourDisabled || !mSettingBatterySaverEnabledSticky;
                if (isStickyDisabled || shouldTurnOffSticky) {
                    // 3.2 如果Turn off when charging 开关被打开,并且电量大于90%,那么不会重新打开省电模式
                    mState = STATE_OFF;
                    setStickyActive(false);
                    triggerStickyDisabledNotification();
                } else if (!mIsPowered) {
                    // Re-enable BS.
                    // 3.1 断开电源,重新打开省电模式
                    enableBatterySaverLocked( true,  true,
                            BatterySaverController.REASON_STICKY_RESTORE);
                    mState = STATE_MANUAL_ON;
                }
                break;
            }
            // ...
        }
    }

首先看下第一步,它打开了省电模式,并且状态切换为 STATE_MANUAL_ON

如果此时,插入电源,那么会进入第二步, 关闭省电模式, 并把状态切换为 STATE_PENDING_STICKY_ON

如果关闭了设置中 Battery Saver 界面的 Turn off when Charging 开关,此时拔掉电源,那么进入 3.1 步,又会再次打开省电模式,这就是 sticky 的含义。

如果打开了设置中 Battery Saver 界面的 Turn off when Charging 开关,那么进入 3.2 步,不会再次打开省电模式。

设置中 Battery Saver 界面的 Turn off when Charging 开关就是 battery saver sticky auto disable 功能。

结束

通读了整个省电模式的代码,给我的感觉是很多功能都非常鸡肋,限于偏于原因,我只分析了核心的代码,那就是如何切换省电模式。剩下的其他功能,留给读者自行分析。

到此这篇关于Android PowerManagerService 打开省电模式的文章就介绍到这了,更多相关Android PowerManagerService 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android PowerManagerService 打开省电模式

本文链接: https://lsjlt.com/news/165882.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android PowerManagerService 打开省电模式
    目录概要打开省电模式BatterySaverStateMachine状态管理BatterySaverController切换省电模式BattterySaverPolicy控制省电策略...
    99+
    2024-04-02
  • 初识Android PowerManagerService省电模式
    目录前言功能介绍环境结束前言 最近遇到一些关于省电模式、电量消耗、Doze模式,等等相关问题。于是,我决定对它们进行彻底分析,那就先从省电模式开启。 功能介绍 可以在 Setting...
    99+
    2024-04-02
  • win10平板模式省电吗
    本文小编为大家详细介绍“win10平板模式省电吗”,内容详细,步骤清晰,细节处理妥当,希望这篇“win10平板模式省电吗”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。win10平板模式会省电吗:答:不会省电,和桌...
    99+
    2023-07-01
  • AndroidPowerManagerService省电模式策略控制
    目录前言监听策略改变更新策略通知监听者如何配置策略结束前言 初识Android PowerManagerService省电模式 让我们省电模式的概念有了初步的认识...
    99+
    2024-04-02
  • android怎么打开开发者模式
    要打开Android设备上的开发者模式,请按照以下步骤操作:1. 打开手机的设置菜单,可以在应用列表中找到设置图标,通常是一个齿轮或...
    99+
    2023-09-12
    android
  • 海信电视打开开发者模式进行ADB调试
    海信电视进入开发者模式方法(之一,不同型号存在差异): 新版海信电视进入开发者模式方法: "设置"-->音量控制-->音量平衡-->"OK"键+"菜单"键同时按3~5次进入工厂模式界面; 进入工厂模式:在工厂模式界面(雪花屏或者纯蓝屏)...
    99+
    2023-08-31
    智能电视 TV android
  • 电脑显示器黑屏显示省电模式如何解决
    这篇文章主要介绍“电脑显示器黑屏显示省电模式如何解决”,在日常操作中,相信很多人在电脑显示器黑屏显示省电模式如何解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”电脑显示器黑屏显示省电模式如何解决”的疑惑有所...
    99+
    2023-07-01
  • 电脑表格打开是兼容模式如何弄
    要将电脑表格打开为兼容模式,您可以按照以下步骤进行操作:1. 打开电脑表格应用程序(例如Microsoft Excel)。2. 在菜...
    99+
    2023-09-11
    电脑
  • 电脑360浏览器极速模式如何打开
    这篇文章主要介绍“电脑360浏览器极速模式如何打开”,在日常操作中,相信很多人在电脑360浏览器极速模式如何打开问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”电脑360浏览器极速模式如何打开”的疑惑有所帮助!...
    99+
    2023-07-01
  • 在Windows电脑上以安全模式打开Office应用
    在Windows电脑上以安全模式打开Office应用,可以按照以下步骤操作:1. 关闭所有Office应用程序。2. 按下Windo...
    99+
    2023-09-14
    Windows
  • wps怎么打开ppt模式
    这篇文章主要介绍“wps怎么打开ppt模式”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“wps怎么打开ppt模式”文章能帮助大家解决问题。首先打开wps,然后进入软件。 之后可以点击左侧的“新建空白...
    99+
    2023-07-02
  • win11如何打开开发者模式
    今天小编给大家分享一下win11如何打开开发者模式的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。首先点击任务栏最左边的win...
    99+
    2023-07-02
  • win10电脑怎么打开高性能模式加速游戏
    这篇文章主要介绍“win10电脑怎么打开高性能模式加速游戏”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“win10电脑怎么打开高性能模式加速游戏”文章能帮助大家解决问题。开启方法/步骤:打开wind...
    99+
    2023-06-27
  • Android软键盘显示模式及打开和关闭方式(推荐)
    Android软键盘显示模式:     Android定义了一个属性,名字为windowSoftInputMode, 用它可以让程序可以控制活动主...
    99+
    2022-06-06
    显示模式 关闭 Android
  • win7系统边休息边下载的离开模式让你省电工作两不误
      一、什么是电脑的离开模式   Windows的“离开”模式类似于待机(或休眠),待机模式可以关闭大部分设备的电源以达到节电的目的,并且在需要的时候能快速返回到工作状态。但是离开模式更要比待机&...
    99+
    2023-06-01
    win7 边休息边下载 离开模式 模式 离开 系统
  • 详解Android MVP开发模式
    本文主要讲解MVP开发模式以及具体实例。 一、简介 MVP(Model View Presenter)模式是著名的MVC(Model View Controller)模式的一...
    99+
    2022-06-06
    Android
  • win10怎么开启节电模式
    今天就跟大家聊聊有关win10怎么开启节电模式,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。很多时候为了提高笔记本电脑的用电时间和效率,特别是电脑电池容量不大的,很多人都会选择开启电...
    99+
    2023-06-27
  • win10护眼模式如何打开
    要打开Windows 10的护眼模式,您可以按照以下步骤操作:1. 点击Windows开始菜单,然后选择“设置”(图标为齿轮状)。2...
    99+
    2023-09-12
    win10
  • pycharm交互模式如何打开
    在PyCharm中,默认是以项目模式启动的,没有提供交互模式的选项。但是,你可以通过以下步骤打开PyCharm的交互模式:1. 打开...
    99+
    2023-10-18
    pycharm
  • csm如何打开兼容模式
    这篇文章主要介绍了csm如何打开兼容模式的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇csm如何打开兼容模式文章都会有所收获,下面我们一起来看看吧。 csm打开兼容模式的方法...
    99+
    2023-03-06
    csm
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作