diff --git a/res/xml/dream_fragment_overview.xml b/res/xml/dream_fragment_overview.xml index db8f4fdd2a6..3321fd1dda1 100644 --- a/res/xml/dream_fragment_overview.xml +++ b/res/xml/dream_fragment_overview.xml @@ -37,8 +37,7 @@ + android:layout="@layout/dream_picker_layout"/> mCallbacks = new HashSet<>(); + + public DreamPickerController(Context context) { + this(context, DreamBackend.getInstance(context)); } - public DreamPickerController(Context context, String key, DreamBackend backend) { - super(context, key); + public DreamPickerController(Context context, DreamBackend backend) { + super(context, PREF_KEY); mBackend = backend; mDreamInfos = mBackend.getDreamInfos(); mActiveDream = getActiveDreamInfo(mDreamInfos); @@ -96,6 +100,11 @@ public class DreamPickerController extends BasePreferenceController { } } + @Nullable + public DreamInfo getActiveDreamInfo() { + return mActiveDream; + } + @Nullable private static DreamInfo getActiveDreamInfo(List dreamInfos) { return dreamInfos @@ -105,6 +114,19 @@ public class DreamPickerController extends BasePreferenceController { .orElse(null); } + void addCallback(Callback callback) { + mCallbacks.add(callback); + } + + void removeCallback(Callback callback) { + mCallbacks.remove(callback); + } + + interface Callback { + // Triggered when the selected dream changes. + void onActiveDreamChanged(); + } + private class DreamItem implements IDreamItem { DreamInfo mDreamInfo; @@ -131,6 +153,7 @@ public class DreamPickerController extends BasePreferenceController { public void onItemClicked() { mActiveDream = mDreamInfo; mBackend.setActiveDream(mDreamInfo.componentName); + mCallbacks.forEach(Callback::onActiveDreamChanged); mMetricsFeatureProvider.action(SettingsEnums.PAGE_UNKNOWN, SettingsEnums.ACTION_DREAM_SELECT_TYPE, SettingsEnums.DREAM, mDreamInfo.componentName.flattenToString(), 1); diff --git a/src/com/android/settings/dream/DreamSettings.java b/src/com/android/settings/dream/DreamSettings.java index acc69731d0d..622f57a434d 100644 --- a/src/com/android/settings/dream/DreamSettings.java +++ b/src/com/android/settings/dream/DreamSettings.java @@ -59,8 +59,14 @@ public class DreamSettings extends DashboardFragment implements OnMainSwitchChan private MainSwitchPreference mMainSwitchPreference; private Button mPreviewButton; + private Preference mComplicationsTogglePreference; private RecyclerView mRecyclerView; + private DreamPickerController mDreamPickerController; + + private final DreamPickerController.Callback mCallback = + this::updateComplicationsToggleVisibility; + @WhenToDream static int getSettingFromPrefKey(String key) { switch (key) { @@ -128,7 +134,13 @@ public class DreamSettings extends DashboardFragment implements OnMainSwitchChan @Override protected List createPreferenceControllers(Context context) { - return buildPreferenceControllers(context); + final List controllers = new ArrayList<>(); + if (mDreamPickerController == null) { + mDreamPickerController = new DreamPickerController(context); + } + controllers.add(mDreamPickerController); + controllers.add(new WhenToDreamPreferenceController(context)); + return controllers; } public static CharSequence getSummaryTextWithDreamName(Context context) { @@ -146,10 +158,9 @@ public class DreamSettings extends DashboardFragment implements OnMainSwitchChan } } - private static List buildPreferenceControllers(Context context) { - final List controllers = new ArrayList<>(); - controllers.add(new WhenToDreamPreferenceController(context)); - return controllers; + @VisibleForTesting + void setDreamPickerController(DreamPickerController dreamPickerController) { + mDreamPickerController = dreamPickerController; } private void setAllPreferencesEnabled(boolean isEnabled) { @@ -174,12 +185,29 @@ public class DreamSettings extends DashboardFragment implements OnMainSwitchChan final DreamBackend dreamBackend = DreamBackend.getInstance(getContext()); + mComplicationsTogglePreference = findPreference( + DreamComplicationPreferenceController.PREF_KEY); + updateComplicationsToggleVisibility(); + mMainSwitchPreference = findPreference(MAIN_SWITCH_PREF_KEY); if (mMainSwitchPreference != null) { mMainSwitchPreference.addOnSwitchChangeListener(this); } setAllPreferencesEnabled(dreamBackend.isEnabled()); + + if (mDreamPickerController != null) { + mDreamPickerController.addCallback(mCallback); + } + } + + @Override + public void onDestroy() { + if (mDreamPickerController != null) { + mDreamPickerController.removeCallback(mCallback); + } + + super.onDestroy(); } @Override @@ -199,6 +227,16 @@ public class DreamSettings extends DashboardFragment implements OnMainSwitchChan return mRecyclerView; } + private void updateComplicationsToggleVisibility() { + if (mDreamPickerController == null || mComplicationsTogglePreference == null) { + return; + } + + final DreamBackend.DreamInfo activeDream = mDreamPickerController.getActiveDreamInfo(); + mComplicationsTogglePreference.setVisible( + activeDream != null && activeDream.supportsComplications); + } + private void updatePaddingForPreviewButton() { mPreviewButton.post(() -> { mRecyclerView.setPadding(0, 0, 0, mPreviewButton.getMeasuredHeight()); diff --git a/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java b/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java index 7a5299f35e3..401ffe0700f 100644 --- a/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java +++ b/tests/robotests/src/com/android/settings/dream/DreamPickerControllerTest.java @@ -62,8 +62,7 @@ public class DreamPickerControllerTest { } private DreamPickerController buildController() { - final DreamPickerController controller = new DreamPickerController(mContext, "key", - mBackend); + final DreamPickerController controller = new DreamPickerController(mContext, mBackend); controller.displayPreference(mScreen); return controller; } diff --git a/tests/robotests/src/com/android/settings/dream/DreamSettingsTest.java b/tests/robotests/src/com/android/settings/dream/DreamSettingsTest.java index 4fceb17e372..56dacddd614 100644 --- a/tests/robotests/src/com/android/settings/dream/DreamSettingsTest.java +++ b/tests/robotests/src/com/android/settings/dream/DreamSettingsTest.java @@ -21,21 +21,36 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.os.Bundle; + +import androidx.preference.Preference; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; +import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; +import com.android.settings.testutils.shadow.ShadowFragment; import com.android.settingslib.dream.DreamBackend; import com.android.settingslib.dream.DreamBackend.WhenToDream; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +@Config(shadows = ShadowFragment.class) @RunWith(RobolectricTestRunner.class) public class DreamSettingsTest { @@ -46,7 +61,8 @@ public class DreamSettingsTest { DreamSettings.NEVER_DREAM ); - private static final @WhenToDream int[] SETTINGS = { + @WhenToDream + private static final int[] SETTINGS = { DreamBackend.WHILE_CHARGING, DreamBackend.WHILE_DOCKED, DreamBackend.EITHER, @@ -67,6 +83,15 @@ public class DreamSettingsTest { R.string.screensaver_settings_summary_never }; + @Mock + private Preference mDreamPickerPref; + @Mock + private Preference mComplicationsTogglePref; + @Mock + private DreamPickerController mDreamPickerController; + @Captor + private ArgumentCaptor mDreamPickerCallbackCaptor; + @Test public void getSettingFromPrefKey() { for (int i = 0; i < KEYS.size(); i++) { @@ -130,4 +155,144 @@ public class DreamSettingsTest { assertThat(DreamSettings.getSummaryTextFromBackend(mockBackend, mockContext)).isEqualTo( fakeName + " test dream is on"); } + + @Test + public void complicationsToggle_addAndRemoveActiveDreamChangeCallback() { + MockitoAnnotations.initMocks(this); + + final Context context = ApplicationProvider.getApplicationContext(); + final DreamSettings dreamSettings = prepareDreamSettings(context); + + dreamSettings.onAttach(context); + dreamSettings.onCreate(Bundle.EMPTY); + verify(mDreamPickerController).addCallback(mDreamPickerCallbackCaptor.capture()); + + dreamSettings.onDestroy(); + verify(mDreamPickerController).removeCallback(mDreamPickerCallbackCaptor.getValue()); + } + + @Test + public void complicationsToggle_showWhenDreamSupportsComplications() { + MockitoAnnotations.initMocks(this); + + final Context context = ApplicationProvider.getApplicationContext(); + final DreamSettings dreamSettings = prepareDreamSettings(context); + + // Active dream supports complications + final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); + activeDream.supportsComplications = true; + when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); + + dreamSettings.onAttach(context); + dreamSettings.onCreate(Bundle.EMPTY); + + // Verify dream complications toggle is visible + verify(mComplicationsTogglePref).setVisible(true); + } + + @Test + public void complicationsToggle_hideWhenDreamDoesNotSupportComplications() { + MockitoAnnotations.initMocks(this); + + final Context context = ApplicationProvider.getApplicationContext(); + final DreamSettings dreamSettings = prepareDreamSettings(context); + + // Active dream does not support complications + final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); + activeDream.supportsComplications = false; + when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); + + dreamSettings.onAttach(context); + dreamSettings.onCreate(Bundle.EMPTY); + + // Verify dream complications toggle is hidden + verify(mComplicationsTogglePref).setVisible(false); + } + + @Test + public void complicationsToggle_showWhenSwitchToDreamSupportsComplications() { + MockitoAnnotations.initMocks(this); + + final Context context = ApplicationProvider.getApplicationContext(); + final DreamSettings dreamSettings = prepareDreamSettings(context); + + // Active dream does not support complications + final DreamBackend.DreamInfo activeDream = new DreamBackend.DreamInfo(); + activeDream.supportsComplications = false; + when(mDreamPickerController.getActiveDreamInfo()).thenReturn(activeDream); + + dreamSettings.onAttach(context); + dreamSettings.onCreate(Bundle.EMPTY); + + // Verify dream complications toggle is hidden + verify(mComplicationsTogglePref).setVisible(false); + verify(mDreamPickerController).addCallback(mDreamPickerCallbackCaptor.capture()); + + // Active dream changes to one that supports complications + activeDream.supportsComplications = true; + mDreamPickerCallbackCaptor.getValue().onActiveDreamChanged(); + + // Verify dream complications toggle is shown + verify(mComplicationsTogglePref).setVisible(true); + } + + private DreamSettings prepareDreamSettings(Context context) { + final TestDreamSettings dreamSettings = new TestDreamSettings(context); + when(mDreamPickerController.getPreferenceKey()).thenReturn(DreamPickerController.PREF_KEY); + when(mDreamPickerPref.getExtras()).thenReturn(new Bundle()); + when(mDreamPickerPref.getKey()).thenReturn(DreamPickerController.PREF_KEY); + when(mComplicationsTogglePref.getKey()).thenReturn( + DreamComplicationPreferenceController.PREF_KEY); + + dreamSettings.addPreference(DreamPickerController.PREF_KEY, mDreamPickerPref); + dreamSettings.addPreference(DreamComplicationPreferenceController.PREF_KEY, + mComplicationsTogglePref); + dreamSettings.setDreamPickerController(mDreamPickerController); + + return dreamSettings; + } + + private static class TestDreamSettings extends DreamSettings { + + private final Context mContext; + private final PreferenceManager mPreferenceManager; + + private final HashMap mPreferences = new HashMap<>(); + + TestDreamSettings(Context context) { + super(); + mContext = context; + mPreferenceManager = new PreferenceManager(context); + mPreferenceManager.setPreferences(mPreferenceManager.createPreferenceScreen(context)); + } + + @Override + public int getPreferenceScreenResId() { + return R.xml.placeholder_prefs; + } + + @Override + public PreferenceScreen getPreferenceScreen() { + return mPreferenceManager.getPreferenceScreen(); + } + + @Override + public PreferenceManager getPreferenceManager() { + return mPreferenceManager; + } + + @Override + public Context getContext() { + return mContext; + } + + @Override + public T findPreference(CharSequence key) { + return (T) mPreferences.get(key); + } + + void addPreference(String key, Preference preference) { + mPreferences.put(key, preference); + } + } }