Update battery saver column to PrimarySwitchPreference (1/2)

 - Change battery saver entry column to new design
 Screenshot: https://screenshot.googleplex.com/9a9Gxm3McJVmLkD.png

Bug: 177407113
Test: make RunSettingsRoboTests -j40
Change-Id: I513bc4371518645f4e725df27f2cb978cec284e8
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index a9819fd..6161d79 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -40,7 +40,7 @@
         android:title="@string/summary_placeholder"
         settings:controller="com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController" />
 
-    <Preference
+    <com.android.settings.widget.PrimarySwitchPreference
         android:fragment="com.android.settings.fuelgauge.batterysaver.BatterySaverSettings"
         android:key="battery_saver_summary"
         android:title="@string/battery_saver"
diff --git a/src/com/android/settings/fuelgauge/BatterySaverController.java b/src/com/android/settings/fuelgauge/BatterySaverController.java
index acb5e32..a91f85c 100644
--- a/src/com/android/settings/fuelgauge/BatterySaverController.java
+++ b/src/com/android/settings/fuelgauge/BatterySaverController.java
@@ -15,37 +15,35 @@
  */
 package com.android.settings.fuelgauge;
 
-import android.content.ContentResolver;
 import android.content.Context;
-import android.database.ContentObserver;
-import android.os.Handler;
-import android.os.Looper;
 import android.os.PowerManager;
-import android.provider.Settings;
-import android.provider.Settings.Global;
 
-import androidx.preference.Preference;
+import androidx.annotation.VisibleForTesting;
 import androidx.preference.PreferenceScreen;
 
-import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.TogglePreferenceController;
+import com.android.settings.widget.PrimarySwitchPreference;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
 import com.android.settingslib.fuelgauge.BatterySaverUtils;
 
-public class BatterySaverController extends BasePreferenceController
+/**
+ * Controller to update the battery saver entry preference.
+ */
+public class BatterySaverController extends TogglePreferenceController
         implements LifecycleObserver, OnStart, OnStop, BatterySaverReceiver.BatterySaverListener {
     private static final String KEY_BATTERY_SAVER = "battery_saver_summary";
     private final BatterySaverReceiver mBatteryStateChangeReceiver;
     private final PowerManager mPowerManager;
-    private Preference mBatterySaverPref;
+
+    @VisibleForTesting
+    PrimarySwitchPreference mBatterySaverPref;
 
     public BatterySaverController(Context context) {
         super(context, KEY_BATTERY_SAVER);
 
-        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mPowerManager = mContext.getSystemService(PowerManager.class);
         mBatteryStateChangeReceiver = new BatterySaverReceiver(context);
         mBatteryStateChangeReceiver.setBatterySaverListener(this);
         BatterySaverUtils.revertScheduleToNoneIfNeeded(context);
@@ -69,60 +67,38 @@
 
     @Override
     public void onStart() {
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL)
-                , true, mObserver);
 
         mBatteryStateChangeReceiver.setListening(true);
-        updateSummary();
     }
 
     @Override
     public void onStop() {
-        mContext.getContentResolver().unregisterContentObserver(mObserver);
         mBatteryStateChangeReceiver.setListening(false);
     }
 
     @Override
