diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 1d464c005cb9d..b71578060fdcf 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -2,22 +2,23 @@ ** ** Copyright 2007, The Android Open Source Project ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at ** -** http://www.apache.org/licenses/LICENSE-2.0 +** http://www.apache.org/licenses/LICENSE-2.0 ** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and ** limitations under the License. */ package android.os; import android.os.WorkSource; +import android.os.PowerSaveState; /** @hide */ @@ -45,6 +46,7 @@ interface IPowerManager void nap(long time); boolean isInteractive(); boolean isPowerSaveMode(); + PowerSaveState getPowerSaveState(int serviceType); boolean setPowerSaveMode(boolean mode); boolean isDeviceIdleMode(); boolean isLightDeviceIdleMode(); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 31b3bc988f406..a713eef72c45a 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -970,6 +970,24 @@ public final class PowerManager { } } + /** + * Get data about the battery saver mode for a specific service + * @param serviceType unique key for the service, one of + * {@link com.android.server.power.BatterySaverPolicy.ServiceType} + * @return Battery saver state data. + * + * @hide + * @see com.android.server.power.BatterySaverPolicy + * @see PowerSaveState + */ + public PowerSaveState getPowerSaveState(int serviceType) { + try { + return mService.getPowerSaveState(serviceType); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Returns true if the device is currently in idle mode. This happens when a device * has been sitting unused and unmoving for a sufficiently long period of time, so that diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index d0db2555823f5..44addfc9bb1dc 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -131,12 +131,13 @@ public abstract class PowerManagerInternal { public abstract void setDozeOverrideFromDreamManager( int screenState, int screenBrightness); - public abstract boolean getLowPowerModeEnabled(); + public abstract PowerSaveState getLowPowerState(int serviceType); public abstract void registerLowPowerModeObserver(LowPowerModeListener listener); public interface LowPowerModeListener { - public void onLowPowerModeChanged(boolean enabled); + int getServiceType(); + void onLowPowerModeChanged(PowerSaveState state); } public abstract boolean setDeviceIdleMode(boolean enabled); diff --git a/core/java/android/os/PowerSaveState.aidl b/core/java/android/os/PowerSaveState.aidl new file mode 100644 index 0000000000000..e3f572d58e4ff --- /dev/null +++ b/core/java/android/os/PowerSaveState.aidl @@ -0,0 +1,19 @@ +/* +** Copyright 2017, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.os; + +parcelable PowerSaveState; \ No newline at end of file diff --git a/core/java/android/os/PowerSaveState.java b/core/java/android/os/PowerSaveState.java new file mode 100644 index 0000000000000..9269e762ef4c4 --- /dev/null +++ b/core/java/android/os/PowerSaveState.java @@ -0,0 +1,95 @@ +/* Copyright 2017, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +package android.os; + +/** + * Data class for battery saver state. It contains the data + *
+ * 1. Whether battery saver mode is enabled
+ * 2. Specific parameters to use in battery saver mode(i.e. screen brightness, gps mode)
+ *
+ * @hide
+ */
+public class PowerSaveState implements Parcelable {
+ public final boolean batterySaverEnabled;
+ public final int gpsMode;
+ public final float brightnessFactor;
+
+ public PowerSaveState(Builder builder) {
+ batterySaverEnabled = builder.mBatterySaverEnabled;
+ gpsMode = builder.mGpsMode;
+ brightnessFactor = builder.mBrightnessFactor;
+ }
+
+ public PowerSaveState(Parcel in) {
+ batterySaverEnabled = in.readByte() != 0;
+ gpsMode = in.readInt();
+ brightnessFactor = in.readFloat();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeByte((byte) (batterySaverEnabled ? 1 : 0));
+ dest.writeInt(gpsMode);
+ dest.writeFloat(brightnessFactor);
+ }
+
+ public static final class Builder {
+ private boolean mBatterySaverEnabled = false;
+ private int mGpsMode = 0;
+ private float mBrightnessFactor = 0.5f;
+
+ public Builder() {}
+
+ public Builder setBatterySaverEnabled(boolean enabled) {
+ mBatterySaverEnabled = enabled;
+ return this;
+ }
+
+ public Builder setGpsMode(int mode) {
+ mGpsMode = mode;
+ return this;
+ }
+
+ public Builder setBrightnessFactor(float factor) {
+ mBrightnessFactor = factor;
+ return this;
+ }
+
+ public PowerSaveState build() {
+ return new PowerSaveState(this);
+ }
+ }
+
+ public static final Parcelable.Creator
+ * vibration_disabled (boolean)
+ * animation_disabled (boolean)
+ * soundtrigger_disabled (boolean)
+ * fullbackup_deferred (boolean)
+ * keyvaluebackup_deferred (boolean)
+ * firewall_disabled (boolean)
+ * gps_mode (int)
+ * adjust_brightness_disabled (boolean)
+ * adjust_brightness_factor (float)
+ *
+ * @hide
+ * @see com.android.server.power.BatterySaverPolicy
+ */
+ public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
+
/**
* App standby (app idle) specific settings.
* This is encoded as a key=value list, separated by commas. Ex:
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 9a64507fc7cad..696d4981285b4 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -158,6 +158,7 @@ public class SettingsBackupTest {
Settings.Global.DEVICE_DEMO_MODE,
Settings.Global.DEVICE_IDLE_CONSTANTS,
Settings.Global.DEVICE_IDLE_CONSTANTS_WATCH,
+ Settings.Global.BATTERY_SAVER_CONSTANTS,
Settings.Global.DEVICE_NAME,
Settings.Global.DEVICE_PROVISIONED,
Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index c26032ce1cf5d..8f2b428afed2d 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -80,6 +80,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.database.ContentObserver;
import android.net.Uri;
+import android.os.PowerSaveState;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -122,6 +123,7 @@ import com.android.server.SystemConfig;
import com.android.server.SystemService;
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
+import com.android.server.power.BatterySaverPolicy.ServiceType;
import libcore.io.IoUtils;
import java.io.BufferedInputStream;
@@ -5440,7 +5442,9 @@ public class BackupManagerService {
// Don't run the backup if we're in battery saver mode, but reschedule
// to try again in the not-so-distant future.
- if (mPowerManager.isPowerSaveMode()) {
+ final PowerSaveState result =
+ mPowerManager.getPowerSaveState(ServiceType.FULL_BACKUP);
+ if (result.batterySaverEnabled) {
if (DEBUG) Slog.i(TAG, "Deferring scheduled full backups in battery saver mode");
FullBackupJob.schedule(mContext, KeyValueBackupJob.BATCH_INTERVAL);
return false;
@@ -9889,7 +9893,9 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
public void backupNow() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "backupNow");
- if (mPowerManager.isPowerSaveMode()) {
+ final PowerSaveState result =
+ mPowerManager.getPowerSaveState(ServiceType.KEYVALUE_BACKUP);
+ if (result.batterySaverEnabled) {
if (DEBUG) Slog.v(TAG, "Not running backup while in battery save mode");
KeyValueBackupJob.schedule(mContext); // try again in several hours
} else {
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 8888325152779..5fe6952fbc66d 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -25,6 +25,7 @@ import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.media.AudioManager;
+import android.os.PowerSaveState;
import android.os.BatteryStats;
import android.os.Handler;
import android.os.IVibratorService;
@@ -50,6 +51,7 @@ import android.media.AudioAttributes;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
+import com.android.server.power.BatterySaverPolicy.ServiceType;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -233,10 +235,15 @@ public class VibratorService extends IVibratorService.Stub
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mPowerManagerInternal.registerLowPowerModeObserver(
new PowerManagerInternal.LowPowerModeListener() {
- @Override
- public void onLowPowerModeChanged(boolean enabled) {
- updateInputDeviceVibrators();
- }
+ @Override
+ public int getServiceType() {
+ return ServiceType.VIBRATION;
+ }
+
+ @Override
+ public void onLowPowerModeChanged(PowerSaveState result) {
+ updateInputDeviceVibrators();
+ }
});
mContext.getContentResolver().registerContentObserver(
@@ -553,7 +560,8 @@ public class VibratorService extends IVibratorService.Stub
} catch (SettingNotFoundException snfe) {
}
- mLowPowerMode = mPowerManagerInternal.getLowPowerModeEnabled();
+ mLowPowerMode = mPowerManagerInternal
+ .getLowPowerState(ServiceType.VIBRATION).batterySaverEnabled;
if (mVibrateInputDevicesSetting) {
if (!mInputDeviceListenerRegistered) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 35713025a2f55..1712d48878567 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -24,6 +24,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.wifi.IWifiManager;
import android.net.wifi.WifiActivityEnergyInfo;
+import android.os.PowerSaveState;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Handler;
@@ -60,6 +61,7 @@ import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.PowerProfile;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
+import com.android.server.power.BatterySaverPolicy.ServiceType;
import java.io.File;
import java.io.FileDescriptor;
@@ -232,7 +234,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub
public void initPowerManagement() {
final PowerManagerInternal powerMgr = LocalServices.getService(PowerManagerInternal.class);
powerMgr.registerLowPowerModeObserver(this);
- mStats.notePowerSaveMode(powerMgr.getLowPowerModeEnabled());
+ mStats.notePowerSaveMode(
+ powerMgr.getLowPowerState(ServiceType.BATTERY_STATS)
+ .batterySaverEnabled);
(new WakeupReasonThread()).start();
}
@@ -258,9 +262,14 @@ public final class BatteryStatsService extends IBatteryStats.Stub
}
@Override
- public void onLowPowerModeChanged(boolean enabled) {
+ public int getServiceType() {
+ return ServiceType.BATTERY_STATS;
+ }
+
+ @Override
+ public void onLowPowerModeChanged(PowerSaveState result) {
synchronized (mStats) {
- mStats.notePowerSaveMode(enabled);
+ mStats.notePowerSaveMode(result.batterySaverEnabled);
}
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index fdaba0bb4c1ff..3a1ddd789f134 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -16,13 +16,6 @@
package com.android.server.location;
-import com.android.internal.app.IAppOpsService;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.location.GpsNetInitiatedHandler;
-import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
-import com.android.internal.location.ProviderProperties;
-import com.android.internal.location.ProviderRequest;
-
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.PendingIntent;
@@ -55,6 +48,7 @@ import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.Uri;
import android.os.AsyncTask;
+import android.os.PowerSaveState;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Bundle;
@@ -81,6 +75,17 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.NtpTrustedTime;
+import com.android.internal.app.IAppOpsService;
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.location.GpsNetInitiatedHandler;
+import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
+import com.android.internal.location.ProviderProperties;
+import com.android.internal.location.ProviderRequest;
+import com.android.server.power.BatterySaverPolicy;
+import com.android.server.power.BatterySaverPolicy.ServiceType;
+
+import libcore.io.IoUtils;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -96,7 +101,6 @@ import java.util.Map.Entry;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
-import libcore.io.IoUtils;
/**
* A GNSS implementation of LocationProvider used by LocationManager.
@@ -243,14 +247,6 @@ public class GnssLocationProvider implements LocationProviderInterface {
private static final int TCP_MIN_PORT = 0;
private static final int TCP_MAX_PORT = 0xffff;
- // Value of batterySaverGpsMode such that GPS isn't affected by battery saver mode.
- private static final int BATTERY_SAVER_MODE_NO_CHANGE = 0;
- // Value of batterySaverGpsMode such that GPS is disabled when battery saver mode
- // is enabled and the screen is off.
- private static final int BATTERY_SAVER_MODE_DISABLED_WHEN_SCREEN_OFF = 1;
- // Secure setting for GPS behavior when battery saver mode is on.
- private static final String BATTERY_SAVER_GPS_MODE = "batterySaverGpsMode";
-
/** simpler wrapper for ProviderRequest + Worksource */
private static class GpsRequest {
public ProviderRequest request;
@@ -548,11 +544,12 @@ public class GnssLocationProvider implements LocationProviderInterface {
private void updateLowPowerMode() {
// Disable GPS if we are in device idle mode.
boolean disableGps = mPowerManager.isDeviceIdleMode();
- switch (Settings.Secure.getInt(mContext.getContentResolver(), BATTERY_SAVER_GPS_MODE,
- BATTERY_SAVER_MODE_DISABLED_WHEN_SCREEN_OFF)) {
- case BATTERY_SAVER_MODE_DISABLED_WHEN_SCREEN_OFF:
+ final PowerSaveState result =
+ mPowerManager.getPowerSaveState(ServiceType.GPS);
+ switch (result.gpsMode) {
+ case BatterySaverPolicy.GPS_MODE_DISABLED_WHEN_SCREEN_OFF:
// If we are in battery saver mode and the screen is off, disable GPS.
- disableGps |= mPowerManager.isPowerSaveMode() && !mPowerManager.isInteractive();
+ disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
break;
}
if (disableGps != mDisableGps) {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 507899836ee24..4e9d838e7c454 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -131,6 +131,7 @@ import android.net.NetworkTemplate;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.os.PowerSaveState;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
@@ -180,6 +181,7 @@ import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
+import com.android.server.power.BatterySaverPolicy.ServiceType;
import libcore.io.IoUtils;
import com.google.android.collect.Lists;
@@ -590,18 +592,26 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mPowerManagerInternal.registerLowPowerModeObserver(
new PowerManagerInternal.LowPowerModeListener() {
- @Override
- public void onLowPowerModeChanged(boolean enabled) {
- if (LOGD) Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
- synchronized (mUidRulesFirstLock) {
- if (mRestrictPower != enabled) {
- mRestrictPower = enabled;
- updateRulesForRestrictPowerUL();
+ @Override
+ public int getServiceType() {
+ return ServiceType.NETWORK_FIREWALL;
+ }
+
+ @Override
+ public void onLowPowerModeChanged(PowerSaveState result) {
+ final boolean enabled = result.batterySaverEnabled;
+ if (LOGD) Slog.d(TAG,
+ "onLowPowerModeChanged(" + enabled + ")");
+ synchronized (mUidRulesFirstLock) {
+ if (mRestrictPower != enabled) {
+ mRestrictPower = enabled;
+ updateRulesForRestrictPowerUL();
+ }
+ }
}
- }
- }
});
- mRestrictPower = mPowerManagerInternal.getLowPowerModeEnabled();
+ mRestrictPower = mPowerManagerInternal.getLowPowerState(
+ ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
mSystemReady = true;
diff --git a/services/core/java/com/android/server/power/BatterySaverPolicy.java b/services/core/java/com/android/server/power/BatterySaverPolicy.java
new file mode 100644
index 0000000000000..8d20531a6a17d
--- /dev/null
+++ b/services/core/java/com/android/server/power/BatterySaverPolicy.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.power;
+
+import android.annotation.IntDef;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.KeyValueListParser;
+import android.util.Slog;
+import android.os.PowerSaveState;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Class to decide whether to turn on battery saver mode for specific service
+ */
+public class BatterySaverPolicy extends ContentObserver {
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ServiceType.GPS,
+ ServiceType.VIBRATION,
+ ServiceType.ANIMATION,
+ ServiceType.FULL_BACKUP,
+ ServiceType.KEYVALUE_BACKUP,
+ ServiceType.NETWORK_FIREWALL,
+ ServiceType.SCREEN_BRIGHTNESS,
+ ServiceType.SOUND,
+ ServiceType.BATTERY_STATS})
+ public @interface ServiceType {
+ int NULL = 0;
+ int GPS = 1;
+ int VIBRATION = 2;
+ int ANIMATION = 3;
+ int FULL_BACKUP = 4;
+ int KEYVALUE_BACKUP = 5;
+ int NETWORK_FIREWALL = 6;
+ int SCREEN_BRIGHTNESS = 7;
+ int SOUND = 8;
+ int BATTERY_STATS = 9;
+ }
+
+ private static final String TAG = "BatterySaverPolicy";
+
+ // Value of batterySaverGpsMode such that GPS isn't affected by battery saver mode.
+ public static final int GPS_MODE_NO_CHANGE = 0;
+ // Value of batterySaverGpsMode such that GPS is disabled when battery saver mode
+ // is enabled and the screen is off.
+ public static final int GPS_MODE_DISABLED_WHEN_SCREEN_OFF = 1;
+ // Secure setting for GPS behavior when battery saver mode is on.
+ public static final String SECURE_KEY_GPS_MODE = "batterySaverGpsMode";
+
+ private static final String KEY_GPS_MODE = "gps_mode";
+ private static final String KEY_VIBRATION_DISABLED = "vibration_disabled";
+ private static final String KEY_ANIMATION_DISABLED = "animation_disabled";
+ private static final String KEY_SOUNDTRIGGER_DISABLED = "soundtrigger_disabled";
+ private static final String KEY_FIREWALL_DISABLED = "firewall_disabled";
+ private static final String KEY_ADJUST_BRIGHTNESS_DISABLED = "adjust_brightness_disabled";
+ private static final String KEY_ADJUST_BRIGHTNESS_FACTOR = "adjust_brightness_factor";
+ private static final String KEY_FULLBACKUP_DEFERRED = "fullbackup_deferred";
+ private static final String KEY_KEYVALUE_DEFERRED = "keyvaluebackup_deferred";
+
+ private final KeyValueListParser mParser = new KeyValueListParser(',');
+
+ /**
+ * {@code true} if vibration is disabled in battery saver mode.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_VIBRATION_DISABLED
+ */
+ private boolean mVibrationDisabled;
+
+ /**
+ * {@code true} if animation is disabled in battery saver mode.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_ANIMATION_DISABLED
+ */
+ private boolean mAnimationDisabled;
+
+ /**
+ * {@code true} if sound trigger is disabled in battery saver mode
+ * in battery saver mode.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_SOUNDTRIGGER_DISABLED
+ */
+ private boolean mSoundTriggerDisabled;
+
+ /**
+ * {@code true} if full backup is deferred in battery saver mode.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_FULLBACKUP_DEFERRED
+ */
+ private boolean mFullBackupDeferred;
+
+ /**
+ * {@code true} if key value backup is deferred in battery saver mode.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_KEYVALUE_DEFERRED
+ */
+ private boolean mKeyValueBackupDeferred;
+
+ /**
+ * {@code true} if network policy firewall is disabled in battery saver mode.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_FIREWALL_DISABLED
+ */
+ private boolean mFireWallDisabled;
+
+ /**
+ * {@code true} if adjust brightness is disabled in battery saver mode.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_ADJUST_BRIGHTNESS_DISABLED
+ */
+ private boolean mAdjustBrightnessDisabled;
+
+ /**
+ * This is the flag to decide the gps mode in battery saver mode.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_GPS_MODE
+ */
+ private int mGpsMode;
+
+ /**
+ * This is the flag to decide the how much to adjust the screen brightness. This is
+ * the float value from 0 to 1 where 1 means don't change brightness.
+ *
+ * @see Settings.Global#BATTERY_SAVER_CONSTANTS
+ * @see #KEY_ADJUST_BRIGHTNESS_FACTOR
+ */
+ private float mAdjustBrightnessFactor;
+
+ private ContentResolver mContentResolver;
+
+ public BatterySaverPolicy(Handler handler) {
+ super(handler);
+ }
+
+ public void start(ContentResolver contentResolver) {
+ mContentResolver = contentResolver;
+
+ mContentResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.BATTERY_SAVER_CONSTANTS), false, this);
+ onChange(true, null);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ final String value = Settings.Global.getString(mContentResolver,
+ Settings.Global.BATTERY_SAVER_CONSTANTS);
+ updateConstants(value);
+ }
+
+ @VisibleForTesting
+ void updateConstants(final String value) {
+ synchronized (BatterySaverPolicy.this) {
+ try {
+ mParser.setString(value);
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Bad battery saver constants");
+ }
+
+ mVibrationDisabled = mParser.getBoolean(KEY_VIBRATION_DISABLED, true);
+ mAnimationDisabled = mParser.getBoolean(KEY_ANIMATION_DISABLED, true);
+ mSoundTriggerDisabled = mParser.getBoolean(KEY_SOUNDTRIGGER_DISABLED, true);
+ mFullBackupDeferred = mParser.getBoolean(KEY_FULLBACKUP_DEFERRED, true);
+ mKeyValueBackupDeferred = mParser.getBoolean(KEY_KEYVALUE_DEFERRED, true);
+ mFireWallDisabled = mParser.getBoolean(KEY_FIREWALL_DISABLED, false);
+ mAdjustBrightnessDisabled = mParser.getBoolean(KEY_ADJUST_BRIGHTNESS_DISABLED, false);
+ mAdjustBrightnessFactor = mParser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR, 0.5f);
+
+ // Get default value from Settings.Secure
+ final int defaultGpsMode = Settings.Secure.getInt(mContentResolver, SECURE_KEY_GPS_MODE,
+ GPS_MODE_DISABLED_WHEN_SCREEN_OFF);
+ mGpsMode = mParser.getInt(KEY_GPS_MODE, defaultGpsMode);
+ }
+ }
+
+ /**
+ * 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 (BatterySaverPolicy.this) {
+ final PowerSaveState.Builder builder = new PowerSaveState.Builder();
+ 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();
+ case ServiceType.FULL_BACKUP:
+ return builder.setBatterySaverEnabled(mFullBackupDeferred)
+ .build();
+ case ServiceType.KEYVALUE_BACKUP:
+ return builder.setBatterySaverEnabled(mKeyValueBackupDeferred)
+ .build();
+ case ServiceType.NETWORK_FIREWALL:
+ return builder.setBatterySaverEnabled(!mFireWallDisabled)
+ .build();
+ case ServiceType.SCREEN_BRIGHTNESS:
+ return builder.setBatterySaverEnabled(!mAdjustBrightnessDisabled)
+ .setBrightnessFactor(mAdjustBrightnessFactor)
+ .build();
+ case ServiceType.SOUND:
+ return builder.setBatterySaverEnabled(mSoundTriggerDisabled)
+ .build();
+ case ServiceType.VIBRATION:
+ return builder.setBatterySaverEnabled(mVibrationDisabled)
+ .build();
+ default:
+ return builder.setBatterySaverEnabled(realMode)
+ .build();
+ }
+ }
+ }
+
+ public void dump(PrintWriter pw) {
+ pw.println();
+ pw.println("Battery saver policy");
+ pw.println(" Settings " + Settings.Global.BATTERY_SAVER_CONSTANTS);
+ pw.println(" value: " + Settings.Global.getString(mContentResolver,
+ Settings.Global.BATTERY_SAVER_CONSTANTS));
+
+ pw.println();
+ pw.println(" " + KEY_VIBRATION_DISABLED + "=" + mVibrationDisabled);
+ pw.println(" " + KEY_ANIMATION_DISABLED + "=" + mAnimationDisabled);
+ pw.println(" " + KEY_FULLBACKUP_DEFERRED + "=" + mFullBackupDeferred);
+ pw.println(" " + KEY_KEYVALUE_DEFERRED + "=" + mKeyValueBackupDeferred);
+ pw.println(" " + KEY_FIREWALL_DISABLED + "=" + mFireWallDisabled);
+ pw.println(" " + KEY_ADJUST_BRIGHTNESS_DISABLED + "=" + mAdjustBrightnessDisabled);
+ pw.println(" " + KEY_ADJUST_BRIGHTNESS_FACTOR + "=" + mAdjustBrightnessFactor);
+ pw.println(" " + KEY_GPS_MODE + "=" + mGpsMode);
+
+ }
+}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index d3931fba82836..cd63527b05ff7 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -35,6 +35,7 @@ import android.hardware.power.V1_0.PowerHint;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
+import android.os.PowerSaveState;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -80,7 +81,7 @@ import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
-
+import com.android.server.power.BatterySaverPolicy.ServiceType;
import libcore.util.Objects;
import java.io.FileDescriptor;
@@ -192,6 +193,7 @@ public final class PowerManagerService extends SystemService
private final Context mContext;
private final ServiceThread mHandlerThread;
private final PowerManagerHandler mHandler;
+ private final BatterySaverPolicy mBatterySaverPolicy;
private LightsManager mLightsManager;
private BatteryManagerInternal mBatteryManagerInternal;
@@ -605,6 +607,7 @@ public final class PowerManagerService extends SystemService
mHandlerThread.start();
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
mConstants = new Constants(mHandler);
+ mBatterySaverPolicy = new BatterySaverPolicy(mHandler);
synchronized (mLock) {
mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
@@ -704,6 +707,7 @@ public final class PowerManagerService extends SystemService
final ContentResolver resolver = mContext.getContentResolver();
mConstants.start(resolver);
+ mBatterySaverPolicy.start(resolver);
// Register for settings changes.
resolver.registerContentObserver(Settings.Secure.getUriFor(
@@ -939,8 +943,12 @@ public final class PowerManagerService extends SystemService
listeners = new ArrayList