失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > android低电量模式吗 Android P 省电模式(LowPowerMode)(二) ------ 省电行为

android低电量模式吗 Android P 省电模式(LowPowerMode)(二) ------ 省电行为

时间:2019-06-29 08:15:43

相关推荐

android低电量模式吗 Android P 省电模式(LowPowerMode)(二) ------ 省电行为

在上篇文章Android P 省电模式(LowPowerMode)(一) ------ 省电模式手动开启流程 中最后分析到,开启省电模式后,会在 BatterySaverController 中回调所有注册的 LowPowerModeListener(onLowPowerModeChanged)和 plugin(onBatterySaverChanged),并发出广播。 我们看一下 系统做了哪些事情来实现省电。

主要有 振动,亮度,网络访问,GPS位置信息,动画,语音识别几个方面。

1. 限制振动 VibratorService.java

VibratorService.java中回调:

public void systemReady() {

Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "VibratorService#systemReady");

try {

..........................

mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);

mPowerManagerInternal.registerLowPowerModeObserver(

new PowerManagerInternal.LowPowerModeListener() {

@Override

public int getServiceType() {

return ServiceType.VIBRATION;

}

@Override

public void onLowPowerModeChanged(PowerSaveState result) {

updateVibrators();//更改低电量状态

}

});

..........................

}

private void updateVibrators() {

synchronized (mLock) {

boolean devicesUpdated = updateInputDeviceVibratorsLocked();

boolean lowPowerModeUpdated = updateLowPowerModeLocked();//更改低电量状态

updateVibrationIntensityLocked();

if (devicesUpdated || lowPowerModeUpdated) {

// If the state changes out from under us then just reset.

doCancelVibrateLocked();

}

}

}

private boolean updateLowPowerModeLocked() {

boolean lowPowerMode = mPowerManagerInternal

.getLowPowerState(ServiceType.VIBRATION).batterySaverEnabled;//看看这个值怎么拿到的

if (lowPowerMode != mLowPowerMode) {

mLowPowerMode = lowPowerMode;//mLowPowerMode这个变量判断要不要震动会用到

return true;

}

return false;

}

frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java :

@Override

public PowerSaveState getLowPowerState(@ServiceType int serviceType) {

return mBatterySaverPolicy.getBatterySaverPolicy(serviceType,

mBatterySaverController.isEnabled());//这个方法根据传入的serviceType 决定要不要对省电模式做出反应,很关键的方法

}

frameworks\base\services\core\java\com\android\server\power\BatterySaverPolicy.java :

/**

* Get the {@link PowerSaveState} based on {@paramref type} and {@paramref realMode}.

* The result will have {@link PowerSaveState#batterySaverEnabled} and some other

* parameters when necessary.

*

* @param type type of the service, one of {@link ServiceType}

* @param realMode whether the battery saver is on by default

* @return State data that contains battery saver data

*/

public PowerSaveState getBatterySaverPolicy(@ServiceType int type, boolean realMode) {

synchronized (mLock) {

final PowerSaveState.Builder builder = new PowerSaveState.Builder()

.setGlobalBatterySaverEnabled(realMode);

if (!realMode) {

return builder.setBatterySaverEnabled(realMode)

.build();

}

switch (type) {

case ServiceType.GPS:

return builder.setBatterySaverEnabled(realMode)

.setGpsMode(mGpsMode)

.build();

case ServiceType.ANIMATION:

return builder.setBatterySaverEnabled(mAnimationDisabled)

.build();//mVibrationDisabledEffective决定省电模式下要不要取消动画

case ServiceType.FULL_BACKUP:

return builder.setBatterySaverEnabled(mFullBackupDeferred)

.build();

case ServiceType.KEYVALUE_BACKUP:

return builder.setBatterySaverEnabled(mKeyValueBackupDeferred)

.build();

case WORK_FIREWALL:

return builder.setBatterySaverEnabled(!mFireWallDisabled)

.build();

case ServiceType.SCREEN_BRIGHTNESS:

return builder.setBatterySaverEnabled(!mAdjustBrightnessDisabled)

.setBrightnessFactor(mAdjustBrightnessFactor)

.build();

case ServiceType.DATA_SAVER:

return builder.setBatterySaverEnabled(!mDataSaverDisabled)

.build();

case ServiceType.SOUND:

return builder.setBatterySaverEnabled(mSoundTriggerDisabled)

.build();

case ServiceType.VIBRATION:

return builder.setBatterySaverEnabled(mVibrationDisabledEffective)

.build();//mVibrationDisabledEffective决定省电模式下要不要禁止振动

case ServiceType.FORCE_ALL_APPS_STANDBY:

return builder.setBatterySaverEnabled(mForceAllAppsStandby)

.build();

case ServiceType.FORCE_BACKGROUND_CHECK:

return builder.setBatterySaverEnabled(mForceBackgroundCheck)

.build();

case ServiceType.OPTIONAL_SENSORS:

return builder.setBatterySaverEnabled(mOptionalSensorsDisabled)

.build();

case ServiceType.AOD:

return builder.setBatterySaverEnabled(mAodDisabled)

.build();

default:

return builder.setBatterySaverEnabled(realMode)

.build();

}

}

}

