OSDN Git Service

Update dark theme to have new screen
authorSalvador Martinez <dehboxturtle@google.com>
Wed, 20 Mar 2019 17:52:52 +0000 (10:52 -0700)
committerSalvador Martinez <dehboxturtle@google.com>
Tue, 26 Mar 2019 20:17:11 +0000 (13:17 -0700)
The dark theme preference should have it's own screen rather than
being a dialog. This adds some boilerplate code that will be
needed for the illustration as well as converting the current
list preference to open a new screen.

Test: robotests
Bug: 128686189
Change-Id: I5b62276353c0d39ad2ad00d21d2280e76cceb09b

res/xml/dark_ui_settings.xml [new file with mode: 0644]
res/xml/display_settings.xml
src/com/android/settings/display/DarkUIPreferenceController.java
src/com/android/settings/display/DarkUISettings.java [new file with mode: 0644]
src/com/android/settings/display/DarkUISettingsRadioButtonsController.java [new file with mode: 0644]
src/com/android/settings/widget/RadioButtonPickerFragment.java
src/com/android/settings/widget/VideoPreference.java
tests/robotests/src/com/android/settings/display/DarkUIPreferenceControllerTest.java [deleted file]
tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/widget/VideoPreferenceTest.java

diff --git a/res/xml/dark_ui_settings.xml b/res/xml/dark_ui_settings.xml
new file mode 100644 (file)
index 0000000..1f11eba
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2019 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.
+  -->
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res-auto"
+    android:title="@string/dark_ui_mode"
+    android:key="dark_ui_mode_screen"
+    settings:staticPreferenceLocation="append"
+    settings:keywords="@string/keywords_dark_ui_mode">
+</PreferenceScreen >
index 91fe656..9e84793 100644 (file)
             android:targetClass="@string/config_wallpaper_picker_class" />
     </com.android.settingslib.RestrictedPreference>
 
-    <ListPreference
+
+    <Preference
         android:key="dark_ui_mode"
+        android:fragment="com.android.settings.display.DarkUISettings"
         android:title="@string/dark_ui_mode"
-        android:dialogTitle="@string/dark_ui_mode_title"
-        android:entries="@array/dark_ui_mode_entries"
-        android:entryValues="@array/dark_ui_mode_values"
-        settings:keywords="@string/keywords_dark_ui_mode"
-        settings:controller="com.android.settings.display.DarkUIPreferenceController" />
+        settings:searchable="false"
+        settings:controller="com.android.settings.display.DarkUIPreferenceController"/>
 
     <!-- Cross-listed item, if you change this, also change it in power_usage_summary.xml -->
     <com.android.settings.display.TimeoutListPreference
index 21af603..7d8fd56 100644 (file)
@@ -27,8 +27,7 @@ import androidx.preference.PreferenceScreen;
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
 
-public class DarkUIPreferenceController extends BasePreferenceController
-        implements Preference.OnPreferenceChangeListener {
+public class DarkUIPreferenceController extends BasePreferenceController {
 
     private UiModeManager mUiModeManager;
 
@@ -48,58 +47,8 @@ public class DarkUIPreferenceController extends BasePreferenceController
     }
 
     @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        int value = mUiModeManager.getNightMode();
-        ListPreference preference = screen.findPreference(getPreferenceKey());
-        preference.setValue(modeToString(value));
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        mUiModeManager.setNightMode(modeToInt((String) newValue));
-        refreshSummary(preference);
-        return true;
-    }
-
-    @Override
     public CharSequence getSummary() {
-        return modeToDescription(mUiModeManager.getNightMode());
-    }
-
-    private String modeToDescription(int mode) {
-        String[] values = mContext.getResources().getStringArray(R.array.dark_ui_mode_entries);
-        switch (mode) {
-            case UiModeManager.MODE_NIGHT_YES:
-                return values[0];
-            case UiModeManager.MODE_NIGHT_NO:
-            case UiModeManager.MODE_NIGHT_AUTO:
-            default:
-                return values[1];
-
-        }
-    }
-
-    private String modeToString(int mode) {
-        switch (mode) {
-            case UiModeManager.MODE_NIGHT_YES:
-                return "yes";
-            case UiModeManager.MODE_NIGHT_NO:
-            case UiModeManager.MODE_NIGHT_AUTO:
-            default:
-                return "no";
-
-        }
-    }
-
-    private int modeToInt(String mode) {
-        switch (mode) {
-            case "yes":
-                return UiModeManager.MODE_NIGHT_YES;
-            case "no":
-            case "auto":
-            default:
-                return UiModeManager.MODE_NIGHT_NO;
-        }
+        return DarkUISettingsRadioButtonsController.modeToDescription(
+                mContext, mUiModeManager.getNightMode());
     }
 }