-    public CharSequence getSummary() {
-        final ContentResolver resolver = mContext.getContentResolver();
-        final boolean isPowerSaveOn = mPowerManager.isPowerSaveMode();
-        final int percent = Settings.Global.getInt(resolver,
-                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
-        final int mode = Settings.Global.getInt(resolver,
-                Global.AUTOMATIC_POWER_SAVE_MODE, PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
-        if (isPowerSaveOn) {
-            return mContext.getString(R.string.battery_saver_on_summary);
-        } else if (mode == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE) {
-            if (percent != 0) {
-                return mContext.getString(R.string.battery_saver_off_scheduled_summary,
-                        Utils.formatPercentage(percent));
-            } else {
-                return mContext.getString(R.string.battery_saver_off_summary);
-            }
-        } else {
-            return mContext.getString(R.string.battery_saver_auto_routine);
-        }
-    }
-
-    private void updateSummary() {
-        mBatterySaverPref.setSummary(getSummary());
-    }
-
-    private final ContentObserver mObserver = new ContentObserver(
-            new Handler(Looper.getMainLooper())) {
-        @Override
-        public void onChange(boolean selfChange) {
-            updateSummary();
-        }
-    };
-
-    @Override
     public void onPowerSaveModeChanged() {
-        updateSummary();
+        final boolean isChecked = isChecked();
+        if (mBatterySaverPref != null && mBatterySaverPref.isChecked() != isChecked) {
+            mBatterySaverPref.setChecked(isChecked);
+        }
     }
 
     @Override
     public void onBatteryChanged(boolean pluggedIn) {
+        if (mBatterySaverPref != null) {
+            mBatterySaverPref.setSwitchEnabled(!pluggedIn);
+        }
+    }
+
+    @Override
+    public boolean isChecked() {
+        return mPowerManager.isPowerSaveMode();
+    }
+
+    @Override
+    public boolean setChecked(boolean stateOn) {
+        return BatterySaverUtils.setPowerSaveMode(mContext, stateOn,
+            false /* needFirstTimeWarning */);
     }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
index db9ffa5..4d2910e 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySaverControllerTest.java
@@ -17,15 +17,20 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.os.PowerManager;
-import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.widget.LinearLayout;
 
-import androidx.preference.Preference;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settings.R;
+import com.android.settings.widget.PrimarySwitchPreference;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -34,64 +39,108 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
-import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
 public class BatterySaverControllerTest {
 
     @Mock
-    private Preference mBatterySaverPref;
-    @Mock
     private PowerManager mPowerManager;
 
     private BatterySaverController mBatterySaverController;
-    private Context mContext;
+    private PrimarySwitchPreference mBatterySaverPref;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        final Context mContext = spy(RuntimeEnvironment.application);
 
-        mContext = RuntimeEnvironment.application;
-        mBatterySaverController = spy(new BatterySaverController(mContext));
-        ReflectionHelpers.setField(mBatterySaverController, "mPowerManager", mPowerManager);
-        ReflectionHelpers.setField(mBatterySaverController, "mBatterySaverPref", mBatterySaverPref);
+        mBatterySaverPref = new PrimarySwitchPreference(mContext);
+        final LayoutInflater inflater = LayoutInflater.from(mContext);
+        final PreferenceViewHolder mHolder =
+                PreferenceViewHolder.createInstanceForTests(inflater.inflate(
+                com.android.settingslib.R.layout.preference_two_target, null));
+        final LinearLayout mWidgetView = mHolder.itemView.findViewById(android.R.id.widget_frame);
+        inflater.inflate(R.layout.restricted_preference_widget_primary_switch, mWidgetView, true);
+        mBatterySaverPref.onBindViewHolder(mHolder);
 
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
+        doReturn(mPowerManager).when(mContext).getSystemService(Context.POWER_SERVICE);
+
+        mBatterySaverController = new BatterySaverController(mContext);
+        mBatterySaverController.mBatterySaverPref = mBatterySaverPref;
     }
 
     @Test
-    public void onPreferenceChange_onStart() {
-        mBatterySaverController.onStart();
-        verify(mBatterySaverPref).setSummary("Off");
+    public void onBatteryChanged_true_switchEnabled() {
+        mBatterySaverController.onBatteryChanged(true);
+
+        assertThat(mBatterySaverPref.getSwitch().isEnabled()).isFalse();
     }
 
     @Test
-    public void onPreferenceChange_onPowerSaveModeChanged() {
-        mBatterySaverController.onPowerSaveModeChanged();
-        verify(mBatterySaverPref).setSummary("Off");
+    public void onBatteryChanged_false_switchDisabled() {
+        mBatterySaverController.onBatteryChanged(false);
+
+        assertThat(mBatterySaverPref.getSwitch().isEnabled()).isTrue();
     }
 
     @Test
-    public void getSummary_batterySaverOn_showSummaryOn() {
+    public void onPowerSaveModeChanged_differentState_updateToIsChecked() {
         when(mPowerManager.isPowerSaveMode()).thenReturn(true);
 
-        assertThat(mBatterySaverController.getSummary()).isEqualTo("On");
+        assertThat(mBatterySaverPref.isChecked()).isFalse();
+
+        mBatterySaverController.onPowerSaveModeChanged();
+
+        assertThat(mBatterySaverPref.isChecked()).isTrue();
     }
 
     @Test
-    public void getSummary_batterySaverOffButScheduled_showSummaryScheduled() {
-        when(mPowerManager.isPowerSaveMode()).thenReturn(false);
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 15);
+    public void onPowerSaveModeChanged_differentState_updateToUnChecked() {
+        mBatterySaverPref.setChecked(true);
 
-        assertThat(mBatterySaverController.getSummary()).isEqualTo("Will turn on at 15%");
+        when(mPowerManager.isPowerSaveMode()).thenReturn(false);
+        assertThat(mBatterySaverPref.isChecked()).isTrue();
+
+        mBatterySaverController.onPowerSaveModeChanged();
+
+        assertThat(mBatterySaverPref.isChecked()).isFalse();
     }
 
     @Test
-    public void getSummary_batterySaverOff_showSummaryOff() {
+    public void onPowerSaveModeChanged_sameState_noUpdate() {
+        when(mPowerManager.isPowerSaveMode()).thenReturn(false);
+        assertThat(mBatterySaverPref.isChecked()).isFalse();
+
+        mBatterySaverController.onPowerSaveModeChanged();
+
+        assertThat(mBatterySaverPref.isChecked()).isFalse();
+    }
+
+    @Test
+    public void setChecked_on_setPowerSaveMode() {
+        mBatterySaverController.setChecked(true);
+
+        verify(mPowerManager).setPowerSaveModeEnabled(true);
+    }
+
+    @Test
+    public void setChecked_off_unsetPowerSaveMode() {
+        mBatterySaverController.setChecked(false);
+
+        verify(mPowerManager).setPowerSaveModeEnabled(false);
+    }
+
+    @Test
+    public void isChecked_on_powerSaveModeOn() {
+        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+
+        assertThat(mBatterySaverController.isChecked()).isTrue();
+    }
+
+    @Test
+    public void isChecked_off_powerSaveModeOff() {
         when(mPowerManager.isPowerSaveMode()).thenReturn(false);
 
-        assertThat(mBatterySaverController.getSummary()).isEqualTo("Off");
+        assertThat(mBatterySaverController.isChecked()).isFalse();
     }
 }