Loading res/values/strings.xml +8 −2 Original line number Diff line number Diff line Loading @@ -5857,10 +5857,16 @@ screen magnification on app transitions</string> <!-- Title for the accessibility preference to power button to end a call. [CHAR LIMIT=35] --> <string name="accessibility_power_button_ends_call_prerefence_title">Power button ends call</string> <!-- Title for the dark theme group category --> <string name="dark_theme_version_category">Mode</string> <!-- Title for the accessibility preference for applying the original dark theme. [CHAR LIMIT=35] --> <string name="accessibility_standard_dark_theme_title">Standard</string> <!-- Summary for the accessibility preference for applying the original dark theme. [CHAR LIMIT=100] --> <string name="accessibility_standard_dark_theme_summary">Applies Dark theme across your device and supported apps</string> <!-- Title for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=35] --> <string name="accessibility_force_invert_title">Make more apps dark</string> <string name="accessibility_expanded_dark_theme_title">Expanded</string> <!-- Summary for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=100] --> <string name="accessibility_force_invert_summary">Expands dark theme to more apps. May not work with all apps.</string> <string name="accessibility_expanded_dark_theme_summary">Automatically applies Dark theme to more apps for improved accessibility</string> <!-- Title for the accessibility preference for disabling animations. [CHAR LIMIT=35] --> <string name="accessibility_disable_animations">Remove animations</string> <!-- Summary for the accessibility preference for disabling animations. [CHAR LIMIT=60] --> res/xml/dark_mode_settings.xml +17 −7 Original line number Diff line number Diff line Loading @@ -36,15 +36,25 @@ settings:controller="com.android.settings.display.TwilightLocationPreferenceController"/> <PreferenceCategory android:key="display_category" android:title="@string/accessibility_screen_option"> android:key="dark_theme_group" android:title="@string/dark_theme_version_category" settings:controller="com.android.settings.accessibility.ForceInvertPreferenceController"> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="standard_dark_theme" android:title="@string/accessibility_standard_dark_theme_title" android:summary="@string/accessibility_standard_dark_theme_summary" settings:searchable="true"/> <SwitchPreferenceCompat android:key="toggle_force_invert" android:summary="@string/accessibility_force_invert_summary" android:title="@string/accessibility_force_invert_title" settings:controller="com.android.settings.accessibility.ToggleForceInvertPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="expanded_dark_theme" android:title="@string/accessibility_expanded_dark_theme_title" android:summary="@string/accessibility_expanded_dark_theme_summary" settings:searchable="true"/> </PreferenceCategory> <PreferenceCategory android:key="display_category" android:title="@string/accessibility_screen_option"> <DropDownPreference android:key="dark_ui_auto_mode" android:title="@string/dark_ui_auto_mode_title" Loading src/com/android/settings/accessibility/ToggleForceInvertPreferenceController.java→src/com/android/settings/accessibility/ForceInvertPreferenceController.java +103 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2025 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. Loading @@ -20,50 +20,84 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import android.content.Context; import android.content.res.Configuration; import android.provider.Settings; import android.view.accessibility.Flags; import androidx.annotation.NonNull; import androidx.preference.Preference; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.widget.SelectorWithWidgetPreference; /** A toggle preference controller for force invert (force dark). */ public class ToggleForceInvertPreferenceController extends TogglePreferenceController { public class ForceInvertPreferenceController extends BasePreferenceController implements SelectorWithWidgetPreference.OnClickListener { public ToggleForceInvertPreferenceController(Context context, String preferenceKey) { @VisibleForTesting static final String STANDARD_DARK_THEME_KEY = "standard_dark_theme"; @VisibleForTesting static final String EXPANDED_DARK_THEME_KEY = "expanded_dark_theme"; @Nullable private SelectorWithWidgetPreference mStandardDarkThemePreference; @Nullable private SelectorWithWidgetPreference mExpandedDarkThemePreference; public ForceInvertPreferenceController( @NonNull Context context, @NonNull String preferenceKey) { super(context, preferenceKey); } @Override public boolean isChecked() { return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, OFF) != OFF; public int getAvailabilityStatus() { return Flags.forceInvertColor() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } @Override public boolean setChecked(boolean isChecked) { return Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, isChecked ? ON : OFF); public int getSliceHighlightMenuRes() { return R.string.menu_key_accessibility; } @Override public void updateState(@NonNull Preference preference) { super.updateState(preference); final boolean isDarkModeActivated = (mContext.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) != 0; preference.setEnabled(isDarkModeActivated); public void onRadioButtonClicked(@NonNull SelectorWithWidgetPreference preference) { boolean isForceInvertEnabled = preference.getKey().equals(EXPANDED_DARK_THEME_KEY); if (mExpandedDarkThemePreference == null || isForceInvertEnabled == mExpandedDarkThemePreference.isChecked()) { // User selects the same preference as before, we perform an early return to avoid // unnecessary UI updates and IO operations. return; } updateSelectorPreferenceStatus(isForceInvertEnabled); Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, isForceInvertEnabled ? ON : OFF); } @Override public int getAvailabilityStatus() { return Flags.forceInvertColor() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; public void displayPreference(@NonNull PreferenceScreen screen) { super.displayPreference(screen); // initialize the status of the radio buttons PreferenceCategory preferenceCategory = screen.findPreference(getPreferenceKey()); mStandardDarkThemePreference = preferenceCategory.findPreference(STANDARD_DARK_THEME_KEY); mExpandedDarkThemePreference = preferenceCategory.findPreference(EXPANDED_DARK_THEME_KEY); mStandardDarkThemePreference.setOnClickListener(this); mExpandedDarkThemePreference.setOnClickListener(this); boolean isForceInvertEnabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, OFF) != OFF; updateSelectorPreferenceStatus(isForceInvertEnabled); } @Override public int getSliceHighlightMenuRes() { return R.string.menu_key_accessibility; private void updateSelectorPreferenceStatus(boolean isForceInvertEnabled) { if (mStandardDarkThemePreference == null || mExpandedDarkThemePreference == null) { return; } mStandardDarkThemePreference.setChecked(!isForceInvertEnabled); mExpandedDarkThemePreference.setChecked(isForceInvertEnabled); } } tests/robotests/src/com/android/settings/accessibility/ToggleForceInvertPreferenceControllerTest.java→tests/robotests/src/com/android/settings/accessibility/ForceInvertPreferenceControllerTest.java +150 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2025 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. Loading @@ -23,107 +23,124 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Configuration; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.widget.SelectorWithWidgetPreference; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; /** Tests for {@link ToggleForceInvertPreferenceController}. */ /** Tests for {@link ForceInvertPreferenceController}. */ @RunWith(RobolectricTestRunner.class) public class ToggleForceInvertPreferenceControllerTest { public class ForceInvertPreferenceControllerTest { @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Mock private PreferenceScreen mScreen; @Mock private PreferenceCategory mPreferenceCategory; private final Context mContext = ApplicationProvider.getApplicationContext(); private ToggleForceInvertPreferenceController mController; private ForceInvertPreferenceController mController; private SelectorWithWidgetPreference mStandardDarkThemePreference; private SelectorWithWidgetPreference mExpandedDarkThemePreference; @Before public void setUp() { mController = new ToggleForceInvertPreferenceController(mContext, "toggle_force_invert"); mController = new ForceInvertPreferenceController(mContext, "dark_theme_group"); mStandardDarkThemePreference = new SelectorWithWidgetPreference(mContext); mStandardDarkThemePreference .setKey(ForceInvertPreferenceController.STANDARD_DARK_THEME_KEY); mExpandedDarkThemePreference = new SelectorWithWidgetPreference(mContext); mExpandedDarkThemePreference .setKey(ForceInvertPreferenceController.EXPANDED_DARK_THEME_KEY); when(mScreen.findPreference(mController.getPreferenceKey())) .thenReturn(mPreferenceCategory); when(mPreferenceCategory .findPreference(ForceInvertPreferenceController.STANDARD_DARK_THEME_KEY)) .thenReturn(mStandardDarkThemePreference); when(mPreferenceCategory .findPreference(ForceInvertPreferenceController.EXPANDED_DARK_THEME_KEY)) .thenReturn(mExpandedDarkThemePreference); } @Test @RequiresFlagsDisabled(FLAG_FORCE_INVERT_COLOR) public void flagOff_getAvailabilityStatus_shouldReturnUnsupported() { public void getAvailabilityStatus_flagOff_shouldReturnUnsupported() { assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); } @Test @RequiresFlagsEnabled(FLAG_FORCE_INVERT_COLOR) public void flagOn_getAvailabilityStatus_shouldReturnAvailable() { public void getAvailabilityStatus_flagOn_shouldReturnAvailable() { assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.AVAILABLE); } @Test public void updateState_darkModeOn_preferenceEnabled() { Configuration config = mContext.getResources().getConfiguration(); config.uiMode = Configuration.UI_MODE_NIGHT_YES; mContext.getResources().updateConfiguration(config, null); public void settingOff_reflectsCorrectValue() { setEnabled(false); Preference preference = mock(Preference.class); mController.updateState(preference); mController.displayPreference(mScreen); verify(preference).setEnabled(true); assertThat(mStandardDarkThemePreference.isChecked()).isTrue(); assertThat(mExpandedDarkThemePreference.isChecked()).isFalse(); } @Test public void updateState_darkModeOff_preferenceDisabled() { Configuration config = mContext.getResources().getConfiguration(); config.uiMode = Configuration.UI_MODE_NIGHT_NO; mContext.getResources().updateConfiguration(config, null); public void settingOn_reflectsCorrectValue() { setEnabled(true); Preference preference = mock(Preference.class); mController.updateState(preference); mController.displayPreference(mScreen); verify(preference).setEnabled(false); assertThat(mStandardDarkThemePreference.isChecked()).isFalse(); assertThat(mExpandedDarkThemePreference.isChecked()).isTrue(); } @Test public void settingOff_reflectsCorrectValue() { setEnabled(false); assertThat(mController.isChecked()).isFalse(); } public void onRadioButtonClicked_standardDarkTheme_settingChanges() { mController.displayPreference(mScreen); mController.onRadioButtonClicked(mStandardDarkThemePreference); @Test public void settingOn_reflectsCorrectValue() { setEnabled(true); assertThat(mController.isChecked()).isTrue(); assertThat(mStandardDarkThemePreference.isChecked()).isTrue(); assertThat(mExpandedDarkThemePreference.isChecked()).isFalse(); boolean isForceInvertEnabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* def=*/ -1) == ON; assertThat(isForceInvertEnabled).isFalse(); } @Test public void onCheck_settingChanges() { setEnabled(false); mController.setChecked(true); assertThat(isEnabled()).isTrue(); mController.setChecked(false); assertThat(isEnabled()).isFalse(); } public void onRadioButtonClicked_expandedDarkTheme_settingChanges() { mController.displayPreference(mScreen); mController.onRadioButtonClicked(mExpandedDarkThemePreference); private boolean isEnabled() { return Settings.Secure.getInt(mContext.getContentResolver(), assertThat(mStandardDarkThemePreference.isChecked()).isFalse(); assertThat(mExpandedDarkThemePreference.isChecked()).isTrue(); boolean isForceInvertEnabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* def=*/ -1) == ON; assertThat(isForceInvertEnabled).isTrue(); } private void setEnabled(boolean enabled) { Loading Loading
res/values/strings.xml +8 −2 Original line number Diff line number Diff line Loading @@ -5857,10 +5857,16 @@ screen magnification on app transitions</string> <!-- Title for the accessibility preference to power button to end a call. [CHAR LIMIT=35] --> <string name="accessibility_power_button_ends_call_prerefence_title">Power button ends call</string> <!-- Title for the dark theme group category --> <string name="dark_theme_version_category">Mode</string> <!-- Title for the accessibility preference for applying the original dark theme. [CHAR LIMIT=35] --> <string name="accessibility_standard_dark_theme_title">Standard</string> <!-- Summary for the accessibility preference for applying the original dark theme. [CHAR LIMIT=100] --> <string name="accessibility_standard_dark_theme_summary">Applies Dark theme across your device and supported apps</string> <!-- Title for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=35] --> <string name="accessibility_force_invert_title">Make more apps dark</string> <string name="accessibility_expanded_dark_theme_title">Expanded</string> <!-- Summary for the accessibility preference for forcing all apps to use dark theme. [CHAR LIMIT=100] --> <string name="accessibility_force_invert_summary">Expands dark theme to more apps. May not work with all apps.</string> <string name="accessibility_expanded_dark_theme_summary">Automatically applies Dark theme to more apps for improved accessibility</string> <!-- Title for the accessibility preference for disabling animations. [CHAR LIMIT=35] --> <string name="accessibility_disable_animations">Remove animations</string> <!-- Summary for the accessibility preference for disabling animations. [CHAR LIMIT=60] -->
res/xml/dark_mode_settings.xml +17 −7 Original line number Diff line number Diff line Loading @@ -36,15 +36,25 @@ settings:controller="com.android.settings.display.TwilightLocationPreferenceController"/> <PreferenceCategory android:key="display_category" android:title="@string/accessibility_screen_option"> android:key="dark_theme_group" android:title="@string/dark_theme_version_category" settings:controller="com.android.settings.accessibility.ForceInvertPreferenceController"> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="standard_dark_theme" android:title="@string/accessibility_standard_dark_theme_title" android:summary="@string/accessibility_standard_dark_theme_summary" settings:searchable="true"/> <SwitchPreferenceCompat android:key="toggle_force_invert" android:summary="@string/accessibility_force_invert_summary" android:title="@string/accessibility_force_invert_title" settings:controller="com.android.settings.accessibility.ToggleForceInvertPreferenceController"/> <com.android.settingslib.widget.SelectorWithWidgetPreference android:key="expanded_dark_theme" android:title="@string/accessibility_expanded_dark_theme_title" android:summary="@string/accessibility_expanded_dark_theme_summary" settings:searchable="true"/> </PreferenceCategory> <PreferenceCategory android:key="display_category" android:title="@string/accessibility_screen_option"> <DropDownPreference android:key="dark_ui_auto_mode" android:title="@string/dark_ui_auto_mode_title" Loading
src/com/android/settings/accessibility/ToggleForceInvertPreferenceController.java→src/com/android/settings/accessibility/ForceInvertPreferenceController.java +103 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2025 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. Loading @@ -20,50 +20,84 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import android.content.Context; import android.content.res.Configuration; import android.provider.Settings; import android.view.accessibility.Flags; import androidx.annotation.NonNull; import androidx.preference.Preference; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.widget.SelectorWithWidgetPreference; /** A toggle preference controller for force invert (force dark). */ public class ToggleForceInvertPreferenceController extends TogglePreferenceController { public class ForceInvertPreferenceController extends BasePreferenceController implements SelectorWithWidgetPreference.OnClickListener { public ToggleForceInvertPreferenceController(Context context, String preferenceKey) { @VisibleForTesting static final String STANDARD_DARK_THEME_KEY = "standard_dark_theme"; @VisibleForTesting static final String EXPANDED_DARK_THEME_KEY = "expanded_dark_theme"; @Nullable private SelectorWithWidgetPreference mStandardDarkThemePreference; @Nullable private SelectorWithWidgetPreference mExpandedDarkThemePreference; public ForceInvertPreferenceController( @NonNull Context context, @NonNull String preferenceKey) { super(context, preferenceKey); } @Override public boolean isChecked() { return Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, OFF) != OFF; public int getAvailabilityStatus() { return Flags.forceInvertColor() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } @Override public boolean setChecked(boolean isChecked) { return Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, isChecked ? ON : OFF); public int getSliceHighlightMenuRes() { return R.string.menu_key_accessibility; } @Override public void updateState(@NonNull Preference preference) { super.updateState(preference); final boolean isDarkModeActivated = (mContext.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) != 0; preference.setEnabled(isDarkModeActivated); public void onRadioButtonClicked(@NonNull SelectorWithWidgetPreference preference) { boolean isForceInvertEnabled = preference.getKey().equals(EXPANDED_DARK_THEME_KEY); if (mExpandedDarkThemePreference == null || isForceInvertEnabled == mExpandedDarkThemePreference.isChecked()) { // User selects the same preference as before, we perform an early return to avoid // unnecessary UI updates and IO operations. return; } updateSelectorPreferenceStatus(isForceInvertEnabled); Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, isForceInvertEnabled ? ON : OFF); } @Override public int getAvailabilityStatus() { return Flags.forceInvertColor() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; public void displayPreference(@NonNull PreferenceScreen screen) { super.displayPreference(screen); // initialize the status of the radio buttons PreferenceCategory preferenceCategory = screen.findPreference(getPreferenceKey()); mStandardDarkThemePreference = preferenceCategory.findPreference(STANDARD_DARK_THEME_KEY); mExpandedDarkThemePreference = preferenceCategory.findPreference(EXPANDED_DARK_THEME_KEY); mStandardDarkThemePreference.setOnClickListener(this); mExpandedDarkThemePreference.setOnClickListener(this); boolean isForceInvertEnabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, OFF) != OFF; updateSelectorPreferenceStatus(isForceInvertEnabled); } @Override public int getSliceHighlightMenuRes() { return R.string.menu_key_accessibility; private void updateSelectorPreferenceStatus(boolean isForceInvertEnabled) { if (mStandardDarkThemePreference == null || mExpandedDarkThemePreference == null) { return; } mStandardDarkThemePreference.setChecked(!isForceInvertEnabled); mExpandedDarkThemePreference.setChecked(isForceInvertEnabled); } }
tests/robotests/src/com/android/settings/accessibility/ToggleForceInvertPreferenceControllerTest.java→tests/robotests/src/com/android/settings/accessibility/ForceInvertPreferenceControllerTest.java +150 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2025 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. Loading @@ -23,107 +23,124 @@ import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Configuration; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; import com.android.settings.core.BasePreferenceController; import com.android.settingslib.widget.SelectorWithWidgetPreference; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; /** Tests for {@link ToggleForceInvertPreferenceController}. */ /** Tests for {@link ForceInvertPreferenceController}. */ @RunWith(RobolectricTestRunner.class) public class ToggleForceInvertPreferenceControllerTest { public class ForceInvertPreferenceControllerTest { @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Mock private PreferenceScreen mScreen; @Mock private PreferenceCategory mPreferenceCategory; private final Context mContext = ApplicationProvider.getApplicationContext(); private ToggleForceInvertPreferenceController mController; private ForceInvertPreferenceController mController; private SelectorWithWidgetPreference mStandardDarkThemePreference; private SelectorWithWidgetPreference mExpandedDarkThemePreference; @Before public void setUp() { mController = new ToggleForceInvertPreferenceController(mContext, "toggle_force_invert"); mController = new ForceInvertPreferenceController(mContext, "dark_theme_group"); mStandardDarkThemePreference = new SelectorWithWidgetPreference(mContext); mStandardDarkThemePreference .setKey(ForceInvertPreferenceController.STANDARD_DARK_THEME_KEY); mExpandedDarkThemePreference = new SelectorWithWidgetPreference(mContext); mExpandedDarkThemePreference .setKey(ForceInvertPreferenceController.EXPANDED_DARK_THEME_KEY); when(mScreen.findPreference(mController.getPreferenceKey())) .thenReturn(mPreferenceCategory); when(mPreferenceCategory .findPreference(ForceInvertPreferenceController.STANDARD_DARK_THEME_KEY)) .thenReturn(mStandardDarkThemePreference); when(mPreferenceCategory .findPreference(ForceInvertPreferenceController.EXPANDED_DARK_THEME_KEY)) .thenReturn(mExpandedDarkThemePreference); } @Test @RequiresFlagsDisabled(FLAG_FORCE_INVERT_COLOR) public void flagOff_getAvailabilityStatus_shouldReturnUnsupported() { public void getAvailabilityStatus_flagOff_shouldReturnUnsupported() { assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); } @Test @RequiresFlagsEnabled(FLAG_FORCE_INVERT_COLOR) public void flagOn_getAvailabilityStatus_shouldReturnAvailable() { public void getAvailabilityStatus_flagOn_shouldReturnAvailable() { assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.AVAILABLE); } @Test public void updateState_darkModeOn_preferenceEnabled() { Configuration config = mContext.getResources().getConfiguration(); config.uiMode = Configuration.UI_MODE_NIGHT_YES; mContext.getResources().updateConfiguration(config, null); public void settingOff_reflectsCorrectValue() { setEnabled(false); Preference preference = mock(Preference.class); mController.updateState(preference); mController.displayPreference(mScreen); verify(preference).setEnabled(true); assertThat(mStandardDarkThemePreference.isChecked()).isTrue(); assertThat(mExpandedDarkThemePreference.isChecked()).isFalse(); } @Test public void updateState_darkModeOff_preferenceDisabled() { Configuration config = mContext.getResources().getConfiguration(); config.uiMode = Configuration.UI_MODE_NIGHT_NO; mContext.getResources().updateConfiguration(config, null); public void settingOn_reflectsCorrectValue() { setEnabled(true); Preference preference = mock(Preference.class); mController.updateState(preference); mController.displayPreference(mScreen); verify(preference).setEnabled(false); assertThat(mStandardDarkThemePreference.isChecked()).isFalse(); assertThat(mExpandedDarkThemePreference.isChecked()).isTrue(); } @Test public void settingOff_reflectsCorrectValue() { setEnabled(false); assertThat(mController.isChecked()).isFalse(); } public void onRadioButtonClicked_standardDarkTheme_settingChanges() { mController.displayPreference(mScreen); mController.onRadioButtonClicked(mStandardDarkThemePreference); @Test public void settingOn_reflectsCorrectValue() { setEnabled(true); assertThat(mController.isChecked()).isTrue(); assertThat(mStandardDarkThemePreference.isChecked()).isTrue(); assertThat(mExpandedDarkThemePreference.isChecked()).isFalse(); boolean isForceInvertEnabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* def=*/ -1) == ON; assertThat(isForceInvertEnabled).isFalse(); } @Test public void onCheck_settingChanges() { setEnabled(false); mController.setChecked(true); assertThat(isEnabled()).isTrue(); mController.setChecked(false); assertThat(isEnabled()).isFalse(); } public void onRadioButtonClicked_expandedDarkTheme_settingChanges() { mController.displayPreference(mScreen); mController.onRadioButtonClicked(mExpandedDarkThemePreference); private boolean isEnabled() { return Settings.Secure.getInt(mContext.getContentResolver(), assertThat(mStandardDarkThemePreference.isChecked()).isFalse(); assertThat(mExpandedDarkThemePreference.isChecked()).isTrue(); boolean isForceInvertEnabled = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED, /* def=*/ -1) == ON; assertThat(isForceInvertEnabled).isTrue(); } private void setEnabled(boolean enabled) { Loading