diff --git a/src/com/android/settings/display/DarkUISettings.java b/src/com/android/settings/display/DarkUISettings.java
new file mode 100644 (file)
index 0000000..50fd386
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2019 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.settings.display;
+
+import android.app.UiModeManager;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.provider.SearchIndexableResource;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settings.widget.RadioButtonPickerFragment;
+import com.android.settingslib.search.SearchIndexable;
+import com.android.settingslib.widget.CandidateInfo;
+import com.android.settingslib.widget.FooterPreference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The screen for selecting the dark theme preference for this device. Automatically updates
+ * the associated footer view with any needed information.
+ */
+@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
+public class DarkUISettings extends RadioButtonPickerFragment implements Indexable {
+
+  private DarkUISettingsRadioButtonsController mController;
+  private Preference mFooter;
+
+  @Override
+  protected int getPreferenceScreenResId() {
+      return R.xml.dark_ui_settings;
+  }
+
+  @Override
+  public void onAttach(Context context) {
+      super.onAttach(context);
+      // TODO(b/128686189): add illustration once it is ready
+      setIllustration(0, 0);
+      mFooter = new FooterPreference(context);
+      mFooter.setIcon(android.R.color.transparent);
+      mController = new DarkUISettingsRadioButtonsController(context, mFooter);
+  }
+
+  @Override
+  protected List<? extends CandidateInfo> getCandidates() {
+      final Context context = getContext();
+      final List<CandidateInfo> candidates = new ArrayList<>();
+      candidates.add(new DarkUISettingsCandidateInfo(
+              DarkUISettingsRadioButtonsController.modeToDescription(
+                      context, UiModeManager.MODE_NIGHT_YES),
+              /* summary */ null,
+              DarkUISettingsRadioButtonsController.KEY_DARK,
+              /* enabled */ true));
+      candidates.add(new DarkUISettingsCandidateInfo(
+              DarkUISettingsRadioButtonsController.modeToDescription(
+                      context, UiModeManager.MODE_NIGHT_NO),
+              /* summary */ null,
+              DarkUISettingsRadioButtonsController.KEY_LIGHT,
+              /* enabled */ true));
+      return candidates;
+  }
+
+  @Override
+  protected void addStaticPreferences(PreferenceScreen screen) {
+      screen.addPreference(mFooter);
+  }
+
+  @Override
+  protected String getDefaultKey() {
+      return mController.getDefaultKey();
+  }
+
+  @Override
+  protected boolean setDefaultKey(String key) {
+      return mController.setDefaultKey(key);
+  }
+
+  @Override
+  public int getMetricsCategory() {
+      return SettingsEnums.DARK_UI_SETTINGS;
+  }
+
+  static class DarkUISettingsCandidateInfo extends CandidateInfo {
+
+      private final CharSequence mLabel;
+      private final CharSequence mSummary;
+      private final String mKey;
+
+      DarkUISettingsCandidateInfo(CharSequence label, CharSequence summary, String key,
+              boolean enabled) {
+          super(enabled);
+          mLabel = label;
+          mKey = key;
+          mSummary = summary;
+      }
+
+      @Override
+      public CharSequence loadLabel() {
+          return mLabel;
+      }
+
+      @Override
+      public Drawable loadIcon() {
+          return null;
+      }
+
+      @Override
+      public String getKey() {
+          return mKey;
+      }
+
+      public CharSequence getSummary() {
+          return mSummary;
+      }
+  }
+
+  public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+      new BaseSearchIndexProvider() {
+        @Override
+        public List<SearchIndexableResource> getXmlResourcesToIndex(
+            Context context, boolean enabled) {
+          final SearchIndexableResource sir = new SearchIndexableResource(context);
+          sir.xmlResId = R.xml.dark_ui_settings;
+          return Arrays.asList(sir);
+        }
+      };
+}
diff --git a/src/com/android/settings/display/DarkUISettingsRadioButtonsController.java b/src/com/android/settings/display/DarkUISettingsRadioButtonsController.java
new file mode 100644 (file)
index 0000000..0fca306
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 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.settings.display;
+
+import android.app.UiModeManager;
+import android.content.Context;
+import androidx.preference.Preference;
+import com.android.settings.R;
+import androidx.annotation.VisibleForTesting;
+
+public class DarkUISettingsRadioButtonsController {
+
+    public static final String KEY_DARK = "key_dark_ui_settings_dark";
+    public static final String KEY_LIGHT = "key_dark_ui_settings_light";
+
+    @VisibleForTesting
+    UiModeManager mManager;
+
+    private Preference mFooter;
+
+    public DarkUISettingsRadioButtonsController(Context context, Preference footer) {
+        mManager = context.getSystemService(UiModeManager.class);
+        mFooter = footer;
+    }
+
+    public String getDefaultKey() {
+        final int mode = mManager.getNightMode();
+        updateFooter();
+        return mode == UiModeManager.MODE_NIGHT_YES ? KEY_DARK : KEY_LIGHT;
+    }
+
+    public boolean setDefaultKey(String key) {
+        switch(key) {
+            case KEY_DARK:
+                mManager.setNightMode(UiModeManager.MODE_NIGHT_YES);
+                break;
+            case KEY_LIGHT:
+                mManager.setNightMode(UiModeManager.MODE_NIGHT_NO);
+                break;
+            default:
+                throw new IllegalStateException(
+                        "Not a valid key for " + this.getClass().getSimpleName() + ": " + key);
+        }
+        updateFooter();
+        return true;
+    }
+
+    public void updateFooter() {
+        final int mode = mManager.getNightMode();
+        switch (mode) {
+            case UiModeManager.MODE_NIGHT_YES:
+                mFooter.setSummary(R.string.dark_ui_settings_dark_summary);
+                break;
+            case UiModeManager.MODE_NIGHT_NO:
+            case UiModeManager.MODE_NIGHT_AUTO:
+            default:
+                mFooter.setSummary(R.string.dark_ui_settings_light_summary);
+        }
+    }
+
+    public static String modeToDescription(Context context, int mode) {
+        final String[] values = context.getResources().getStringArray(R.array.dark_ui_mode_entries);
+        switch (mode) {
+            case UiModeManager.MODE_NIGHT_YES:
+                return values[0];
+            case UiModeManager.MODE_NIGHT_NO:
+            case UiModeManager.MODE_NIGHT_AUTO:
+            default:
+                return values[1];
+        }
+    }
+}
index 591cd21..8861c94 100644 (file)
@@ -58,6 +58,9 @@ public abstract class RadioButtonPickerFragment extends InstrumentedPreferenceFr
 
     protected UserManager mUserManager;
     protected int mUserId;