BatterySaverPolicy.java 这个类很关键,所有关于省电模式的默认配置都在这个类里面初始化,如果要定制省电模式行为的话,这个类会被用到。

回调的流程的最终目的就是根据配置修改了 mLowPowerMode 变量的值,这个值会在调用振动时使用,用以决定要不要振动。

@GuardedBy("mLock")

private void startVibrationLocked(final Vibration vib) {

Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationLocked");

try {

//关于省电模式下是否允许振动在这个方法里判断

if (!isAllowedToVibrateLocked(vib)) {

return;

}

//

final int intensity = getCurrentIntensityLocked(vib);

if (intensity == Vibrator.VIBRATION_INTENSITY_OFF) {

return;

}

//如果是来电且响铃时振动开关未打开,则不振动

if (vib.isRingtone() && !shouldVibrateForRingtone()) {

if (DEBUG) {

Slog.e(TAG, "Vibrate ignored, not vibrating for ringtones");

}

return;

}

........................

}

private boolean isAllowedToVibrateLocked(Vibration vib) {

//如果不在省电模式则允许振动,如果在省电模式,排除掉以下几种情况外都不允许震动

if (!mLowPowerMode) {

return true;

}

//省电模式对铃声振动不影响

if (vib.usageHint == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {

return true;

}

//省电模式对 闹钟,辅助功能和 VoIP通话,视频通话 的振动不影响

if (vib.usageHint == AudioAttributes.USAGE_ALARM ||

vib.usageHint == AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY ||

vib.usageHint == AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST) {

return true;

}

return false;

}

2. 降低屏幕亮度

frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java :

/**

* Updates the display power state asynchronously.

* When the update is finished, mDisplayReady will be set to true. The display

* controller posts a message to tell us when the actual display power state

* has been updated so we come back here to double-check and finish up.

*

* This function recalculates the display power state each time.

*

* @return True if the display became ready.

*/

private boolean updateDisplayPowerStateLocked(int dirty) {

.......................

updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);

..........................

mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,

mRequestWaitForNegativeProximity);

..........................

}

@VisibleForTesting

void updatePowerRequestFromBatterySaverPolicy(DisplayPowerRequest displayPowerRequest) {

PowerSaveState state = mBatterySaverPolicy.

getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS,

mBatterySaverController.isEnabled());

displayPowerRequest.lowPowerMode = state.batterySaverEnabled;

displayPowerRequest.screenLowPowerBrightnessFactor = state.brightnessFactor;

}

frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java :

public boolean requestPowerState(DisplayPowerRequest request,

boolean waitForNegativeProximity) {

synchronized (mSyncRoot) {

return mDisplayPowerController.requestPowerState(request,

waitForNegativeProximity);

}

}

frameworks\base\services\core\java\com\android\server\display\DisplayPowerController.java

public boolean requestPowerState(DisplayPowerRequest request,

boolean waitForNegativeProximity) {

................................

if (changed && !mPendingRequestChangedLocked) {

mPendingRequestChangedLocked = true;

sendUpdatePowerStateLocked();

}

.................................

}

}

sendUpdatePowerStateLocked 内部交由 Handler 消息处理,最终会调用 updatePowerState 方法:

private void updatePowerState() {

............................

// If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor

// as long as it is above the minimum threshold.

if (mPowerRequest.lowPowerMode) {

if (brightness > mScreenBrightnessRangeMinimum) {

final float brightnessFactor =

Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1);// 亮度缩放比例

final int lowPowerBrightness = (int) (brightness * brightnessFactor);

brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum);

}

}

............................

}

BatterySaverPolicy.java 中定义的 默认亮度缩放比例是 0.5,亮度降低一半

