Refactor battery saver logic + add "per device" setting

- Extract the battery saver mode transition logic to BatterySaverController.

This now also supports running different code when screen turns on and off.

- BatterySaverPolicy now takes a "per-device configuration" from config.xml,
which can be overwritten via a global setting. We'll use this to set up
max CPU frequencies.

- The actual part to write max CPU frequencies is not finished yet.

Test: atest BatterySaverPolicyTest
Bug: 68769804
Change-Id: Ife38c2cd94ac9902911b005dbbca8b0d0a62e6d7
diff --git a/services/tests/servicestests/res/values/strings.xml b/services/tests/servicestests/res/values/strings.xml
index 1253d44..3ac56bb 100644
--- a/services/tests/servicestests/res/values/strings.xml
+++ b/services/tests/servicestests/res/values/strings.xml
@@ -28,4 +28,8 @@
     <string name="test_account_type2_authenticator_label">AccountManagerService Test Account Type2</string>
     <string name="test_account_type1">com.android.server.accounts.account_manager_service_test.account.type1</string>
     <string name="test_account_type2">com.android.server.accounts.account_manager_service_test.account.type2</string>
+
+    <string name="config_batterySaverDeviceSpecificConfig_1"></string>
+    <string name="config_batterySaverDeviceSpecificConfig_2">file-off:/sys/a=1,file-off:/sys/b=2</string>
+    <string name="config_batterySaverDeviceSpecificConfig_3">file-off:/sys/a=3,file-on:/proc/c=4,/abc=3</string>
 </resources>
diff --git a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
index 50ac41c..5b6225e7 100644
--- a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
@@ -18,8 +18,13 @@
 import android.os.PowerManager.ServiceType;
 import android.os.PowerSaveState;
 import android.os.Handler;
+import android.provider.Settings;
+import android.provider.Settings.Global;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.ArrayMap;
+
+import com.android.frameworks.servicestests.R;
 
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -36,7 +41,7 @@
     private static final float DEFAULT_BRIGHTNESS_FACTOR = 0.5f;
     private static final float PRECISION = 0.001f;
     private static final int GPS_MODE = 0;
-    private static final int DEFAULT_GPS_MODE = 1;
+    private static final int DEFAULT_GPS_MODE = 0;
     private static final String BATTERY_SAVER_CONSTANTS = "vibration_disabled=true,"
             + "animation_disabled=false,"
             + "soundtrigger_disabled=true,"
@@ -49,15 +54,34 @@
             + "gps_mode=0";
     private static final String BATTERY_SAVER_INCORRECT_CONSTANTS = "vi*,!=,,true";
 