+    private int mIllustrationId;
+    private int mIllustrationPreviewId;
+    private VideoPreference mVideoPreference;
 
     @Override
     public void onAttach(Context context) {
@@ -164,6 +167,9 @@ public abstract class RadioButtonPickerFragment extends InstrumentedPreferenceFr
         final String systemDefaultKey = getSystemDefaultKey();
         final PreferenceScreen screen = getPreferenceScreen();
         screen.removeAll();
+        if (mIllustrationId != 0) {
+            addIllustration(screen);
+        }
         if (!mAppendStaticPreferences) {
             addStaticPreferences(screen);
         }
@@ -241,6 +247,23 @@ public abstract class RadioButtonPickerFragment extends InstrumentedPreferenceFr
         }
     }
 
+    /**
+     * Allows you to set an illustration at the top of this screen. Set the illustration id to 0
+     * if you want to remove the illustration.
+     * @param illustrationId The res id for the raw of the illustration.
+     * @param previewId The res id for the drawable of the illustration
+     */
+    protected void setIllustration(int illustrationId, int previewId) {
+        mIllustrationId = illustrationId;
+        mIllustrationPreviewId = previewId;
+    }
+
+    private void addIllustration(PreferenceScreen screen) {
+        mVideoPreference = new VideoPreference(getContext());
+        mVideoPreference.setVideo(mIllustrationId, mIllustrationPreviewId);
+        screen.addPreference(mVideoPreference);
+    }
+
     protected abstract List<? extends CandidateInfo> getCandidates();
 
     protected abstract String getDefaultKey();
