Merge "Hook up data saver to battery saver."

This commit is contained in:
TreeHugger Robot
2017-03-24 04:55:10 +00:00
committed by Android (Google) Code Review
5 changed files with 223 additions and 8 deletions

View File

@@ -24,7 +24,17 @@ package android.os;
* @hide
*/
public class PowerSaveState implements Parcelable {
/**
* Whether we should enable battery saver for this service.
*
* @see com.android.server.power.BatterySaverPolicy.ServiceType
*/
public final boolean batterySaverEnabled;
/**
* Whether the battery saver is enabled globally, which means the data we get from
* {@link PowerManager#isPowerSaveMode()}
*/
public final boolean globalBatterySaverEnabled;
public final int gpsMode;
public final float brightnessFactor;
@@ -32,10 +42,12 @@ public class PowerSaveState implements Parcelable {
batterySaverEnabled = builder.mBatterySaverEnabled;
gpsMode = builder.mGpsMode;
brightnessFactor = builder.mBrightnessFactor;
globalBatterySaverEnabled = builder.mGlobalBatterySaverEnabled;
}
public PowerSaveState(Parcel in) {
batterySaverEnabled = in.readByte() != 0;
globalBatterySaverEnabled = in.readByte() != 0;
gpsMode = in.readInt();
brightnessFactor = in.readFloat();
}
@@ -48,12 +60,14 @@ public class PowerSaveState implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (batterySaverEnabled ? 1 : 0));
dest.writeByte((byte) (globalBatterySaverEnabled ? 1 : 0));
dest.writeInt(gpsMode);
dest.writeFloat(brightnessFactor);
}
public static final class Builder {
private boolean mBatterySaverEnabled = false;
private boolean mGlobalBatterySaverEnabled = false;
private int mGpsMode = 0;
private float mBrightnessFactor = 0.5f;
@@ -64,6 +78,11 @@ public class PowerSaveState implements Parcelable {
return this;
}
public Builder setGlobalBatterySaverEnabled(boolean enabled) {
mGlobalBatterySaverEnabled = enabled;
return this;
}
public Builder setGpsMode(int mode) {
mGpsMode = mode;
return this;

View File

@@ -322,6 +322,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
private INotificationManager mNotifManager;
private PowerManagerInternal mPowerManagerInternal;
private IDeviceIdleController mDeviceIdleController;
@GuardedBy("mUidRulesFirstLock")
private PowerSaveState mRestrictBackgroundPowerState;
// Store the status of restrict background before turning on battery saver.
// Used to restore mRestrictBackground when battery saver is turned off.
private boolean mRestrictBackgroundBeforeBsm;
// See main javadoc for instructions on how to use these locks.
final Object mUidRulesFirstLock = new Object();
@@ -332,6 +338,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackground;
@GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictPower;
@GuardedBy("mUidRulesFirstLock") volatile boolean mDeviceIdleMode;
// Store whether user flipped restrict background in battery saver mode
@GuardedBy("mUidRulesFirstLock") volatile boolean mRestrictBackgroundChangedInBsm;
private final boolean mSuppressDefaultPolicy;
@@ -617,8 +625,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
@Override
public void onLowPowerModeChanged(PowerSaveState result) {
final boolean enabled = result.batterySaverEnabled;
if (LOGD) Slog.d(TAG,
"onLowPowerModeChanged(" + enabled + ")");
if (LOGD) {
Slog.d(TAG, "onLowPowerModeChanged(" + enabled + ")");
}
synchronized (mUidRulesFirstLock) {
if (mRestrictPower != enabled) {
mRestrictPower = enabled;
@@ -626,7 +635,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
}
});
});
mRestrictPower = mPowerManagerInternal.getLowPowerState(
ServiceType.NETWORK_FIREWALL).batterySaverEnabled;
@@ -635,6 +644,32 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// read policy from disk
readPolicyAL();
// Update the restrictBackground if battery saver is turned on
mRestrictBackgroundBeforeBsm = mRestrictBackground;
mRestrictBackgroundPowerState = mPowerManagerInternal
.getLowPowerState(ServiceType.DATA_SAVER);
final boolean localRestrictBackground =
mRestrictBackgroundPowerState.batterySaverEnabled;
if (localRestrictBackground && localRestrictBackground != mRestrictBackground) {
mRestrictBackground = localRestrictBackground;
mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED,
mRestrictBackground ? 1 : 0, 0).sendToTarget();
}
mPowerManagerInternal.registerLowPowerModeObserver(
new PowerManagerInternal.LowPowerModeListener() {
@Override
public int getServiceType() {
return ServiceType.DATA_SAVER;
}
@Override
public void onLowPowerModeChanged(PowerSaveState result) {
synchronized (mUidRulesFirstLock) {
updateRestrictBackgroundByLowPowerModeUL(result);
}
}
});
if (addDefaultRestrictBackgroundWhitelistUidsUL()) {
writePolicyAL();
}
@@ -2159,6 +2194,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} catch (RemoteException e) {
// ignored; service lives in system_server
}
if (mRestrictBackgroundPowerState.globalBatterySaverEnabled) {
mRestrictBackgroundChangedInBsm = true;
}
synchronized (mNetworkPoliciesSecondLock) {
updateNotificationsNL();
writePolicyAL();
@@ -3645,6 +3684,35 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
mHandler.getLooper().getQueue().addIdleHandler(handler);
}
@VisibleForTesting
public void updateRestrictBackgroundByLowPowerModeUL(final PowerSaveState result) {
mRestrictBackgroundPowerState = result;
boolean restrictBackground = result.batterySaverEnabled;
boolean shouldInvokeRestrictBackground;
// store the temporary mRestrictBackgroundChangedInBsm and update it at last
boolean localRestrictBgChangedInBsm = mRestrictBackgroundChangedInBsm;
if (result.globalBatterySaverEnabled) {
// Try to turn on restrictBackground if (1) it is off and (2) batter saver need to
// turn it on.
shouldInvokeRestrictBackground = !mRestrictBackground && result.batterySaverEnabled;
mRestrictBackgroundBeforeBsm = mRestrictBackground;
localRestrictBgChangedInBsm = false;
} else {
// Try to restore the restrictBackground if it doesn't change in bsm
shouldInvokeRestrictBackground = !mRestrictBackgroundChangedInBsm;
restrictBackground = mRestrictBackgroundBeforeBsm;
}
if (shouldInvokeRestrictBackground) {
setRestrictBackground(restrictBackground);
}
// Change it at last so setRestrictBackground() won't affect this variable
mRestrictBackgroundChangedInBsm = localRestrictBgChangedInBsm;
}
private static void collectKeys(SparseIntArray source, SparseBooleanArray target) {
final int size = source.size();
for (int i = 0; i < size; i++) {

View File

@@ -43,7 +43,8 @@ public class BatterySaverPolicy extends ContentObserver {
ServiceType.NETWORK_FIREWALL,
ServiceType.SCREEN_BRIGHTNESS,
ServiceType.SOUND,
ServiceType.BATTERY_STATS})
ServiceType.BATTERY_STATS,
ServiceType.DATA_SAVER})
public @interface ServiceType {
int NULL = 0;
int GPS = 1;
@@ -55,6 +56,7 @@ public class BatterySaverPolicy extends ContentObserver {
int SCREEN_BRIGHTNESS = 7;
int SOUND = 8;
int BATTERY_STATS = 9;
int DATA_SAVER = 10;
}
private static final String TAG = "BatterySaverPolicy";
@@ -73,6 +75,7 @@ public class BatterySaverPolicy extends ContentObserver {
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_DATASAVER_DISABLED = "datasaver_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";
@@ -136,6 +139,14 @@ public class BatterySaverPolicy extends ContentObserver {
*/
private boolean mAdjustBrightnessDisabled;
/**
* {@code true} if data saver is disabled in battery saver mode.
*
* @see Settings.Global#BATTERY_SAVER_CONSTANTS
* @see #KEY_DATASAVER_DISABLED
*/
private boolean mDataSaverDisabled;
/**
* This is the flag to decide the gps mode in battery saver mode.
*
@@ -191,6 +202,7 @@ public class BatterySaverPolicy extends ContentObserver {
mFireWallDisabled = mParser.getBoolean(KEY_FIREWALL_DISABLED, false);
mAdjustBrightnessDisabled = mParser.getBoolean(KEY_ADJUST_BRIGHTNESS_DISABLED, false);
mAdjustBrightnessFactor = mParser.getFloat(KEY_ADJUST_BRIGHTNESS_FACTOR, 0.5f);
mDataSaverDisabled = mParser.getBoolean(KEY_DATASAVER_DISABLED, true);
// Get default value from Settings.Secure
final int defaultGpsMode = Settings.Secure.getInt(mContentResolver, SECURE_KEY_GPS_MODE,
@@ -210,7 +222,8 @@ public class BatterySaverPolicy extends ContentObserver {
*/
public PowerSaveState getBatterySaverPolicy(@ServiceType int type, boolean realMode) {
synchronized (BatterySaverPolicy.this) {
final PowerSaveState.Builder builder = new PowerSaveState.Builder();
final PowerSaveState.Builder builder = new PowerSaveState.Builder()
.setGlobalBatterySaverEnabled(realMode);
if (!realMode) {
return builder.setBatterySaverEnabled(realMode)
.build();
@@ -236,6 +249,9 @@ public class BatterySaverPolicy extends ContentObserver {
return builder.setBatterySaverEnabled(!mAdjustBrightnessDisabled)
.setBrightnessFactor(mAdjustBrightnessFactor)
.build();
case ServiceType.DATA_SAVER:
return builder.setBatterySaverEnabled(!mDataSaverDisabled)
.build();
case ServiceType.SOUND:
return builder.setBatterySaverEnabled(mSoundTriggerDisabled)
.build();
@@ -262,6 +278,7 @@ public class BatterySaverPolicy extends ContentObserver {
pw.println(" " + KEY_FULLBACKUP_DEFERRED + "=" + mFullBackupDeferred);
pw.println(" " + KEY_KEYVALUE_DEFERRED + "=" + mKeyValueBackupDeferred);
pw.println(" " + KEY_FIREWALL_DISABLED + "=" + mFireWallDisabled);
pw.println(" " + KEY_DATASAVER_DISABLED + "=" + mDataSaverDisabled);
pw.println(" " + KEY_ADJUST_BRIGHTNESS_DISABLED + "=" + mAdjustBrightnessDisabled);
pw.println(" " + KEY_ADJUST_BRIGHTNESS_FACTOR + "=" + mAdjustBrightnessFactor);
pw.println(" " + KEY_GPS_MODE + "=" + mGpsMode);

View File

@@ -37,6 +37,7 @@ import static com.android.server.net.NetworkPolicyManagerService.ProcStateSeqHis
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_WARNING;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -51,10 +52,15 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -89,6 +95,7 @@ import android.net.NetworkTemplate;
import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.UserHandle;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
@@ -198,6 +205,7 @@ public class NetworkPolicyManagerServiceTest {
private IUidObserver mUidObserver;
private INetworkManagementEventObserver mNetworkObserver;
private PowerManagerInternal mPowerManagerInternal;
private NetworkPolicyListenerAnswer mPolicyListener;
private NetworkPolicyManagerService mService;
@@ -227,12 +235,16 @@ public class NetworkPolicyManagerServiceTest {
@BeforeClass
public static void registerLocalServices() {
addLocalServiceMock(PowerManagerInternal.class);
addLocalServiceMock(DeviceIdleController.LocalService.class);
final UsageStatsManagerInternal usageStats =
addLocalServiceMock(UsageStatsManagerInternal.class);
when(usageStats.getIdleUidsForUser(anyInt())).thenReturn(new int[]{});
mActivityManagerInternal = addLocalServiceMock(ActivityManagerInternal.class);
final PowerSaveState state = new PowerSaveState.Builder()
.setBatterySaverEnabled(false).build();
final PowerManagerInternal pmInternal = addLocalServiceMock(PowerManagerInternal.class);
when(pmInternal.getLowPowerState(anyInt())).thenReturn(state);
}
@Before
@@ -401,6 +413,85 @@ public class NetworkPolicyManagerServiceTest {
removeRestrictBackgroundWhitelist(false);
}
@Test
public void testLowPowerModeObserver_ListenersRegistered()
throws Exception {
PowerManagerInternal pmInternal = LocalServices.getService(PowerManagerInternal.class);
verify(pmInternal, atLeast(2)).registerLowPowerModeObserver(any());
}
@Test
public void updateRestrictBackgroundByLowPowerMode_RestrictOnBeforeBsm_RestrictOnAfterBsm()
throws Exception {
setRestrictBackground(true);
PowerSaveState stateOn = new PowerSaveState.Builder()
.setGlobalBatterySaverEnabled(true)
.setBatterySaverEnabled(false)
.build();
mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
// RestrictBackground should be on even though battery saver want to turn it off
assertThat(mService.getRestrictBackground()).isTrue();
PowerSaveState stateOff = new PowerSaveState.Builder()
.setGlobalBatterySaverEnabled(false)
.setBatterySaverEnabled(false)
.build();
mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
// RestrictBackground should be on, following its previous state
assertThat(mService.getRestrictBackground()).isTrue();
}
@Test
public void updateRestrictBackgroundByLowPowerMode_RestrictOffBeforeBsm_RestrictOffAfterBsm()
throws Exception {
setRestrictBackground(false);
PowerSaveState stateOn = new PowerSaveState.Builder()
.setGlobalBatterySaverEnabled(true)
.setBatterySaverEnabled(true)
.build();
doReturn(true).when(mNetworkManager).setDataSaverModeEnabled(true);
mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
// RestrictBackground should be turned on because of battery saver
assertThat(mService.getRestrictBackground()).isTrue();
PowerSaveState stateOff = new PowerSaveState.Builder()
.setGlobalBatterySaverEnabled(false)
.setBatterySaverEnabled(false)
.build();
mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
// RestrictBackground should be off, following its previous state
assertThat(mService.getRestrictBackground()).isFalse();
}
@Test
public void updateRestrictBackgroundByLowPowerMode_StatusChangedInBsm_DoNotRestore()
throws Exception {
setRestrictBackground(true);
PowerSaveState stateOn = new PowerSaveState.Builder()
.setGlobalBatterySaverEnabled(true)
.setBatterySaverEnabled(true)
.build();
mService.updateRestrictBackgroundByLowPowerModeUL(stateOn);
// RestrictBackground should still be on
assertThat(mService.getRestrictBackground()).isTrue();
// User turns off RestrictBackground manually
setRestrictBackground(false);
PowerSaveState stateOff = new PowerSaveState.Builder().setBatterySaverEnabled(
false).build();
mService.updateRestrictBackgroundByLowPowerModeUL(stateOff);
// RestrictBackground should be off because user changes it manually
assertThat(mService.getRestrictBackground()).isFalse();
}
private void removeRestrictBackgroundWhitelist(boolean expectIntent) throws Exception {
// Sanity checks.
assertWhitelistUids(UID_A);
@@ -1231,7 +1322,7 @@ public class NetworkPolicyManagerServiceTest {
private void setRestrictBackground(boolean flag) throws Exception {
// Must set expectation, otherwise NMPS will reset value to previous one.
when(mNetworkManager.setDataSaverModeEnabled(flag)).thenReturn(true);
doReturn(true).when(mNetworkManager).setDataSaverModeEnabled(flag);
mService.setRestrictBackground(flag);
// Sanity check.
assertEquals("restrictBackground not set", flag, mService.getRestrictBackground());

View File

@@ -19,7 +19,9 @@ import android.os.PowerSaveState;
import android.os.Handler;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.power.BatterySaverPolicy.ServiceType;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -40,6 +42,7 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
+ "animation_disabled=false,"
+ "soundtrigger_disabled=true,"
+ "firewall_disabled=false,"
+ "datasaver_disabled=false,"
+ "adjust_brightness_disabled=true,"
+ "adjust_brightness_factor=0.7,"
+ "fullbackup_deferred=true,"
@@ -98,6 +101,18 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
testServiceDefaultValue(ServiceType.NETWORK_FIREWALL);
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyDataSaver_DefaultValueCorrect() {
mBatterySaverPolicy.updateConstants("");
final PowerSaveState batterySaverStateOn =
mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.DATA_SAVER, BATTERY_SAVER_ON);
assertThat(batterySaverStateOn.batterySaverEnabled).isFalse();
final PowerSaveState batterySaverStateOff = mBatterySaverPolicy.getBatterySaverPolicy(
ServiceType.DATA_SAVER, BATTERY_SAVER_OFF);
assertThat(batterySaverStateOff.batterySaverEnabled).isFalse();
}
@SmallTest
public void testGetBatterySaverPolicy_PolicyScreenBrightness_DefaultValueCorrect() {
testServiceDefaultValue(ServiceType.SCREEN_BRIGHTNESS);
@@ -137,7 +152,8 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
assertThat(networkState.batterySaverEnabled).isTrue();
final PowerSaveState screenState =
mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS, BATTERY_SAVER_ON);
mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS,
BATTERY_SAVER_ON);
assertThat(screenState.batterySaverEnabled).isFalse();
assertThat(screenState.brightnessFactor).isWithin(PRECISION).of(BRIGHTNESS_FACTOR);
@@ -149,6 +165,10 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
ServiceType.KEYVALUE_BACKUP, BATTERY_SAVER_ON);
assertThat(keyValueBackupState.batterySaverEnabled).isFalse();
final PowerSaveState dataSaverState = mBatterySaverPolicy.getBatterySaverPolicy(
ServiceType.DATA_SAVER, BATTERY_SAVER_ON);
assertThat(dataSaverState.batterySaverEnabled).isTrue();
final PowerSaveState gpsState =
mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.GPS, BATTERY_SAVER_ON);
assertThat(gpsState.batterySaverEnabled).isTrue();