+    private class BatterySaverPolicyForTest extends BatterySaverPolicy {
+        public BatterySaverPolicyForTest(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        String getGlobalSetting(String key) {
+            return mMockGlobalSettings.get(key);
+        }
+
+        @Override
+        int getDeviceSpecificConfigResId() {
+            return mDeviceSpecificConfigResId;
+        }
+    }
+
     @Mock
     Handler mHandler;
-    private BatterySaverPolicy mBatterySaverPolicy;
+    private BatterySaverPolicyForTest mBatterySaverPolicy;
+
+    private final ArrayMap<String, String> mMockGlobalSettings = new ArrayMap<>();
+    private int mDeviceSpecificConfigResId = R.string.config_batterySaverDeviceSpecificConfig_1;
 
     public void setUp() throws Exception {
         super.setUp();
         MockitoAnnotations.initMocks(this);
-        mBatterySaverPolicy = new BatterySaverPolicy(mHandler);
-        mBatterySaverPolicy.start(getContext().getContentResolver());
+        mBatterySaverPolicy = new BatterySaverPolicyForTest(mHandler);
+        mBatterySaverPolicy.systemReady(getContext());
     }
 
     @SmallTest
@@ -102,7 +126,7 @@
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyDataSaver_DefaultValueCorrect() {
-        mBatterySaverPolicy.updateConstants("");
+        mBatterySaverPolicy.updateConstantsLocked("", "");
         final PowerSaveState batterySaverStateOn =
                 mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.DATA_SAVER, BATTERY_SAVER_ON);
         assertThat(batterySaverStateOn.batterySaverEnabled).isFalse();
@@ -132,7 +156,7 @@
 
     @SmallTest
     public void testUpdateConstants_getCorrectData() {
-        mBatterySaverPolicy.updateConstants(BATTERY_SAVER_CONSTANTS);
+        mBatterySaverPolicy.updateConstantsLocked(BATTERY_SAVER_CONSTANTS, "");
 
         final PowerSaveState vibrationState =
                 mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.VIBRATION, BATTERY_SAVER_ON);
@@ -177,12 +201,12 @@
     @SmallTest
     public void testUpdateConstants_IncorrectData_NotCrash() {
         //Should not crash
-        mBatterySaverPolicy.updateConstants(BATTERY_SAVER_INCORRECT_CONSTANTS);
-        mBatterySaverPolicy.updateConstants(null);
+        mBatterySaverPolicy.updateConstantsLocked(BATTERY_SAVER_INCORRECT_CONSTANTS, "");
+        mBatterySaverPolicy.updateConstantsLocked(null, "");
     }
 
     private void testServiceDefaultValue(@ServiceType int type) {
-        mBatterySaverPolicy.updateConstants("");
+        mBatterySaverPolicy.updateConstantsLocked("", "");
         final PowerSaveState batterySaverStateOn =
                 mBatterySaverPolicy.getBatterySaverPolicy(type, BATTERY_SAVER_ON);
         assertThat(batterySaverStateOn.batterySaverEnabled).isTrue();
@@ -191,4 +215,37 @@
                 mBatterySaverPolicy.getBatterySaverPolicy(type, BATTERY_SAVER_OFF);
         assertThat(batterySaverStateOff.batterySaverEnabled).isFalse();
     }
+
+    public void testDeviceSpecific() {
+        mDeviceSpecificConfigResId = R.string.config_batterySaverDeviceSpecificConfig_1;
+        mMockGlobalSettings.put(Global.BATTERY_SAVER_CONSTANTS, "");
+        mMockGlobalSettings.put(Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS, "");
+
+        mBatterySaverPolicy.onChangeForTest();
+        assertThat(mBatterySaverPolicy.getFileValues(true).toString()).isEqualTo("{}");
+        assertThat(mBatterySaverPolicy.getFileValues(false).toString()).isEqualTo("{}");
+
+
+        mDeviceSpecificConfigResId = R.string.config_batterySaverDeviceSpecificConfig_2;
+
+        mBatterySaverPolicy.onChangeForTest();
+        assertThat(mBatterySaverPolicy.getFileValues(true).toString()).isEqualTo("{}");
+        assertThat(mBatterySaverPolicy.getFileValues(false).toString())
+                .isEqualTo("{/sys/a=1, /sys/b=2}");
+
+
+        mDeviceSpecificConfigResId = R.string.config_batterySaverDeviceSpecificConfig_3;
+
+        mBatterySaverPolicy.onChangeForTest();
+        assertThat(mBatterySaverPolicy.getFileValues(true).toString()).isEqualTo("{/proc/c=4}");
+        assertThat(mBatterySaverPolicy.getFileValues(false).toString()).isEqualTo("{/sys/a=3}");
+
+
+        mMockGlobalSettings.put(Global.BATTERY_SAVER_DEVICE_SPECIFIC_CONSTANTS,
+                "file-on:/proc/z=4");
+
+        mBatterySaverPolicy.onChangeForTest();
+        assertThat(mBatterySaverPolicy.getFileValues(true).toString()).isEqualTo("{/proc/z=4}");
+        assertThat(mBatterySaverPolicy.getFileValues(false).toString()).isEqualTo("{}");
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index b60d5bf..5039e42 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -16,32 +16,28 @@
 
 package com.android.server.power;
 
-import android.content.Context;
+import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
+import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.os.PowerManager;
 import android.os.PowerSaveState;
 import android.os.SystemProperties;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.text.TextUtils;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
+
+import com.android.server.power.batterysaver.BatterySaverController;
+
 import org.junit.Rule;
-import org.junit.rules.TemporaryFolder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
-import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
-import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
-import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.when;
-
 /**
  * Tests for {@link com.android.server.power.PowerManagerService}
  */