Dark theme twilight mode backend and tile
am: 381e3300e8
Change-Id: I0d5b96795d5ad818a9b7a21758721e35059d18ed
This commit is contained in:
@@ -68,4 +68,9 @@ interface IUiModeManager {
|
|||||||
* Tells if Night mode is locked or not.
|
* Tells if Night mode is locked or not.
|
||||||
*/
|
*/
|
||||||
boolean isNightModeLocked();
|
boolean isNightModeLocked();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
boolean setNightModeActivated(boolean active);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -473,4 +473,18 @@ public class UiModeManager {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide*
|
||||||
|
*/
|
||||||
|
public boolean setNightModeActivated(boolean active) {
|
||||||
|
if (mService != null) {
|
||||||
|
try {
|
||||||
|
return mService.setNightModeActivated(active);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -894,6 +894,10 @@
|
|||||||
<string name="quick_settings_ui_mode_night_label">Dark theme</string>
|
<string name="quick_settings_ui_mode_night_label">Dark theme</string>
|
||||||
<!-- QuickSettings: Label for the dark theme tile when enabled by battery saver. [CHAR LIMIT=40] -->
|
<!-- QuickSettings: Label for the dark theme tile when enabled by battery saver. [CHAR LIMIT=40] -->
|
||||||
<string name="quick_settings_ui_mode_night_label_battery_saver">Dark theme\nBattery saver</string>
|
<string name="quick_settings_ui_mode_night_label_battery_saver">Dark theme\nBattery saver</string>
|
||||||
|
<!-- QuickSettings: Secondary text for when the Dark Mode will be enabled at sunset. [CHAR LIMIT=20] -->
|
||||||
|
<string name="quick_settings_dark_mode_secondary_label_on_at_sunset">On at sunset</string>
|
||||||
|
<!-- QuickSettings: Secondary text for when the Dark Mode will be on until sunrise. [CHAR LIMIT=20] -->
|
||||||
|
<string name="quick_settings_dark_mode_secondary_label_until_sunrise">Until sunrise</string>
|
||||||
|
|
||||||
<!-- QuickSettings: NFC tile [CHAR LIMIT=NONE] -->
|
<!-- QuickSettings: NFC tile [CHAR LIMIT=NONE] -->
|
||||||
<string name="quick_settings_nfc_label">NFC</string>
|
<string name="quick_settings_nfc_label">NFC</string>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import android.content.Intent;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.service.quicksettings.Tile;
|
import android.service.quicksettings.Tile;
|
||||||
import android.widget.Switch;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
@@ -79,24 +79,33 @@ public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean newState = !mState.value;
|
boolean newState = !mState.value;
|
||||||
mUiModeManager.setNightMode(newState ? UiModeManager.MODE_NIGHT_YES
|
mUiModeManager.setNightModeActivated(newState);
|
||||||
: UiModeManager.MODE_NIGHT_NO);
|
|
||||||
refreshState(newState);
|
refreshState(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void handleUpdateState(BooleanState state, Object arg) {
|
protected void handleUpdateState(BooleanState state, Object arg) {
|
||||||
|
int uiMode = mUiModeManager.getNightMode();
|
||||||
boolean powerSave = mBatteryController.isPowerSave();
|
boolean powerSave = mBatteryController.isPowerSave();
|
||||||
|
boolean isAuto = uiMode == UiModeManager.MODE_NIGHT_AUTO;
|
||||||
boolean nightMode = (mContext.getResources().getConfiguration().uiMode
|
boolean nightMode = (mContext.getResources().getConfiguration().uiMode
|
||||||
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
& Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
||||||
|
|
||||||
|
if (isAuto) {
|
||||||
|
state.secondaryLabel = mContext.getResources().getString(nightMode
|
||||||
|
? R.string.quick_settings_dark_mode_secondary_label_until_sunrise
|
||||||
|
: R.string.quick_settings_dark_mode_secondary_label_on_at_sunset);
|
||||||
|
} else {
|
||||||
|
state.secondaryLabel = null;
|
||||||
|
}
|
||||||
state.value = nightMode;
|
state.value = nightMode;
|
||||||
state.label = mContext.getString(powerSave
|
state.label = mContext.getString(powerSave
|
||||||
? R.string.quick_settings_ui_mode_night_label_battery_saver
|
? R.string.quick_settings_ui_mode_night_label_battery_saver
|
||||||
: R.string.quick_settings_ui_mode_night_label);
|
: R.string.quick_settings_ui_mode_night_label);
|
||||||
state.contentDescription = state.label;
|
|
||||||
state.icon = mIcon;
|
state.icon = mIcon;
|
||||||
state.expandedAccessibilityClassName = Switch.class.getName();
|
state.contentDescription = TextUtils.isEmpty(state.secondaryLabel)
|
||||||
|
? state.label
|
||||||
|
: TextUtils.concat(state.label, ", ", state.secondaryLabel);
|
||||||
if (powerSave) {
|
if (powerSave) {
|
||||||
state.state = Tile.STATE_UNAVAILABLE;
|
state.state = Tile.STATE_UNAVAILABLE;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ import android.service.vr.IVrManager;
|
|||||||
import android.service.vr.IVrStateCallbacks;
|
import android.service.vr.IVrStateCallbacks;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.app.DisableCarModeActivity;
|
import com.android.internal.app.DisableCarModeActivity;
|
||||||
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
|
||||||
import com.android.internal.notification.SystemNotificationChannels;
|
import com.android.internal.notification.SystemNotificationChannels;
|
||||||
@@ -65,6 +65,7 @@ import com.android.internal.util.DumpUtils;
|
|||||||
import com.android.server.twilight.TwilightListener;
|
import com.android.server.twilight.TwilightListener;
|
||||||
import com.android.server.twilight.TwilightManager;
|
import com.android.server.twilight.TwilightManager;
|
||||||
import com.android.server.twilight.TwilightState;
|
import com.android.server.twilight.TwilightState;
|
||||||
|
import com.android.server.wm.WindowManagerInternal;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -72,6 +73,8 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static android.content.Intent.ACTION_SCREEN_OFF;
|
||||||
|
|
||||||
final class UiModeManagerService extends SystemService {
|
final class UiModeManagerService extends SystemService {
|
||||||
private static final String TAG = UiModeManager.class.getSimpleName();
|
private static final String TAG = UiModeManager.class.getSimpleName();
|
||||||
private static final boolean LOG = false;
|
private static final boolean LOG = false;
|
||||||
@@ -85,6 +88,10 @@ final class UiModeManagerService extends SystemService {
|
|||||||
|
|
||||||
private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
|
private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
|
||||||
private int mNightMode = UiModeManager.MODE_NIGHT_NO;
|
private int mNightMode = UiModeManager.MODE_NIGHT_NO;
|
||||||
|
// we use the override auto mode
|
||||||
|
// for example: force night mode off in the night time while in auto mode
|
||||||
|
private int mNightModeOverride = mNightMode;
|
||||||
|
protected static final String OVERRIDE_NIGHT_MODE = Secure.UI_NIGHT_MODE + "_override";
|
||||||
|
|
||||||
private Map<Integer, String> mCarModePackagePriority = new HashMap<>();
|
private Map<Integer, String> mCarModePackagePriority = new HashMap<>();
|
||||||
private boolean mCarModeEnabled = false;
|
private boolean mCarModeEnabled = false;
|
||||||
@@ -119,6 +126,7 @@ final class UiModeManagerService extends SystemService {
|
|||||||
private TwilightManager mTwilightManager;
|
private TwilightManager mTwilightManager;
|
||||||
private NotificationManager mNotificationManager;
|
private NotificationManager mNotificationManager;
|
||||||
private StatusBarManager mStatusBarManager;
|
private StatusBarManager mStatusBarManager;
|
||||||
|
private WindowManagerInternal mWindowManager;
|
||||||
|
|
||||||
private PowerManager.WakeLock mWakeLock;
|
private PowerManager.WakeLock mWakeLock;
|
||||||
|
|
||||||
@@ -128,6 +136,17 @@ final class UiModeManagerService extends SystemService {
|
|||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected UiModeManagerService(Context context, WindowManagerInternal wm,
|
||||||
|
PowerManager.WakeLock wl, TwilightManager tm,
|
||||||
|
boolean setupWizardComplete) {
|
||||||
|
super(context);
|
||||||
|
mWindowManager = wm;
|
||||||
|
mWakeLock = wl;
|
||||||
|
mTwilightManager = tm;
|
||||||
|
mSetupWizardComplete = setupWizardComplete;
|
||||||
|
}
|
||||||
|
|
||||||
private static Intent buildHomeIntent(String category) {
|
private static Intent buildHomeIntent(String category) {
|
||||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||||
intent.addCategory(category);
|
intent.addCategory(category);
|
||||||
@@ -189,8 +208,23 @@ final class UiModeManagerService extends SystemService {
|
|||||||
public void onTwilightStateChanged(@Nullable TwilightState state) {
|
public void onTwilightStateChanged(@Nullable TwilightState state) {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
|
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
|
||||||
updateComputedNightModeLocked();
|
final IntentFilter intentFilter =
|
||||||
updateLocked(0, 0);
|
new IntentFilter(ACTION_SCREEN_OFF);
|
||||||
|
getContext().registerReceiver(mOnScreenOffHandler, intentFilter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final BroadcastReceiver mOnScreenOffHandler = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
updateLocked(0, 0);
|
||||||
|
try {
|
||||||
|
getContext().unregisterReceiver(mOnScreenOffHandler);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// we ignore this exception if the receiver is unregistered already.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,8 +261,10 @@ final class UiModeManagerService extends SystemService {
|
|||||||
private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) {
|
private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange, Uri uri) {
|
public void onChange(boolean selfChange, Uri uri) {
|
||||||
final int mode = Secure.getIntForUser(getContext().getContentResolver(),
|
int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE,
|
||||||
Secure.UI_NIGHT_MODE, mNightMode, 0);
|
mNightMode, 0);
|
||||||
|
mode = mode == UiModeManager.MODE_NIGHT_AUTO
|
||||||
|
? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO;
|
||||||
SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode));
|
SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -247,6 +283,7 @@ final class UiModeManagerService extends SystemService {
|
|||||||
final PowerManager powerManager =
|
final PowerManager powerManager =
|
||||||
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||||
mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
|
mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
|
||||||
|
mWindowManager = LocalServices.getService(WindowManagerInternal.class);
|
||||||
|
|
||||||
// If setup isn't complete for this user listen for completion so we can unblock
|
// If setup isn't complete for this user listen for completion so we can unblock
|
||||||
// being able to send a night mode configuration change event
|
// being able to send a night mode configuration change event
|
||||||
@@ -313,6 +350,16 @@ final class UiModeManagerService extends SystemService {
|
|||||||
false, mDarkThemeObserver, 0);
|
false, mDarkThemeObserver, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected IUiModeManager getService() {
|
||||||
|
return mService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected Configuration getConfiguration() {
|
||||||
|
return mConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
// Records whether setup wizard has happened or not and adds an observer for this user if not.
|
// Records whether setup wizard has happened or not and adds an observer for this user if not.
|
||||||
private void verifySetupWizardCompleted() {
|
private void verifySetupWizardCompleted() {
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
@@ -347,8 +394,11 @@ final class UiModeManagerService extends SystemService {
|
|||||||
if (mSetupWizardComplete) {
|
if (mSetupWizardComplete) {
|
||||||
mNightMode = Secure.getIntForUser(context.getContentResolver(),
|
mNightMode = Secure.getIntForUser(context.getContentResolver(),
|
||||||
Secure.UI_NIGHT_MODE, defaultNightMode, userId);
|
Secure.UI_NIGHT_MODE, defaultNightMode, userId);
|
||||||
|
mNightModeOverride = Secure.getIntForUser(context.getContentResolver(),
|
||||||
|
OVERRIDE_NIGHT_MODE, defaultNightMode, userId);
|
||||||
} else {
|
} else {
|
||||||
mNightMode = defaultNightMode;
|
mNightMode = defaultNightMode;
|
||||||
|
mNightModeOverride = defaultNightMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldNightMode != mNightMode;
|
return oldNightMode != mNightMode;
|
||||||
@@ -474,14 +524,30 @@ final class UiModeManagerService extends SystemService {
|
|||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (mNightMode != mode) {
|
if (mNightMode != mode) {
|
||||||
|
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
|
||||||
|
try {
|
||||||
|
getContext().unregisterReceiver(mOnScreenOffHandler);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// we ignore this exception if the receiver is unregistered already.
|
||||||
|
}
|
||||||
|
}
|
||||||
// Only persist setting if not in car mode
|
// Only persist setting if not in car mode
|
||||||
if (!mCarModeEnabled) {
|
if (!mCarModeEnabled) {
|
||||||
Secure.putIntForUser(getContext().getContentResolver(),
|
Secure.putIntForUser(getContext().getContentResolver(),
|
||||||
Secure.UI_NIGHT_MODE, mode, user);
|
Secure.UI_NIGHT_MODE, mode, user);
|
||||||
|
Secure.putIntForUser(getContext().getContentResolver(),
|
||||||
|
OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
mNightMode = mode;
|
mNightMode = mode;
|
||||||
updateLocked(0, 0);
|
mNightModeOverride = mode;
|
||||||
|
//on screen off will update configuration instead
|
||||||
|
if (mNightMode != UiModeManager.MODE_NIGHT_AUTO) {
|
||||||
|
updateLocked(0, 0);
|
||||||
|
} else {
|
||||||
|
getContext().registerReceiver(
|
||||||
|
mOnScreenOffHandler, new IntentFilter(ACTION_SCREEN_OFF));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -521,6 +587,34 @@ final class UiModeManagerService extends SystemService {
|
|||||||
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
|
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
|
||||||
dumpImpl(pw);
|
dumpImpl(pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setNightModeActivated(boolean active) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
final long ident = Binder.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
|
||||||
|
try {
|
||||||
|
getContext().unregisterReceiver(mOnScreenOffHandler);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
}
|
||||||
|
mNightModeOverride = active
|
||||||
|
? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO;
|
||||||
|
} else if (mNightMode == UiModeManager.MODE_NIGHT_NO
|
||||||
|
&& active) {
|
||||||
|
mNightMode = UiModeManager.MODE_NIGHT_YES;
|
||||||
|
} else if (mNightMode == UiModeManager.MODE_NIGHT_YES
|
||||||
|
&& !active) {
|
||||||
|
mNightMode = UiModeManager.MODE_NIGHT_NO;
|
||||||
|
}
|
||||||
|
updateConfigurationLocked();
|
||||||
|
sendConfigurationLocked();
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
Binder.restoreCallingIdentity(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void dumpImpl(PrintWriter pw) {
|
void dumpImpl(PrintWriter pw) {
|
||||||
@@ -1022,6 +1116,20 @@ final class UiModeManagerService extends SystemService {
|
|||||||
if (state != null) {
|
if (state != null) {
|
||||||
mComputedNightMode = state.isNight();
|
mComputedNightMode = state.isNight();
|
||||||
}
|
}
|
||||||
|
if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) {
|
||||||
|
mComputedNightMode = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) {
|
||||||
|
mComputedNightMode = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mNightModeOverride = mNightMode;
|
||||||
|
final int user = UserHandle.getCallingUserId();
|
||||||
|
Secure.putIntForUser(getContext().getContentResolver(),
|
||||||
|
OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 20019 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.server;
|
||||||
|
|
||||||
|
import android.app.IUiModeManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.testing.AndroidTestingRunner;
|
||||||
|
import android.testing.TestableLooper;
|
||||||
|
import com.android.server.twilight.TwilightManager;
|
||||||
|
import com.android.server.wm.WindowManagerInternal;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static android.app.UiModeManager.MODE_NIGHT_AUTO;
|
||||||
|
import static android.app.UiModeManager.MODE_NIGHT_NO;
|
||||||
|
import static android.app.UiModeManager.MODE_NIGHT_YES;
|
||||||
|
import static junit.framework.TestCase.assertFalse;
|
||||||
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
|
import static org.mockito.BDDMockito.given;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(AndroidTestingRunner.class)
|
||||||
|
@TestableLooper.RunWithLooper
|
||||||
|
public class UiModeManagerServiceTest extends UiServiceTestCase {
|
||||||
|
private UiModeManagerService mUiManagerService;
|
||||||
|
private IUiModeManager mService;
|
||||||
|
@Mock
|
||||||
|
private ContentResolver mContentResolver;
|
||||||
|
@Mock
|
||||||
|
private WindowManagerInternal mWindowManager;
|
||||||
|
@Mock
|
||||||
|
private Context mContext;
|
||||||
|
@Mock
|
||||||
|
private Resources mResources;
|
||||||
|
@Mock
|
||||||
|
TwilightManager mTwilightManager;
|
||||||
|
@Mock
|
||||||
|
PowerManager.WakeLock mWakeLock;
|
||||||
|
private Set<BroadcastReceiver> mScreenOffRecievers;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
mUiManagerService = new UiModeManagerService(mContext, mWindowManager, mWakeLock,
|
||||||
|
mTwilightManager, true);
|
||||||
|
mScreenOffRecievers = new HashSet<>();
|
||||||
|
mService = mUiManagerService.getService();
|
||||||
|
when(mContext.checkCallingOrSelfPermission(anyString()))
|
||||||
|
.thenReturn(PackageManager.PERMISSION_GRANTED);
|
||||||
|
when(mContext.getResources()).thenReturn(mResources);
|
||||||
|
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||||
|
when(mContext.registerReceiver(any(), any())).then(inv -> {
|
||||||
|
mScreenOffRecievers.add(inv.getArgument(0));
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setAutoMode_screenOffRegistered() throws RemoteException {
|
||||||
|
try {
|
||||||
|
mService.setNightMode(MODE_NIGHT_NO);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
mService.setNightMode(MODE_NIGHT_AUTO);
|
||||||
|
verify(mContext).registerReceiver(any(BroadcastReceiver.class), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setAutoMode_screenOffUnRegistered() throws RemoteException {
|
||||||
|
try {
|
||||||
|
mService.setNightMode(MODE_NIGHT_AUTO);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
try {
|
||||||
|
mService.setNightMode(MODE_NIGHT_NO);
|
||||||
|
} catch (SecurityException e) { /*we should ignore this update config exception*/ }
|
||||||
|
given(mContext.registerReceiver(any(), any())).willThrow(SecurityException.class);
|
||||||
|
verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNightModeActive_fromNightModeYesToNoWhenFalse() throws RemoteException {
|
||||||
|
try {
|
||||||
|
mService.setNightMode(MODE_NIGHT_YES);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
try {
|
||||||
|
mService.setNightModeActivated(false);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
assertEquals(MODE_NIGHT_NO, mService.getNightMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNightModeActive_fromNightModeNoToYesWhenTrue() throws RemoteException {
|
||||||
|
try {
|
||||||
|
mService.setNightMode(MODE_NIGHT_NO);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
try {
|
||||||
|
mService.setNightModeActivated(true);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
assertEquals(MODE_NIGHT_YES, mService.getNightMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setNightModeActive_autoNightModeNoChanges() throws RemoteException {
|
||||||
|
try {
|
||||||
|
mService.setNightMode(MODE_NIGHT_AUTO);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
try {
|
||||||
|
mService.setNightModeActivated(true);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
assertEquals(MODE_NIGHT_AUTO, mService.getNightMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isNightModeActive_nightModeYes() throws RemoteException {
|
||||||
|
try {
|
||||||
|
mService.setNightMode(MODE_NIGHT_YES);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
assertTrue(isNightModeActivated());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isNightModeActive_nightModeNo() throws RemoteException {
|
||||||
|
try {
|
||||||
|
mService.setNightMode(MODE_NIGHT_NO);
|
||||||
|
} catch (SecurityException e) { /* we should ignore this update config exception*/ }
|
||||||
|
assertFalse(isNightModeActivated());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNightModeActivated() {
|
||||||
|
return (mUiManagerService.getConfiguration().uiMode
|
||||||
|
& Configuration.UI_MODE_NIGHT_YES) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user