mAdjustBrightnessDisabled = parser.getBoolean(KEY_ADJUST_BRIGHTNESS_DISABLED, true); //原生的配置是省电模式情况下默认不调节亮度

mAdjustBrightnessFactor = parser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR, 0.5f);

3. WindowManagerService 动画

frameworks\base\services\core\java\com\android\server\wm\WindowManagerService.java :

mPowerManagerInternal.registerLowPowerModeObserver(

new PowerManagerInternal.LowPowerModeListener() {

@Override

public int getServiceType() {

return ServiceType.ANIMATION;

}

@Override

public void onLowPowerModeChanged(PowerSaveState result) {

synchronized (mWindowMap) {

//BatterySaverPolicy中配置的是否要在低电量中关闭动画,android P上是 false,默认不关闭动画,8.0上是true的

final boolean enabled = result.batterySaverEnabled;

//mAllowAnimationsInLowPowerMode代表是否在允许在低电模式下继续使用动画(默认是false,就是不允许),如果在低电模式下会把WMS的动画都关闭

if (mAnimationsDisabled != enabled && !mAllowAnimationsInLowPowerMode) {

mAnimationsDisabled = enabled;

dispatchNewAnimatorScaleLocked(null);

}

}

}

});

9.0上低电量模式下是不关闭动画的,8.0上是关闭的。

4. NetworkPolicyManagerService.java 网络防火墙

frameworks\base\services\core\java\com\android\server\net\NetworkPolicyManagerService.java

private void updateRulesForRestrictPowerUL() {

Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForRestrictPowerUL");

try {

updateRulesForDeviceIdleUL();

updateRulesForPowerSaveUL();

updateRulesForAllAppsUL(TYPE_RESTRICT_POWER);

} finally {

Trace.traceEnd(Trace.TRACE_TAG_NETWORK);

}

}

低电量模式下主要就是去更新网络访问的规则,没仔细研究,不敢妄言,Android P上也是默认没有打开限制的,开启低电量模式不去限制网络。

5. GPS 位置信息相关限制

frameworks\base\services\core\java\com\android\server\power\batterysaver\BatterySaverLocationPlugin.java :

private void updateLocationState(BatterySaverController caller) {

final boolean kill =

(caller.getBatterySaverPolicy().getGpsMode()

== PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF) &&

caller.isEnabled() && !caller.isInteractive();

if (DEBUG) {

Slog.d(TAG, "Battery saver " + (kill ? "stopping" : "restoring") + " location.");

}

Settings.Global.putInt(mContext.getContentResolver(),

Global.LOCATION_GLOBAL_KILL_SWITCH, kill ? 1 : 0);

}

/**

* If set to 1, {@link Secure#LOCATION_MODE} will be set to {@link Secure#LOCATION_MODE_OFF}

* temporarily for all users.

*

* @hide

*/

@TestApi

public static final String LOCATION_GLOBAL_KILL_SWITCH =

"location_global_kill_switch";

低电量情况下,灭屏后会关闭GPS,临时限制所有应用访问位置信息。

以上都是 开启低电量模式后,BatterySaverController.java 中主动去回调的,以下是 各模块自己监听 ACTION_POWER_SAVE_MODE_CHANGED 广播后自己处理的

6. 语音互动的功能

frameworks\base\services\voiceinteraction\java\com\android\server\soundtrigger\SoundTriggerHelper.java :

// A single routine that implements the start recognition logic for both generic and keyphrase

// models.

private int startRecognitionLocked(ModelData modelData, boolean notify) {

...........................

if (!isRecognitionAllowed()) {

// Nothing to do here.

Slog.w(TAG, "startRecognition requested but not allowed.");

MetricsLogger.count(mContext, "sth_start_recognition_not_allowed", 1);

return STATUS_OK;

}

}

// Whether we are allowed to run any recognition at all. The conditions that let us run

// a recognition include: no active phone call or not being in a power save mode. Also,

// the native service should be enabled.

private boolean isRecognitionAllowed() {

return !mCallActive && !mServiceDisabled && !mIsPowerSaveMode;

}

低电量模式下不识别语音

其他各上层模块,如settings,systemUI 也监听了 ACTION_POWER_SAVE_MODE_CHANGED 广播,主要是做一些 UI上的变化。

如果觉得《android低电量模式吗 Android P 省电模式(LowPowerMode)(二) ------ 省电行为》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。