index fd215d8..2d88673 100644 (file)
@@ -55,22 +55,41 @@ public class VideoPreference extends Preference {
     private int mPreviewResource;
     private boolean mViewVisible;
     private Surface mSurface;
+    private int mAnimationId;
+
+    public VideoPreference(Context context) {
+        super(context);
+        mContext = context;
+        initialize(context, null);
+    }
 
     public VideoPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
         mContext = context;
+        initialize(context, attrs);
+    }
+
+    private void initialize(Context context, AttributeSet attrs) {
         TypedArray attributes = context.getTheme().obtainStyledAttributes(
                 attrs,
-                com.android.settings.R.styleable.VideoPreference,
+                R.styleable.VideoPreference,
                 0, 0);
         try {
-            int animation = attributes.getResourceId(R.styleable.VideoPreference_animation, 0);
+            // if these are already set that means they were set dynamically and don't need
+            // to be loaded from xml
+            mAnimationId = mAnimationId == 0
+                ? attributes.getResourceId(R.styleable.VideoPreference_animation, 0)
+                : mAnimationId;
             mVideoPath = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
                     .authority(context.getPackageName())
-                    .appendPath(String.valueOf(animation))
+                    .appendPath(String.valueOf(mAnimationId))
                     .build();
-            mPreviewResource = attributes.getResourceId(
-                    R.styleable.VideoPreference_preview, 0);
+            mPreviewResource = mPreviewResource == 0
+                ? attributes.getResourceId(R.styleable.VideoPreference_preview, 0)
+                : mPreviewResource;
+            if (mPreviewResource == 0 && mAnimationId == 0) {
+                return;
+            }
             initMediaPlayer();
             if (mMediaPlayer != null && mMediaPlayer.getDuration() > 0) {
                 setVisible(true);
@@ -103,20 +122,9 @@ public class VideoPreference extends Preference {
 
         imageView.setImageResource(mPreviewResource);
         layout.setAspectRatio(mAspectRadio);
+        updateViewStates(imageView, playButton);
 
-        video.setOnClickListener(v -> {
-            if (mMediaPlayer != null) {
-                if (mMediaPlayer.isPlaying()) {
-                    mMediaPlayer.pause();
-                    playButton.setVisibility(View.VISIBLE);
-                    mVideoPaused = true;
-                } else {
-                    mMediaPlayer.start();
-                    playButton.setVisibility(View.GONE);
-                    mVideoPaused = false;
-                }
-            }
-        });
+        video.setOnClickListener(v -> updateViewStates(imageView, playButton));
 
         video.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
             @Override
@@ -161,6 +169,23 @@ public class VideoPreference extends Preference {
         });
     }
 
+    @VisibleForTesting
+    void updateViewStates(ImageView imageView, ImageView playButton) {
+        if (mMediaPlayer != null) {
+            if (mMediaPlayer.isPlaying()) {
+                mMediaPlayer.pause();
+                playButton.setVisibility(View.VISIBLE);
+                imageView.setVisibility(View.VISIBLE);
+                mVideoPaused = true;
+            } else {
+                imageView.setVisibility(View.GONE);
+                playButton.setVisibility(View.GONE);
+                mMediaPlayer.start();
+                mVideoPaused = false;
+            }
+        }
+    }
+
     @Override
     public void onDetached() {
         releaseMediaPlayer();
@@ -178,6 +203,20 @@ public class VideoPreference extends Preference {
         releaseMediaPlayer();
     }
 
+    /**
+     * Sets the video for this preference. If a previous video was set this one will override it
+     * and properly release any resources and re-initialize the preference to play the new video.
+     *
+     * @param videoId The raw res id of the video
+     * @param previewId The drawable res id of the preview image to use if the video fails to load.
+     */
+    public void setVideo(int videoId, int previewId) {
+        mAnimationId = videoId;
+        mPreviewResource = previewId;
+        releaseMediaPlayer();
+        initialize(mContext, null);
+    }
+
     private void initMediaPlayer() {
         if (mMediaPlayer == null) {
             mMediaPlayer = MediaPlayer.create(mContext, mVideoPath);
diff --git a/tests/robotests/src/com/android/settings/display/DarkUIPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/DarkUIPreferenceControllerTest.java
deleted file mode 100644 (file)
index c8f847b..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2018 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.settings.display;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.UiModeManager;
-import android.content.Context;
-
-import androidx.preference.ListPreference;
-import androidx.preference.PreferenceScreen;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class DarkUIPreferenceControllerTest {
-
-    private Context mContext;
-    @Mock
-    private ListPreference mPreference;
-    @Mock
-    private PreferenceScreen mPreferenceScreen;
-    @Mock
-    private UiModeManager mUiModeManager;
-    private DarkUIPreferenceController mController;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mController = new DarkUIPreferenceController(mContext, "dark_ui_mode");
-        mController.setUiModeManager(mUiModeManager);
-        when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
-            .thenReturn(mPreference);
-        mController.displayPreference(mPreferenceScreen);
-    }
-
-    @Test
-    public void onPreferenceChanged_setAuto() {
-        // Auto was deprecated, it should default to NO.
-        mController.onPreferenceChange(mPreference, "auto");
-        verify(mUiModeManager).setNightMode(eq(UiModeManager.MODE_NIGHT_NO));
-    }
-
-    @Test
-    public void onPreferenceChanged_setNightMode() {
-        mController.onPreferenceChange(mPreference, "yes");
-        verify(mUiModeManager).setNightMode(eq(UiModeManager.MODE_NIGHT_YES));
-    }
-
-    @Test
-    public void onPreferenceChanged_setDayMode() {
-        mController.onPreferenceChange(mPreference, "no");
-        verify(mUiModeManager).setNightMode(eq(UiModeManager.MODE_NIGHT_NO));
-    }
-
-    public int getCurrentMode() {
-        final UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class);
-        return uiModeManager.getNightMode();
-    }
-}
diff --git a/tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java b/tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java
new file mode 100644 (file)
index 0000000..76142a4
--- /dev/null
@@ -0,0 +1,52 @@
+package com.android.settings.display;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+
+import android.app.UiModeManager;
+import android.content.Context;
+import androidx.preference.Preference;
+import com.android.settings.R;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class DarkUISettingsRadioButtonsControllerTest {
+
+    @Mock
+    private UiModeManager mUiModeManager;
+    @Mock
+    private Preference mFooter;
+    private Context mContext;
+    private DarkUISettingsRadioButtonsController mController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = new DarkUISettingsRadioButtonsController(mContext, mFooter);
+        mController.mManager = mUiModeManager;
+    }
+
+    @Test
+    public void footerUpdatesCorrectly() {
+        doReturn(UiModeManager.MODE_NIGHT_YES).when(mUiModeManager).getNightMode();
+        mController.updateFooter();
+        verify(mFooter).setSummary(eq(R.string.dark_ui_settings_dark_summary));
+
+        doReturn(UiModeManager.MODE_NIGHT_NO).when(mUiModeManager).getNightMode();
+        mController.updateFooter();
+        verify(mFooter).setSummary(eq(R.string.dark_ui_settings_light_summary));
+    }
+
+    public int getCurrentMode() {
+        final UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class);
+        return uiModeManager.getNightMode();
+    }
+}
index 4cd6be4..b53f364 100644 (file)
@@ -18,6 +18,10 @@ package com.android.settings.widget;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -29,6 +33,8 @@ import android.media.MediaPlayer;
 import android.view.LayoutInflater;
 import android.view.TextureView;
 
+import android.view.View;
+import android.widget.ImageView;
 import androidx.preference.PreferenceViewHolder;
 
 import com.android.settings.R;
@@ -45,8 +51,13 @@ import org.robolectric.RuntimeEnvironment;
 public class VideoPreferenceTest {
     private static final int VIDEO_WIDTH = 100;
     private static final int VIDEO_HEIGHT = 150;
+
     @Mock
     private MediaPlayer mMediaPlayer;
+    @Mock
+    private ImageView fakePreview;
+    @Mock
+    private ImageView fakePlayButton;
     private Context mContext;
     private VideoPreference mVideoPreference;
     private PreferenceViewHolder mPreferenceViewHolder;
@@ -83,8 +94,8 @@ public class VideoPreferenceTest {
             (TextureView) mPreferenceViewHolder.findViewById(R.id.video_texture_view);
         mVideoPreference.mAnimationAvailable = true;
         mVideoPreference.mVideoReady = true;
-        mVideoPreference.onBindViewHolder(mPreferenceViewHolder);
         mVideoPreference.onViewInvisible();
+        mVideoPreference.onBindViewHolder(mPreferenceViewHolder);
         when(mMediaPlayer.isPlaying()).thenReturn(false);
         final TextureView.SurfaceTextureListener listener = video.getSurfaceTextureListener();
 
@@ -101,4 +112,30 @@ public class VideoPreferenceTest {
 
         verify(mMediaPlayer).release();
     }
+
+    @Test
+    public void updateViewStates_paused_updatesViews() {
+        when(mMediaPlayer.isPlaying()).thenReturn(true);
+        mVideoPreference.updateViewStates(fakePreview, fakePlayButton);
+        verify(fakePlayButton).setVisibility(eq(View.VISIBLE));
+        verify(fakePreview).setVisibility(eq(View.VISIBLE));
+        verify(mMediaPlayer).pause();
+    }
+
+    @Test
+    public void updateViewStates_playing_updatesViews() {
+        when(mMediaPlayer.isPlaying()).thenReturn(false);
+        mVideoPreference.updateViewStates(fakePreview, fakePlayButton);
+        verify(fakePlayButton).setVisibility(eq(View.GONE));
+        verify(fakePreview).setVisibility(eq(View.GONE));
+        verify(mMediaPlayer).start();
+    }
+
+    @Test
+    public void updateViewStates_noMediaPlayer_skips() {
+        mVideoPreference.mMediaPlayer = null;
+        mVideoPreference.updateViewStates(fakePreview, fakePlayButton);
+        verify(fakePlayButton, never()).setVisibility(anyInt());
+        verify(fakePreview, never()).setVisibility(anyInt());
+    }
 }