diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 4c515ad441d..0e39d6dd9a5 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -110,6 +110,18 @@
- @string/dark_ui_auto_mode_auto
+
+
+
+ - @string/dark_ui_auto_mode_never
+
+ - @string/dark_ui_auto_mode_custom
+
+ - @string/dark_ui_auto_mode_auto
+
+ - @string/dark_ui_auto_mode_custom_bedtime
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7a7d7913981..2dbe40bfd2b 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3077,6 +3077,8 @@
Turns on from sunset to sunrise
Turns on at custom time
+
+ Turns on at bedtime
Status
@@ -3085,18 +3087,27 @@
Will turn on automatically at sunset
Will turn on automatically at %1$s
+
+ Will turn on automatically at bedtime
Will never turn off automatically
Will turn off automatically at sunrise
Will turn off automatically at %1$s
+
+ Will turn off automatically after bedtime
Turn on until %1$s
Turn off until %1$s
Dark theme uses a black background to help keep battery alive longer on some screens. Dark theme schedules wait to turn on until your screen is off.
+
+ Dark theme is currently following your Bedtime mode schedule
+
+ Bedtime mode settings
+
Screen timeout
diff --git a/res/xml/dark_mode_settings.xml b/res/xml/dark_mode_settings.xml
index 41946c1c141..7f136594807 100644
--- a/res/xml/dark_mode_settings.xml
+++ b/res/xml/dark_mode_settings.xml
@@ -55,4 +55,11 @@
android:title="@string/night_display_end_time_title"
settings:searchable="false"/>
+
+
diff --git a/src/com/android/settings/display/darkmode/BedtimeSettings.java b/src/com/android/settings/display/darkmode/BedtimeSettings.java
new file mode 100644
index 00000000000..9714afac80e
--- /dev/null
+++ b/src/com/android/settings/display/darkmode/BedtimeSettings.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 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.darkmode;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+/** Manages Digital Wellbeing bedtime settings' intents. */
+public final class BedtimeSettings {
+ @VisibleForTesting
+ public static final String ACTION_BEDTIME_SETTINGS = "android.settings.BEDTIME_SETTINGS";
+
+ private final Context mContext;
+ private final PackageManager mPackageManager;
+ private final String mWellbeingPackage;
+
+ public BedtimeSettings(Context context) {
+ mContext = context;
+ mPackageManager = context.getPackageManager();
+ mWellbeingPackage = mContext.getResources().getString(
+ com.android.internal.R.string.config_defaultWellbeingPackage);
+ }
+
+ /**
+ * Returns the bedtime settings intent. If the bedtime settings isn't available, returns
+ * {@code null}.
+ */
+ @Nullable
+ public Intent getBedtimeSettingsIntent() {
+ Intent bedtimeSettingsIntent = new Intent(ACTION_BEDTIME_SETTINGS).setPackage(
+ mWellbeingPackage);
+ ResolveInfo bedtimeSettingInfo = mPackageManager.resolveActivity(bedtimeSettingsIntent,
+ PackageManager.MATCH_DEFAULT_ONLY);
+
+ if (bedtimeSettingInfo != null && bedtimeSettingInfo.activityInfo.isEnabled()) {
+ return bedtimeSettingsIntent;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java b/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java
index 800e7e506b0..66ab2d37fa3 100644
--- a/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java
+++ b/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java
@@ -18,7 +18,6 @@ package com.android.settings.display.darkmode;
import android.app.UiModeManager;
import android.content.Context;
import android.content.res.Configuration;
-import android.os.PowerManager;
import android.widget.Switch;
import androidx.preference.Preference;
@@ -41,13 +40,11 @@ public class DarkModeActivationPreferenceController extends BasePreferenceContro
private final UiModeManager mUiModeManager;
private final MetricsFeatureProvider mMetricsFeatureProvider;
- private PowerManager mPowerManager;
private TimeFormatter mFormat;
private MainSwitchPreference mPreference;
public DarkModeActivationPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
- mPowerManager = context.getSystemService(PowerManager.class);
mUiModeManager = context.getSystemService(UiModeManager.class);
mFormat = new TimeFormatter(context);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
@@ -76,6 +73,13 @@ public class DarkModeActivationPreferenceController extends BasePreferenceContro
? R.string.dark_ui_summary_on_auto_mode_auto
: R.string.dark_ui_summary_off_auto_mode_auto);
} else if (mode == UiModeManager.MODE_NIGHT_CUSTOM) {
+ if (mUiModeManager.getNightModeCustomType()
+ == UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME) {
+ return mContext.getString(isActivated
+ ? R.string.dark_ui_summary_on_auto_mode_custom_bedtime
+ : R.string.dark_ui_summary_off_auto_mode_custom_bedtime);
+ }
+
final LocalTime time = isActivated
? mUiModeManager.getCustomNightModeEnd()
: mUiModeManager.getCustomNightModeStart();
diff --git a/src/com/android/settings/display/darkmode/DarkModeCustomBedtimePreferenceController.java b/src/com/android/settings/display/darkmode/DarkModeCustomBedtimePreferenceController.java
new file mode 100644
index 00000000000..c6e379cf621
--- /dev/null
+++ b/src/com/android/settings/display/darkmode/DarkModeCustomBedtimePreferenceController.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 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.darkmode;
+
+import static android.app.UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME;
+
+import android.app.UiModeManager;
+import android.content.Context;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.FooterPreference;
+
+/** Controller for the night mode bedtime custom mode footer. */
+public class DarkModeCustomBedtimePreferenceController extends BasePreferenceController {
+ private final UiModeManager mUiModeManager;
+ private FooterPreference mFooterPreference;
+ private BedtimeSettings mBedtimeSettings;
+
+ public DarkModeCustomBedtimePreferenceController(Context context, String key) {
+ super(context, key);
+ mUiModeManager = context.getSystemService(UiModeManager.class);
+ mBedtimeSettings = new BedtimeSettings(context);
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return mBedtimeSettings.getBedtimeSettingsIntent() == null
+ ? UNSUPPORTED_ON_DEVICE
+ : AVAILABLE_UNSEARCHABLE;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mFooterPreference = screen.findPreference(getPreferenceKey());
+ mFooterPreference.setLearnMoreAction(
+ v -> v.getContext().startActivity(mBedtimeSettings.getBedtimeSettingsIntent()));
+ mFooterPreference.setLearnMoreText(
+ mContext.getString(R.string.dark_ui_bedtime_footer_action));
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ if (mUiModeManager.getNightModeCustomType() != MODE_NIGHT_CUSTOM_TYPE_BEDTIME) {
+ preference.setVisible(false);
+ return;
+ }
+ preference.setVisible(true);
+ }
+}
diff --git a/src/com/android/settings/display/darkmode/DarkModeCustomPreferenceController.java b/src/com/android/settings/display/darkmode/DarkModeCustomPreferenceController.java
index 5f22cb03f40..10cda5334c5 100644
--- a/src/com/android/settings/display/darkmode/DarkModeCustomPreferenceController.java
+++ b/src/com/android/settings/display/darkmode/DarkModeCustomPreferenceController.java
@@ -15,21 +15,20 @@
package com.android.settings.display.darkmode;
-import android.app.Dialog;
+import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
+
import android.app.TimePickerDialog;
import android.app.UiModeManager;
import android.content.Context;
import android.text.TextUtils;
+
import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
+
import com.android.settings.core.BasePreferenceController;
-import com.android.settings.dashboard.DashboardFragment;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
-import static android.app.UiModeManager.MODE_NIGHT_CUSTOM;
-
/**
* Controller for custom mode night mode time settings
*/
@@ -89,7 +88,9 @@ public class DarkModeCustomPreferenceController extends BasePreferenceController
@Override
protected void refreshSummary(Preference preference) {
- if (mUiModeManager.getNightMode() != MODE_NIGHT_CUSTOM) {
+ if (mUiModeManager.getNightMode() != MODE_NIGHT_CUSTOM
+ || mUiModeManager.getNightModeCustomType()
+ != UiModeManager.MODE_NIGHT_CUSTOM_TYPE_SCHEDULE) {
preference.setVisible(false);
return;
}
diff --git a/src/com/android/settings/display/darkmode/DarkModeObserver.java b/src/com/android/settings/display/darkmode/DarkModeObserver.java
index 1482a2a0c28..a15fbc859cc 100644
--- a/src/com/android/settings/display/darkmode/DarkModeObserver.java
+++ b/src/com/android/settings/display/darkmode/DarkModeObserver.java
@@ -25,6 +25,7 @@ import android.os.Looper;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
+
import com.android.internal.annotations.VisibleForTesting;
/**
@@ -64,12 +65,16 @@ public class DarkModeObserver {
callback.run();
mCallback = callback;
final Uri uri = Settings.Secure.getUriFor(Settings.Secure.UI_NIGHT_MODE);
+ final Uri customType =
+ Settings.Secure.getUriFor(Settings.Secure.UI_NIGHT_MODE_CUSTOM_TYPE);
final Uri customStart =
Settings.Secure.getUriFor(Settings.Secure.DARK_THEME_CUSTOM_START_TIME);
final Uri customEnd =
Settings.Secure.getUriFor(Settings.Secure.DARK_THEME_CUSTOM_END_TIME);
mContext.getContentResolver()
.registerContentObserver(uri, false, mContentObserver);
+ mContext.getContentResolver()
+ .registerContentObserver(customType, false, mContentObserver);
mContext.getContentResolver()
.registerContentObserver(customStart, false, mContentObserver);
mContext.getContentResolver()
diff --git a/src/com/android/settings/display/darkmode/DarkModePreference.java b/src/com/android/settings/display/darkmode/DarkModePreference.java
index 4820667ef10..4e1e3087d69 100644
--- a/src/com/android/settings/display/darkmode/DarkModePreference.java
+++ b/src/com/android/settings/display/darkmode/DarkModePreference.java
@@ -81,13 +81,20 @@ public class DarkModePreference extends PrimarySwitchPreference {
? R.string.dark_ui_summary_on_auto_mode_auto
: R.string.dark_ui_summary_off_auto_mode_auto);
} else if (mode == UiModeManager.MODE_NIGHT_CUSTOM) {
- final LocalTime time = active
- ? mUiModeManager.getCustomNightModeEnd()
- : mUiModeManager.getCustomNightModeStart();
- final String timeStr = mFormat.of(time);
- summary = getContext().getString(active
- ? R.string.dark_ui_summary_on_auto_mode_custom
- : R.string.dark_ui_summary_off_auto_mode_custom, timeStr);
+ if (mUiModeManager.getNightModeCustomType()
+ == UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME) {
+ summary = getContext().getString(active
+ ? R.string.dark_ui_summary_on_auto_mode_custom_bedtime
+ : R.string.dark_ui_summary_off_auto_mode_custom_bedtime);
+ } else {
+ final LocalTime time = active
+ ? mUiModeManager.getCustomNightModeEnd()
+ : mUiModeManager.getCustomNightModeStart();
+ final String timeStr = mFormat.of(time);
+ summary = getContext().getString(active
+ ? R.string.dark_ui_summary_on_auto_mode_custom
+ : R.string.dark_ui_summary_off_auto_mode_custom, timeStr);
+ }
} else {
summary = getContext().getString(active
? R.string.dark_ui_summary_on_auto_mode_never
diff --git a/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java b/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java
index 2ac9a9f8638..e122ad06864 100644
--- a/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java
+++ b/src/com/android/settings/display/darkmode/DarkModeScheduleSelectorController.java
@@ -34,10 +34,13 @@ import com.android.settings.display.TwilightLocationDialog;
public class DarkModeScheduleSelectorController extends BasePreferenceController
implements Preference.OnPreferenceChangeListener {
private static final String TAG = DarkModeScheduleSelectorController.class.getSimpleName();
+
private final UiModeManager mUiModeManager;
- private PowerManager mPowerManager;
+ private final PowerManager mPowerManager;
+ private final LocationManager mLocationManager;
+ private final BedtimeSettings mBedtimeSettings;
+
private DropDownPreference mPreference;
- private LocationManager mLocationManager;
private int mCurrentMode;
public DarkModeScheduleSelectorController(Context context, String key) {
@@ -45,12 +48,19 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController
mUiModeManager = context.getSystemService(UiModeManager.class);
mPowerManager = context.getSystemService(PowerManager.class);
mLocationManager = context.getSystemService(LocationManager.class);
+ mBedtimeSettings = new BedtimeSettings(context);
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
+ if (mBedtimeSettings.getBedtimeSettingsIntent() != null) {
+ String[] entries = mContext.getResources().getStringArray(
+ R.array.dark_ui_scheduler_with_bedtime_preference_titles);
+ mPreference.setEntries(entries);
+ mPreference.setEntryValues(entries);
+ }
}
@Override
@@ -73,7 +83,12 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController
resId = R.string.dark_ui_auto_mode_auto;
break;
case UiModeManager.MODE_NIGHT_CUSTOM:
- resId = R.string.dark_ui_auto_mode_custom;
+ boolean isCustomBedtime = mBedtimeSettings.getBedtimeSettingsIntent() != null
+ && mUiModeManager.getNightModeCustomType()
+ == UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME;
+ resId = isCustomBedtime
+ ? R.string.dark_ui_auto_mode_custom_bedtime
+ : R.string.dark_ui_auto_mode_custom;
break;
default:
resId = R.string.dark_ui_auto_mode_never;
@@ -104,6 +119,9 @@ public class DarkModeScheduleSelectorController extends BasePreferenceController
} else if (newMode == mPreference.findIndexOfValue(
mContext.getString(R.string.dark_ui_auto_mode_custom))) {
mUiModeManager.setNightMode(UiModeManager.MODE_NIGHT_CUSTOM);
+ } else if (newMode == mPreference.findIndexOfValue(
+ mContext.getString(R.string.dark_ui_auto_mode_custom_bedtime))) {
+ mUiModeManager.setNightModeCustomType(UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
}
mCurrentMode = newMode;
return true;
diff --git a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceControllerTest.java
index 0d4646e9106..f41352b030b 100644
--- a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceControllerTest.java
@@ -19,7 +19,6 @@ import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEA
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
@@ -54,12 +53,11 @@ public class DarkModeActivationPreferenceControllerTest {
private DarkModeActivationPreferenceController mController;
private String mPreferenceKey = "key";
- @Mock
private MainSwitchPreference mPreference;
@Mock
private PreferenceScreen mScreen;
@Mock
- private Resources res;
+ private Resources mRes;
@Mock
private UiModeManager mService;
@Mock
@@ -77,9 +75,10 @@ public class DarkModeActivationPreferenceControllerTest {
MockitoAnnotations.initMocks(this);
FakeFeatureFactory.setupForTest();
mContext = spy(RuntimeEnvironment.application);
+ mPreference = new MainSwitchPreference(mContext);
mService = mock(UiModeManager.class);
- when(mContext.getResources()).thenReturn(res);
- when(res.getConfiguration()).thenReturn(mConfigNightNo);
+ when(mContext.getResources()).thenReturn(mRes);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightNo);
when(mContext.getSystemService(UiModeManager.class)).thenReturn(mService);
when(mContext.getSystemService(PowerManager.class)).thenReturn(mPM);
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
@@ -101,10 +100,14 @@ public class DarkModeActivationPreferenceControllerTest {
R.string.dark_ui_summary_off_auto_mode_never)).thenReturn("summary_off_manual");
when(mContext.getString(
R.string.dark_ui_summary_on_auto_mode_never)).thenReturn("summary_on_manual");
- when(mContext.getString(
- R.string.dark_ui_summary_on_auto_mode_custom)).thenReturn("summary_on_custom");
- when(mContext.getString(
- R.string.dark_ui_summary_off_auto_mode_custom)).thenReturn("summary_off_custom");
+ when(mContext.getString(R.string.dark_ui_summary_on_auto_mode_custom, "10:00 AM"))
+ .thenReturn("summary_on_custom");
+ when(mContext.getString(R.string.dark_ui_summary_off_auto_mode_custom, "10:00 AM"))
+ .thenReturn("summary_off_custom");
+ when(mContext.getString(R.string.dark_ui_summary_on_auto_mode_custom_bedtime))
+ .thenReturn("summary_on_custom_bedtime");
+ when(mContext.getString(R.string.dark_ui_summary_off_auto_mode_custom_bedtime))
+ .thenReturn("summary_off_custom_bedtime");
mController = new DarkModeActivationPreferenceController(mContext, mPreferenceKey, mFormat);
mController.displayPreference(mScreen);
mConfigNightNo.uiMode = Configuration.UI_MODE_NIGHT_NO;
@@ -114,85 +117,95 @@ public class DarkModeActivationPreferenceControllerTest {
}
@Test
- public void nightMode_toggleButton_offManual() {
+ public void nightMode_toggleButton_onManual() {
when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
- when(res.getConfiguration()).thenReturn(mConfigNightYes);
- final MainSwitchPreference preference = new MainSwitchPreference(mContext);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightYes);
mController.updateState(mPreference);
- assertThat(preference.isChecked()).isFalse();
+ assertThat(mPreference.isChecked()).isTrue();
+ assertThat(mController.getSummary().toString()).isEqualTo("summary_on_manual");
}
@Test
- public void nightMode_toggleButton_offCustom() {
- when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
- when(res.getConfiguration()).thenReturn(mConfigNightYes);
- final MainSwitchPreference preference = new MainSwitchPreference(mContext);
+ public void nightMode_toggleButton_offManual() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_NO);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightNo);
- mController.updateState(preference);
+ mController.updateState(mPreference);
- assertThat(preference.isChecked()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+ assertThat(mController.getSummary().toString()).isEqualTo("summary_off_manual");
}
@Test
public void nightMode_toggleButton_onCustom() {
when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
- when(res.getConfiguration()).thenReturn(mConfigNightYes);
- final MainSwitchPreference preference = new MainSwitchPreference(mContext);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightYes);
- mController.updateState(preference);
+ mController.updateState(mPreference);
- assertThat(preference.isChecked()).isFalse();
+ assertThat(mPreference.isChecked()).isTrue();
+ assertThat(mController.getSummary().toString()).isEqualTo("summary_on_custom");
}
@Test
- public void nightMode_toggleButton_onAutoWhenModeIsYes() {
- when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
- when(res.getConfiguration()).thenReturn(mConfigNightNo);
- final MainSwitchPreference preference = new MainSwitchPreference(mContext, null);
+ public void nightMode_toggleButton_offCustom() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightNo);
- mController.updateState(preference);
+ mController.updateState(mPreference);
- assertThat(preference.isChecked()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+ assertThat(mController.getSummary().toString()).isEqualTo("summary_off_custom");
}
@Test
- public void nightMode_toggleButton_onAutoWhenModeIsAuto() {
+ public void nightMode_toggleButton_onCustomBedtime() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ when(mService.getNightModeCustomType())
+ .thenReturn(UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightYes);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isChecked()).isTrue();
+ assertThat(mController.getSummary().toString()).isEqualTo("summary_on_custom_bedtime");
+ }
+
+ @Test
+ public void nightMode_toggleButton_offCustomBedtime() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ when(mService.getNightModeCustomType())
+ .thenReturn(UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightNo);
+
+ mController.updateState(mPreference);
+
+ assertThat(mPreference.isChecked()).isFalse();
+ assertThat(mController.getSummary().toString()).isEqualTo("summary_off_custom_bedtime");
+ }
+
+ @Test
+ public void nightMode_toggleButton_onAuto() {
when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_AUTO);
- when(res.getConfiguration()).thenReturn(mConfigNightNo);
- final MainSwitchPreference preference = new MainSwitchPreference(mContext);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightYes);
- mController.updateState(preference);
+ mController.updateState(mPreference);
- assertThat(preference.isChecked()).isFalse();
+ assertThat(mPreference.isChecked()).isTrue();
+ assertThat(mController.getSummary().toString()).isEqualTo("summary_on_auto");
}
@Test
- public void nightModeSummary_buttonText_onManual() {
- when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_NO);
- when(res.getConfiguration()).thenReturn(mConfigNightYes);
-
- assertEquals(mController.getSummary(), mContext.getString(
- R.string.dark_ui_summary_on_auto_mode_never));
- }
-
- @Test
- public void nightModeSummary_buttonText_offAuto() {
+ public void nightMode_toggleButton_offAuto() {
when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_AUTO);
- when(res.getConfiguration()).thenReturn(mConfigNightNo);
+ when(mRes.getConfiguration()).thenReturn(mConfigNightNo);
- assertEquals(mController.getSummary(), mContext.getString(
- R.string.dark_ui_summary_off_auto_mode_auto));
- }
+ mController.updateState(mPreference);
- @Test
- public void buttonVisisbility_hideButton_offWhenInPowerSaveMode() {
- when(mPM.isPowerSaveMode()).thenReturn(true);
- final MainSwitchPreference preference = new MainSwitchPreference(mContext);
-
- mController.updateState(preference);
- assertThat(preference.isChecked()).isFalse();
+ assertThat(mPreference.isChecked()).isFalse();
+ assertThat(mController.getSummary().toString()).isEqualTo("summary_off_auto");
}
@Test
diff --git a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeCustomBedtimePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeCustomBedtimePreferenceControllerTest.java
new file mode 100644
index 00000000000..7f505688d67
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeCustomBedtimePreferenceControllerTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2022 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.darkmode;
+
+import static android.app.UiModeManager.MODE_NIGHT_AUTO;
+import static android.app.UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME;
+import static android.app.UiModeManager.MODE_NIGHT_CUSTOM_TYPE_SCHEDULE;
+import static android.app.UiModeManager.MODE_NIGHT_NO;
+import static android.app.UiModeManager.MODE_NIGHT_YES;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
+import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
+
+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.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.UiModeManager;
+import android.content.Context;
+import android.content.res.Resources;
+
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.settings.testutils.BedtimeSettingsUtils;
+import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settingslib.widget.FooterPreference;
+
+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;
+
+@RunWith(RobolectricTestRunner.class)
+public class DarkModeCustomBedtimePreferenceControllerTest {
+ @Mock
+ private UiModeManager mService;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private Resources mResources;
+ @Mock
+ private FooterPreference mFooterPreference;
+
+ private DarkModeCustomBedtimePreferenceController mController;
+ private Context mContext;
+ private BedtimeSettingsUtils mBedtimeSettingsUtils;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ FakeFeatureFactory.setupForTest();
+
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mBedtimeSettingsUtils = new BedtimeSettingsUtils(mContext);
+
+ when(mContext.getSystemService(UiModeManager.class)).thenReturn(mService);
+
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getString(com.android.internal.R.string.config_defaultWellbeingPackage))
+ .thenReturn("wellbeing");
+
+ when(mScreen.findPreference(anyString())).thenReturn(mFooterPreference);
+
+ mController = new DarkModeCustomBedtimePreferenceController(mContext, "key");
+ }
+
+ @Test
+ public void getAvailabilityStatus_bedtimeSettingsExist_shouldBeAvailableUnsearchable() {
+ mBedtimeSettingsUtils.installBedtimeSettings("wellbeing" /* wellbeingPackage */,
+ true /* enabled */);
+ when(mService.getNightModeCustomType()).thenReturn(MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_bedtimeSettingsDisabled_shouldBeUnsupportedOnDevice() {
+ mBedtimeSettingsUtils.installBedtimeSettings("wellbeing" /* wellbeingPackage */,
+ false /* enabled */);
+ when(mService.getNightModeCustomType()).thenReturn(MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
+
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+ }
+
+ @Test
+ public void nightModeCustomModeBedtime_bedtimeSettingsExist_shouldShowFooterPreference() {
+ mBedtimeSettingsUtils.installBedtimeSettings("wellbeing" /* wellbeingPackage */,
+ true /* enabled */);
+ when(mService.getNightModeCustomType()).thenReturn(MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
+
+ mController.updateState(mFooterPreference);
+
+ verify(mFooterPreference).setVisible(eq(true));
+ assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
+ }
+
+ @Test
+ public void nightModeCustomModeSchedule_bedtimeSettingsExist_shouldHideFooterPreference() {
+ mBedtimeSettingsUtils.installBedtimeSettings("wellbeing" /* wellbeingPackage */,
+ true /* enabled */);
+ when(mService.getNightModeCustomType()).thenReturn(MODE_NIGHT_CUSTOM_TYPE_SCHEDULE);
+
+ mController.updateState(mFooterPreference);
+
+ verify(mFooterPreference).setVisible(eq(false));
+ }
+
+ @Test
+ public void nightModeNo_bedtimeSettingsExist_shouldHideFooterPreference() {
+ mBedtimeSettingsUtils.installBedtimeSettings("wellbeing" /* wellbeingPackage */,
+ true /* enabled */);
+ when(mService.getNightMode()).thenReturn(MODE_NIGHT_NO);
+
+ mController.updateState(mFooterPreference);
+
+ verify(mFooterPreference).setVisible(eq(false));
+ }
+
+ @Test
+ public void nightModeYes_bedtimeSettingsExist_shouldHideFooterPreference() {
+ mBedtimeSettingsUtils.installBedtimeSettings("wellbeing" /* wellbeingPackage */,
+ true /* enabled */);
+ when(mService.getNightMode()).thenReturn(MODE_NIGHT_YES);
+
+ mController.updateState(mFooterPreference);
+
+ verify(mFooterPreference).setVisible(eq(false));
+ }
+
+ @Test
+ public void nightModeAuto_bedtimeSettingsExist_shouldHideFooterPreference() {
+ mBedtimeSettingsUtils.installBedtimeSettings("wellbeing" /* wellbeingPackage */,
+ true /* enabled */);
+ when(mService.getNightMode()).thenReturn(MODE_NIGHT_AUTO);
+
+ mController.updateState(mFooterPreference);
+
+ verify(mFooterPreference).setVisible(eq(false));
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeCustomPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeCustomPreferenceControllerTest.java
index 107b79f7b77..4a26205bb58 100644
--- a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeCustomPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeCustomPreferenceControllerTest.java
@@ -15,12 +15,20 @@
package com.android.settings.display.darkmode;
+import static org.mockito.ArgumentMatchers.any;
+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.app.UiModeManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+
import androidx.preference.Preference;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -28,12 +36,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(RobolectricTestRunner.class)
public class DarkModeCustomPreferenceControllerTest {
private DarkModeCustomPreferenceController mController;
@@ -69,23 +71,87 @@ public class DarkModeCustomPreferenceControllerTest {
}
@Test
- public void nightMode_customOff_hidePreference() {
+ public void nightMode_manualOn_hidePreference() {
when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+ mConfig.uiMode = Configuration.UI_MODE_NIGHT_YES;
+
mController.refreshSummary(mPreference);
+
verify(mPreference).setVisible(eq(false));
}
+ @Test
+ public void nightMode_manualOff_hidePreference() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_NO);
+ mConfig.uiMode = Configuration.UI_MODE_NIGHT_NO;
+
+ mController.refreshSummary(mPreference);
+
+ verify(mPreference).setVisible(eq(false));
+ }
+
+
+ @Test
+ public void nightMode_customOn_showPreference() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ mConfig.uiMode = Configuration.UI_MODE_NIGHT_YES;
+
+ mController.refreshSummary(mPreference);
+
+ verify(mPreference).setVisible(eq(true));
+ }
+
@Test
public void nightMode_customOff_showPreference() {
when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ mConfig.uiMode = Configuration.UI_MODE_NIGHT_NO;
+
mController.refreshSummary(mPreference);
+
verify(mPreference).setVisible(eq(true));
}
@Test
- public void nightMode_customOff_setSummaryNotNull() {
+ public void nightMode_customBedtimeOn_hidePreference() {
when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ when(mService.getNightModeCustomType())
+ .thenReturn(UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
+ mConfig.uiMode = Configuration.UI_MODE_NIGHT_YES;
+
mController.refreshSummary(mPreference);
- verify(mPreference).setSummary(eq(mFormat.of(null)));
+
+ verify(mPreference).setVisible(eq(false));
+ }
+
+ @Test
+ public void nightMode_customBedtimeOff_hidePreference() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ when(mService.getNightModeCustomType())
+ .thenReturn(UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
+ mConfig.uiMode = Configuration.UI_MODE_NIGHT_NO;
+
+ mController.refreshSummary(mPreference);
+
+ verify(mPreference).setVisible(eq(false));
+ }
+
+ @Test
+ public void nightMode_customOn_setSummaryTo10Am() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ mConfig.uiMode = Configuration.UI_MODE_NIGHT_YES;
+
+ mController.refreshSummary(mPreference);
+
+ verify(mPreference).setSummary(eq("10:00 AM"));
+ }
+
+ @Test
+ public void nightMode_customOff_setSummaryTo10Am() {
+ when(mService.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_CUSTOM);
+ mConfig.uiMode = Configuration.UI_MODE_NIGHT_NO;
+
+ mController.refreshSummary(mPreference);
+
+ verify(mPreference).setSummary(eq("10:00 AM"));
}
}
diff --git a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeObserverTest.java b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeObserverTest.java
index dfa8ba118e4..3532be1d59b 100644
--- a/tests/robotests/src/com/android/settings/display/darkmode/DarkModeObserverTest.java
+++ b/tests/robotests/src/com/android/settings/display/darkmode/DarkModeObserverTest.java
@@ -14,35 +14,58 @@
package com.android.settings.display.darkmode;
-import android.content.Context;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.provider.Settings;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
+import static android.provider.Settings.Secure.DARK_THEME_CUSTOM_END_TIME;
+import static android.provider.Settings.Secure.DARK_THEME_CUSTOM_START_TIME;
+import static android.provider.Settings.Secure.UI_NIGHT_MODE;
+import static android.provider.Settings.Secure.UI_NIGHT_MODE_CUSTOM_TYPE;
+import static android.provider.Settings.Secure.getUriFor;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
-@RunWith(RobolectricTestRunner.class)
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.ParameterizedRobolectricTestRunner;
+
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(ParameterizedRobolectricTestRunner.class)
public class DarkModeObserverTest {
+ @ParameterizedRobolectricTestRunner.Parameters(name = "uri: {0}")
+ public static List