Merge "Keep screen on when user undims it manually" into sc-qpr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
103062f1d8
@@ -96,6 +96,7 @@ public class Notifier {
|
||||
private static final int MSG_BROADCAST_ENHANCED_PREDICTION = 4;
|
||||
private static final int MSG_PROFILE_TIMED_OUT = 5;
|
||||
private static final int MSG_WIRED_CHARGING_STARTED = 6;
|
||||
private static final int MSG_SCREEN_POLICY = 7;
|
||||
|
||||
private static final long[] CHARGING_VIBRATION_TIME = {
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, // ramp-up sampling rate = 40ms
|
||||
@@ -120,6 +121,7 @@ public class Notifier {
|
||||
private final SuspendBlocker mSuspendBlocker;
|
||||
private final WindowManagerPolicy mPolicy;
|
||||
private final FaceDownDetector mFaceDownDetector;
|
||||
private final ScreenUndimDetector mScreenUndimDetector;
|
||||
private final ActivityManagerInternal mActivityManagerInternal;
|
||||
private final InputManagerInternal mInputManagerInternal;
|
||||
private final InputMethodManagerInternal mInputMethodManagerInternal;
|
||||
@@ -167,13 +169,14 @@ public class Notifier {
|
||||
|
||||
public Notifier(Looper looper, Context context, IBatteryStats batteryStats,
|
||||
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
|
||||
FaceDownDetector faceDownDetector) {
|
||||
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
|
||||
mContext = context;
|
||||
mBatteryStats = batteryStats;
|
||||
mAppOps = mContext.getSystemService(AppOpsManager.class);
|
||||
mSuspendBlocker = suspendBlocker;
|
||||
mPolicy = policy;
|
||||
mFaceDownDetector = faceDownDetector;
|
||||
mScreenUndimDetector = screenUndimDetector;
|
||||
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
|
||||
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
|
||||
mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
|
||||
@@ -619,6 +622,22 @@ public class Notifier {
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the screen policy changes.
|
||||
*/
|
||||
public void onScreenPolicyUpdate(int newPolicy) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onScreenPolicyUpdate: newPolicy=" + newPolicy);
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
Message msg = mHandler.obtainMessage(MSG_SCREEN_POLICY);
|
||||
msg.arg1 = newPolicy;
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps data for bugreports.
|
||||
*
|
||||
@@ -659,6 +678,7 @@ public class Notifier {
|
||||
tm.notifyUserActivity();
|
||||
mPolicy.userActivity();
|
||||
mFaceDownDetector.userActivity(event);
|
||||
mScreenUndimDetector.userActivity();
|
||||
}
|
||||
|
||||
void postEnhancedDischargePredictionBroadcast(long delayMs) {
|
||||
@@ -812,6 +832,10 @@ public class Notifier {
|
||||
mSuspendBlocker.release();
|
||||
}
|
||||
|
||||
private void screenPolicyChanging(int screenPolicy) {
|
||||
mScreenUndimDetector.recordScreenPolicy(screenPolicy);
|
||||
}
|
||||
|
||||
private void lockProfile(@UserIdInt int userId) {
|
||||
mTrustManager.setDeviceLockedForUser(userId, true /*locked*/);
|
||||
}
|
||||
@@ -852,6 +876,9 @@ public class Notifier {
|
||||
case MSG_WIRED_CHARGING_STARTED:
|
||||
showWiredChargingStarted(msg.arg1);
|
||||
break;
|
||||
case MSG_SCREEN_POLICY:
|
||||
screenPolicyChanging(msg.arg1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,6 +274,7 @@ public final class PowerManagerService extends SystemService
|
||||
private final BatterySavingStats mBatterySavingStats;
|
||||
private final AttentionDetector mAttentionDetector;
|
||||
private final FaceDownDetector mFaceDownDetector;
|
||||
private final ScreenUndimDetector mScreenUndimDetector;
|
||||
private final BinderService mBinderService;
|
||||
private final LocalService mLocalService;
|
||||
private final NativeWrapper mNativeWrapper;
|
||||
@@ -832,9 +833,10 @@ public final class PowerManagerService extends SystemService
|
||||
static class Injector {
|
||||
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
|
||||
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
|
||||
FaceDownDetector faceDownDetector) {
|
||||
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
|
||||
return new Notifier(
|
||||
looper, context, batteryStats, suspendBlocker, policy, faceDownDetector);
|
||||
looper, context, batteryStats, suspendBlocker, policy, faceDownDetector,
|
||||
screenUndimDetector);
|
||||
}
|
||||
|
||||
SuspendBlocker createSuspendBlocker(PowerManagerService service, String name) {
|
||||
@@ -955,6 +957,7 @@ public final class PowerManagerService extends SystemService
|
||||
mInjector.createAmbientDisplaySuppressionController(context);
|
||||
mAttentionDetector = new AttentionDetector(this::onUserAttention, mLock);
|
||||
mFaceDownDetector = new FaceDownDetector(this::onFlip);
|
||||
mScreenUndimDetector = new ScreenUndimDetector();
|
||||
|
||||
mBatterySavingStats = new BatterySavingStats(mLock);
|
||||
mBatterySaverPolicy =
|
||||
@@ -1141,7 +1144,7 @@ public final class PowerManagerService extends SystemService
|
||||
mBatteryStats = BatteryStatsService.getService();
|
||||
mNotifier = mInjector.createNotifier(Looper.getMainLooper(), mContext, mBatteryStats,
|
||||
mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
|
||||
mPolicy, mFaceDownDetector);
|
||||
mPolicy, mFaceDownDetector, mScreenUndimDetector);
|
||||
|
||||
mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager,
|
||||
mInjector.createSuspendBlocker(
|
||||
@@ -1176,6 +1179,7 @@ public final class PowerManagerService extends SystemService
|
||||
mBatterySaverController.systemReady();
|
||||
mBatterySaverPolicy.systemReady();
|
||||
mFaceDownDetector.systemReady(mContext);
|
||||
mScreenUndimDetector.systemReady(mContext);
|
||||
|
||||
// Register for settings changes.
|
||||
resolver.registerContentObserver(Settings.Secure.getUriFor(
|
||||
@@ -3185,6 +3189,7 @@ public final class PowerManagerService extends SystemService
|
||||
|
||||
final boolean ready = mDisplayManagerInternal.requestPowerState(groupId,
|
||||
displayPowerRequest, mRequestWaitForNegativeProximity);
|
||||
mNotifier.onScreenPolicyUpdate(displayPowerRequest.policy);
|
||||
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "updateDisplayPowerStateLocked: displayReady=" + ready
|
||||
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.power;
|
||||
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DIM;
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF;
|
||||
import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Detects when user manually undims the screen (x times) and acquires a wakelock to keep the screen
|
||||
* on temporarily (without changing the screen timeout setting).
|
||||
*/
|
||||
public class ScreenUndimDetector {
|
||||
private static final String TAG = "ScreenUndimDetector";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static final String UNDIM_DETECTOR_WAKE_LOCK = "UndimDetectorWakeLock";
|
||||
|
||||
/** DeviceConfig flag: is keep screen on feature enabled. */
|
||||
static final String KEY_KEEP_SCREEN_ON_ENABLED = "keep_screen_on_enabled";
|
||||
private static final boolean DEFAULT_KEEP_SCREEN_ON_ENABLED = true;
|
||||
private static final int OUTCOME_POWER_BUTTON =
|
||||
FrameworkStatsLog.TIMEOUT_AUTO_EXTENDED_REPORTED__OUTCOME__POWER_BUTTON;
|
||||
private static final int OUTCOME_TIMEOUT =
|
||||
FrameworkStatsLog.TIMEOUT_AUTO_EXTENDED_REPORTED__OUTCOME__TIMEOUT;
|
||||
private boolean mKeepScreenOnEnabled;
|
||||
|
||||
/** DeviceConfig flag: how long should we keep the screen on. */
|
||||
@VisibleForTesting
|
||||
static final String KEY_KEEP_SCREEN_ON_FOR_MILLIS = "keep_screen_on_for_millis";
|
||||
@VisibleForTesting
|
||||
static final long DEFAULT_KEEP_SCREEN_ON_FOR_MILLIS = TimeUnit.MINUTES.toMillis(10);
|
||||
private long mKeepScreenOnForMillis;
|
||||
|
||||
/** DeviceConfig flag: how many user undims required to trigger keeping the screen on. */
|
||||
@VisibleForTesting
|
||||
static final String KEY_UNDIMS_REQUIRED = "undims_required";
|
||||
@VisibleForTesting
|
||||
static final int DEFAULT_UNDIMS_REQUIRED = 2;
|
||||
private int mUndimsRequired;
|
||||
|
||||
/**
|
||||
* DeviceConfig flag: what is the maximum duration between undims to still consider them
|
||||
* consecutive.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static final String KEY_MAX_DURATION_BETWEEN_UNDIMS_MILLIS =
|
||||
"max_duration_between_undims_millis";
|
||||
@VisibleForTesting
|
||||
static final long DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS = TimeUnit.MINUTES.toMillis(5);
|
||||
private long mMaxDurationBetweenUndimsMillis;
|
||||
|
||||
@VisibleForTesting
|
||||
PowerManager.WakeLock mWakeLock;
|
||||
|
||||
@VisibleForTesting
|
||||
int mCurrentScreenPolicy;
|
||||
@VisibleForTesting
|
||||
int mUndimCounter = 0;
|
||||
@VisibleForTesting
|
||||
long mUndimCounterStartedMillis;
|
||||
private long mUndimOccurredTime = -1;
|
||||
private long mInteractionAfterUndimTime = -1;
|
||||
private InternalClock mClock;
|
||||
|
||||
public ScreenUndimDetector() {
|
||||
mClock = new InternalClock();
|
||||
}
|
||||
|
||||
ScreenUndimDetector(InternalClock clock) {
|
||||
mClock = clock;
|
||||
}
|
||||
|
||||
static class InternalClock {
|
||||
public long getCurrentTime() {
|
||||
return SystemClock.elapsedRealtime();
|
||||
}
|
||||
}
|
||||
|
||||
/** Should be called in parent's systemReady() */
|
||||
public void systemReady(Context context) {
|
||||
readValuesFromDeviceConfig();
|
||||
DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
context.getMainExecutor(),
|
||||
(properties) -> onDeviceConfigChange(properties.getKeyset()));
|
||||
|
||||
final PowerManager powerManager = context.getSystemService(PowerManager.class);
|
||||
mWakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
|
||||
| PowerManager.ON_AFTER_RELEASE,
|
||||
UNDIM_DETECTOR_WAKE_LOCK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a message that figures out the screen transitions and detects user undims. Must be
|
||||
* called by the parent that is trying to update the screen policy.
|
||||
*/
|
||||
public void recordScreenPolicy(int newPolicy) {
|
||||
if (newPolicy == mCurrentScreenPolicy) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG,
|
||||
"Screen policy transition: " + mCurrentScreenPolicy + " -> " + newPolicy);
|
||||
}
|
||||
|
||||
// update the current policy with the new one immediately so we don't accidentally get
|
||||
// into a loop (which is possible if the switch below triggers a new policy).
|
||||
final int currentPolicy = mCurrentScreenPolicy;
|
||||
mCurrentScreenPolicy = newPolicy;
|
||||
|
||||
if (!mKeepScreenOnEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (currentPolicy) {
|
||||
case POLICY_DIM:
|
||||
if (newPolicy == POLICY_BRIGHT) {
|
||||
final long now = mClock.getCurrentTime();
|
||||
final long timeElapsedSinceFirstUndim = now - mUndimCounterStartedMillis;
|
||||
if (timeElapsedSinceFirstUndim >= mMaxDurationBetweenUndimsMillis) {
|
||||
reset();
|
||||
}
|
||||
if (mUndimCounter == 0) {
|
||||
mUndimCounterStartedMillis = now;
|
||||
}
|
||||
|
||||
mUndimCounter++;
|
||||
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "User undim, counter=" + mUndimCounter
|
||||
+ " (required=" + mUndimsRequired + ")"
|
||||
+ ", timeElapsedSinceFirstUndim=" + timeElapsedSinceFirstUndim
|
||||
+ " (max=" + mMaxDurationBetweenUndimsMillis + ")");
|
||||
}
|
||||
if (mUndimCounter >= mUndimsRequired) {
|
||||
reset();
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Acquiring a wake lock for " + mKeepScreenOnForMillis);
|
||||
}
|
||||
if (mWakeLock != null) {
|
||||
mUndimOccurredTime = mClock.getCurrentTime();
|
||||
mWakeLock.acquire(mKeepScreenOnForMillis);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (newPolicy == POLICY_OFF || newPolicy == POLICY_DOZE) {
|
||||
checkAndLogUndim(OUTCOME_TIMEOUT);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
break;
|
||||
case POLICY_BRIGHT:
|
||||
if (newPolicy == POLICY_OFF || newPolicy == POLICY_DOZE) {
|
||||
checkAndLogUndim(OUTCOME_POWER_BUTTON);
|
||||
}
|
||||
if (newPolicy != POLICY_DIM) {
|
||||
reset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void reset() {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Resetting the undim detector");
|
||||
}
|
||||
mUndimCounter = 0;
|
||||
mUndimCounterStartedMillis = 0;
|
||||
if (mWakeLock != null && mWakeLock.isHeld()) {
|
||||
mWakeLock.release();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean readKeepScreenOnNotificationEnabled() {
|
||||
return DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_KEEP_SCREEN_ON_ENABLED,
|
||||
DEFAULT_KEEP_SCREEN_ON_ENABLED);
|
||||
}
|
||||
|
||||
private long readKeepScreenOnForMillis() {
|
||||
return DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_KEEP_SCREEN_ON_FOR_MILLIS,
|
||||
DEFAULT_KEEP_SCREEN_ON_FOR_MILLIS);
|
||||
}
|
||||
|
||||
private int readUndimsRequired() {
|
||||
int undimsRequired = DeviceConfig.getInt(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_UNDIMS_REQUIRED,
|
||||
DEFAULT_UNDIMS_REQUIRED);
|
||||
|
||||
if (undimsRequired < 1 || undimsRequired > 5) {
|
||||
Slog.e(TAG, "Provided undimsRequired=" + undimsRequired
|
||||
+ " is not allowed [1, 5]; using the default=" + DEFAULT_UNDIMS_REQUIRED);
|
||||
return DEFAULT_UNDIMS_REQUIRED;
|
||||
}
|
||||
|
||||
return undimsRequired;
|
||||
}
|
||||
|
||||
private long readMaxDurationBetweenUndimsMillis() {
|
||||
return DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_MAX_DURATION_BETWEEN_UNDIMS_MILLIS,
|
||||
DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS);
|
||||
}
|
||||
|
||||
private void onDeviceConfigChange(@NonNull Set<String> keys) {
|
||||
for (String key : keys) {
|
||||
Slog.i(TAG, "onDeviceConfigChange; key=" + key);
|
||||
switch (key) {
|
||||
case KEY_KEEP_SCREEN_ON_ENABLED:
|
||||
case KEY_KEEP_SCREEN_ON_FOR_MILLIS:
|
||||
case KEY_UNDIMS_REQUIRED:
|
||||
case KEY_MAX_DURATION_BETWEEN_UNDIMS_MILLIS:
|
||||
readValuesFromDeviceConfig();
|
||||
return;
|
||||
default:
|
||||
Slog.i(TAG, "Ignoring change on " + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void readValuesFromDeviceConfig() {
|
||||
mKeepScreenOnEnabled = readKeepScreenOnNotificationEnabled();
|
||||
mKeepScreenOnForMillis = readKeepScreenOnForMillis();
|
||||
mUndimsRequired = readUndimsRequired();
|
||||
mMaxDurationBetweenUndimsMillis = readMaxDurationBetweenUndimsMillis();
|
||||
|
||||
Slog.i(TAG, "readValuesFromDeviceConfig():"
|
||||
+ "\nmKeepScreenOnForMillis=" + mKeepScreenOnForMillis
|
||||
+ "\nmKeepScreenOnNotificationEnabled=" + mKeepScreenOnEnabled
|
||||
+ "\nmUndimsRequired=" + mUndimsRequired);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The user interacted with the screen after an undim, indicating the phone is in use.
|
||||
* We use this event for logging.
|
||||
*/
|
||||
public void userActivity() {
|
||||
if (mUndimOccurredTime != 1 && mInteractionAfterUndimTime == -1) {
|
||||
mInteractionAfterUndimTime = mClock.getCurrentTime();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks and logs if an undim occurred.
|
||||
*
|
||||
* A log will occur if an undim seems to have resulted in a timeout or a direct screen off such
|
||||
* as from a power button. Some outcomes may not be correctly assigned to a
|
||||
* TIMEOUT_AUTO_EXTENDED_REPORTED__OUTCOME value.
|
||||
*/
|
||||
private void checkAndLogUndim(int outcome) {
|
||||
if (mUndimOccurredTime != -1) {
|
||||
long now = mClock.getCurrentTime();
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.TIMEOUT_AUTO_EXTENDED_REPORTED,
|
||||
outcome,
|
||||
/* time_to_outcome_millis=*/ now - mUndimOccurredTime,
|
||||
/* time_to_first_interaction_millis= */
|
||||
mInteractionAfterUndimTime != -1 ? now - mInteractionAfterUndimTime : -1
|
||||
);
|
||||
mUndimOccurredTime = -1;
|
||||
mInteractionAfterUndimTime = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@
|
||||
<uses-permission android:name="android.permission.MANAGE_APPOPS"/>
|
||||
<uses-permission android:name="android.permission.MONITOR_DEVICE_CONFIG_ACCESS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission
|
||||
android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.power;
|
||||
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DIM;
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF;
|
||||
import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_VR;
|
||||
import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
|
||||
|
||||
import static com.android.server.power.ScreenUndimDetector.DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS;
|
||||
import static com.android.server.power.ScreenUndimDetector.KEY_KEEP_SCREEN_ON_ENABLED;
|
||||
import static com.android.server.power.ScreenUndimDetector.KEY_MAX_DURATION_BETWEEN_UNDIMS_MILLIS;
|
||||
import static com.android.server.power.ScreenUndimDetector.KEY_UNDIMS_REQUIRED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.testing.TestableContext;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import com.android.server.testables.TestableDeviceConfig;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Tests for {@link com.android.server.power.ScreenUndimDetector}
|
||||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class ScreenUndimDetectorTest {
|
||||
private static final List<Integer> ALL_POLICIES =
|
||||
Arrays.asList(POLICY_OFF,
|
||||
POLICY_DOZE,
|
||||
POLICY_DIM,
|
||||
POLICY_BRIGHT,
|
||||
POLICY_VR);
|
||||
|
||||
@ClassRule
|
||||
public static final TestableContext sContext = new TestableContext(
|
||||
InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
|
||||
@Rule
|
||||
public TestableDeviceConfig.TestableDeviceConfigRule
|
||||
mDeviceConfigRule = new TestableDeviceConfig.TestableDeviceConfigRule();
|
||||
|
||||
private ScreenUndimDetector mScreenUndimDetector;
|
||||
|
||||
private final TestClock mClock = new TestClock();
|
||||
|
||||
private static class TestClock extends ScreenUndimDetector.InternalClock {
|
||||
long mCurrentTime = 0;
|
||||
@Override
|
||||
public long getCurrentTime() {
|
||||
return mCurrentTime;
|
||||
}
|
||||
|
||||
public void advanceTime(long millisAdvanced) {
|
||||
mCurrentTime += millisAdvanced;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_UNDIMS_REQUIRED,
|
||||
Integer.toString(1), false /*makeDefault*/);
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_MAX_DURATION_BETWEEN_UNDIMS_MILLIS,
|
||||
Long.toString(DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS),
|
||||
false /*makeDefault*/);
|
||||
|
||||
mScreenUndimDetector = new ScreenUndimDetector(mClock);
|
||||
mScreenUndimDetector.systemReady(sContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_disabledByFlag_noop() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_KEEP_SCREEN_ON_ENABLED, Boolean.FALSE.toString(), false /*makeDefault*/);
|
||||
|
||||
setup();
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_samePolicy_noop() {
|
||||
for (int policy : ALL_POLICIES) {
|
||||
setup();
|
||||
mScreenUndimDetector.recordScreenPolicy(policy);
|
||||
mScreenUndimDetector.recordScreenPolicy(policy);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_dimToBright_extends() {
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_otherTransitions_doesNotExtend() {
|
||||
for (int from : ALL_POLICIES) {
|
||||
for (int to : ALL_POLICIES) {
|
||||
if (from == POLICY_DIM && to == POLICY_BRIGHT) {
|
||||
continue;
|
||||
}
|
||||
setup();
|
||||
mScreenUndimDetector.recordScreenPolicy(from);
|
||||
mScreenUndimDetector.recordScreenPolicy(to);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
assertThat(mScreenUndimDetector.mUndimCounter).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_dimToBright_twoUndimsNeeded_extends() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_UNDIMS_REQUIRED,
|
||||
Integer.toString(2), false /*makeDefault*/);
|
||||
mScreenUndimDetector.readValuesFromDeviceConfig();
|
||||
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_dimBrightDimOff_resetsCounter_doesNotExtend() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_UNDIMS_REQUIRED,
|
||||
Integer.toString(2), false /*makeDefault*/);
|
||||
mScreenUndimDetector.readValuesFromDeviceConfig();
|
||||
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_OFF);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
assertThat(mScreenUndimDetector.mUndimCounter).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_undimToOff_resetsCounter() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_UNDIMS_REQUIRED,
|
||||
Integer.toString(2), false /*makeDefault*/);
|
||||
mScreenUndimDetector.readValuesFromDeviceConfig();
|
||||
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_OFF);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
assertThat(mScreenUndimDetector.mUndimCounter).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_undimOffUndim_doesNotExtend() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_UNDIMS_REQUIRED,
|
||||
Integer.toString(2), false /*makeDefault*/);
|
||||
mScreenUndimDetector.readValuesFromDeviceConfig();
|
||||
|
||||
// undim
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
// off
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_OFF);
|
||||
// second undim
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
assertThat(mScreenUndimDetector.mUndimCounter).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_dimToBright_tooFarApart_doesNotExtend() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_UNDIMS_REQUIRED,
|
||||
Integer.toString(2), false /*makeDefault*/);
|
||||
mScreenUndimDetector.readValuesFromDeviceConfig();
|
||||
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
|
||||
mClock.advanceTime(DEFAULT_MAX_DURATION_BETWEEN_UNDIMS_MILLIS + 5);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
assertThat(mScreenUndimDetector.mUndimCounter).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_dimToNonBright_resets() {
|
||||
for (int to : Arrays.asList(POLICY_OFF, POLICY_DOZE, POLICY_VR)) {
|
||||
setup();
|
||||
mScreenUndimDetector.mUndimCounter = 1;
|
||||
mScreenUndimDetector.mUndimCounterStartedMillis = 123;
|
||||
mScreenUndimDetector.mWakeLock.acquire();
|
||||
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_DIM);
|
||||
mScreenUndimDetector.recordScreenPolicy(to);
|
||||
|
||||
assertThat(mScreenUndimDetector.mUndimCounter).isEqualTo(0);
|
||||
assertThat(mScreenUndimDetector.mUndimCounterStartedMillis).isEqualTo(0);
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_brightToNonDim_resets() {
|
||||
for (int to : Arrays.asList(POLICY_OFF, POLICY_DOZE, POLICY_VR)) {
|
||||
setup();
|
||||
mScreenUndimDetector.mUndimCounter = 1;
|
||||
mScreenUndimDetector.mUndimCounterStartedMillis = 123;
|
||||
mScreenUndimDetector.mWakeLock.acquire();
|
||||
|
||||
mScreenUndimDetector.recordScreenPolicy(POLICY_BRIGHT);
|
||||
mScreenUndimDetector.recordScreenPolicy(to);
|
||||
|
||||
assertThat(mScreenUndimDetector.mUndimCounter).isEqualTo(0);
|
||||
assertThat(mScreenUndimDetector.mUndimCounterStartedMillis).isEqualTo(0);
|
||||
assertThat(mScreenUndimDetector.mWakeLock.isHeld()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void recordScreenPolicy_otherTransitions_doesNotReset() {
|
||||
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
|
||||
KEY_UNDIMS_REQUIRED,
|
||||
Integer.toString(3),
|
||||
false /*makeDefault*/);
|
||||
mScreenUndimDetector.readValuesFromDeviceConfig();
|
||||
|
||||
for (int from : ALL_POLICIES) {
|
||||
for (int to : ALL_POLICIES) {
|
||||
if (from == POLICY_DIM && to != POLICY_BRIGHT) {
|
||||
continue;
|
||||
}
|
||||
if (from == POLICY_BRIGHT && to != POLICY_DIM) {
|
||||
continue;
|
||||
}
|
||||
mScreenUndimDetector.mCurrentScreenPolicy = POLICY_OFF;
|
||||
mScreenUndimDetector.mUndimCounter = 1;
|
||||
mScreenUndimDetector.mUndimCounterStartedMillis =
|
||||
SystemClock.currentThreadTimeMillis();
|
||||
|
||||
mScreenUndimDetector.recordScreenPolicy(from);
|
||||
mScreenUndimDetector.recordScreenPolicy(to);
|
||||
|
||||
assertThat(mScreenUndimDetector.mUndimCounter).isNotEqualTo(0);
|
||||
assertThat(mScreenUndimDetector.mUndimCounterStartedMillis).isNotEqualTo(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,7 +210,7 @@ public class NotifierTest {
|
||||
@Override
|
||||
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
|
||||
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
|
||||
FaceDownDetector faceDownDetector) {
|
||||
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
|
||||
return mNotifierMock;
|
||||
}
|
||||
|
||||
@@ -298,6 +298,7 @@ public class NotifierTest {
|
||||
BatteryStats.SERVICE_NAME)),
|
||||
mInjector.createSuspendBlocker(mService, "testBlocker"),
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ public class PowerManagerServiceTest {
|
||||
@Override
|
||||
Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
|
||||
SuspendBlocker suspendBlocker, WindowManagerPolicy policy,
|
||||
FaceDownDetector faceDownDetector) {
|
||||
FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector) {
|
||||
return mNotifierMock;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user