Merge "Add a flag to allow extending the check post dim"

This commit is contained in:
Alex Salo
2019-12-03 21:07:23 +00:00
committed by Android (Google) Code Review
5 changed files with 178 additions and 31 deletions

View File

@@ -2148,8 +2148,6 @@
<integer name="config_dreamsBatteryLevelDrainCutoff">5</integer>
<!-- Limit of how long the device can remain unlocked due to attention checking. -->
<integer name="config_attentionMaximumExtension">330000</integer> <!-- 5 minutes and 30 sec.-->
<!-- How long we should wait until we give up on receiving an attention API callback. -->
<integer name="config_attentionApiTimeout">2000</integer> <!-- 2 seconds -->
<!-- ComponentName of a dream to show whenever the system would otherwise have
gone to sleep. When the PowerManager is asked to go to sleep, it will instead

View File

@@ -3645,7 +3645,6 @@
<!-- For Attention Service -->
<java-symbol type="integer" name="config_attentionMaximumExtension" />
<java-symbol type="integer" name="config_attentionApiTimeout" />
<java-symbol type="string" name="config_incidentReportApproverPackage" />
<java-symbol type="array" name="config_restrictedImagesServices" />

View File

@@ -16,6 +16,7 @@
package com.android.server.power;
import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
import static android.provider.Settings.System.ADAPTIVE_SLEEP;
import android.Manifest;
@@ -33,6 +34,7 @@ import android.os.PowerManagerInternal;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.attention.AttentionService;
import android.util.Slog;
@@ -58,6 +60,22 @@ public class AttentionDetector {
private static final String TAG = "AttentionDetector";
private static final boolean DEBUG = false;
/**
* DeviceConfig flag name, describes how much in advance to start checking attention before the
* dim event.
*/
static final String KEY_PRE_DIM_CHECK_DURATION_MILLIS = "pre_dim_check_duration_millis";
/** Default value in absence of {@link DeviceConfig} override. */
static final long DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS = 2_000;
/** DeviceConfig flag name, describes how long to run the check beyond the screen dim event. */
static final String KEY_POST_DIM_CHECK_DURATION_MILLIS =
"post_dim_check_duration_millis";
/** Default value in absence of {@link DeviceConfig} override. */
static final long DEFAULT_POST_DIM_CHECK_DURATION_MILLIS = 0;
private Context mContext;
private boolean mIsSettingEnabled;
@@ -89,11 +107,6 @@ public class AttentionDetector {
@VisibleForTesting
protected int mRequestId;
/**
* {@link android.service.attention.AttentionService} API timeout.
*/
private long mMaxAttentionApiTimeoutMillis;
/**
* Last known user activity.
*/
@@ -124,6 +137,9 @@ public class AttentionDetector {
@VisibleForTesting
AttentionCallbackInternalImpl mCallback;
/** Keep the last used post dim timeout for the dumpsys. */
private long mLastPostDimTimeout;
public AttentionDetector(Runnable onUserAttention, Object lock) {
mOnUserAttention = onUserAttention;
mLock = lock;
@@ -149,8 +165,6 @@ public class AttentionDetector {
mWindowManager = LocalServices.getService(WindowManagerInternal.class);
mMaximumExtensionMillis = context.getResources().getInteger(
com.android.internal.R.integer.config_attentionMaximumExtension);
mMaxAttentionApiTimeoutMillis = context.getResources().getInteger(
com.android.internal.R.integer.config_attentionApiTimeout);
try {
final UserSwitchObserver observer = new UserSwitchObserver();
@@ -169,7 +183,8 @@ public class AttentionDetector {
}, UserHandle.USER_ALL);
}
public long updateUserActivity(long nextScreenDimming) {
/** To be called in {@link PowerManagerService#updateUserActivitySummaryLocked}. */
public long updateUserActivity(long nextScreenDimming, long dimDurationMillis) {
if (nextScreenDimming == mLastActedOnNextScreenDimming
|| !mIsSettingEnabled
|| mWindowManager.isKeyguardShowingAndNotOccluded()) {
@@ -184,7 +199,7 @@ public class AttentionDetector {
}
final long now = SystemClock.uptimeMillis();
final long whenToCheck = nextScreenDimming - getAttentionTimeout();
final long whenToCheck = nextScreenDimming - getPreDimCheckDurationMillis();
final long whenToStopExtending = mLastUserActivityTime + mMaximumExtensionMillis;
if (now < whenToCheck) {
if (DEBUG) {
@@ -213,7 +228,9 @@ public class AttentionDetector {
mLastActedOnNextScreenDimming = nextScreenDimming;
mCallback = new AttentionCallbackInternalImpl(mRequestId);
Slog.v(TAG, "Checking user attention, ID: " + mRequestId);
final boolean sent = mAttentionManager.checkAttention(getAttentionTimeout(), mCallback);
final boolean sent = mAttentionManager.checkAttention(
getPreDimCheckDurationMillis() + getPostDimCheckDurationMillis(dimDurationMillis),
mCallback);
if (!sent) {
mRequested.set(false);
}
@@ -272,11 +289,6 @@ public class AttentionDetector {
}
}
@VisibleForTesting
long getAttentionTimeout() {
return mMaxAttentionApiTimeoutMillis;
}
/**
* {@see AttentionManagerInternal#isAttentionServiceSupported}
*/
@@ -301,12 +313,44 @@ public class AttentionDetector {
pw.println("AttentionDetector:");
pw.println(" mIsSettingEnabled=" + mIsSettingEnabled);
pw.println(" mMaximumExtensionMillis=" + mMaximumExtensionMillis);
pw.println(" mMaxAttentionApiTimeoutMillis=" + mMaxAttentionApiTimeoutMillis);
pw.println(" preDimCheckDurationMillis=" + getPreDimCheckDurationMillis());
pw.println(" postDimCheckDurationMillis=" + mLastPostDimTimeout);
pw.println(" mLastUserActivityTime(excludingAttention)=" + mLastUserActivityTime);
pw.println(" mAttentionServiceSupported=" + isAttentionServiceSupported());
pw.println(" mRequested=" + mRequested);
}
/** How long to check <b>before</b> the screen dims, capped at the dim duration. */
@VisibleForTesting
protected long getPreDimCheckDurationMillis() {
final long millis = DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_PRE_DIM_CHECK_DURATION_MILLIS,
DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS);
if (millis < 0 || millis > 13_000) {
Slog.w(TAG, "Bad flag value supplied for: " + KEY_PRE_DIM_CHECK_DURATION_MILLIS);
return DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS;
}
return millis;
}
/** How long to check <b>after</b> the screen dims, capped at the dim duration. */
@VisibleForTesting
protected long getPostDimCheckDurationMillis(long dimDurationMillis) {
final long millis = DeviceConfig.getLong(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_POST_DIM_CHECK_DURATION_MILLIS,
DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
if (millis < 0 || millis > 10_000) {
Slog.w(TAG, "Bad flag value supplied for: " + KEY_POST_DIM_CHECK_DURATION_MILLIS);
return DEFAULT_POST_DIM_CHECK_DURATION_MILLIS;
}
mLastPostDimTimeout = Math.min(millis, dimDurationMillis);
return mLastPostDimTimeout;
}
@VisibleForTesting
final class AttentionCallbackInternalImpl extends AttentionCallbackInternal {
private final int mId;

View File

@@ -2140,9 +2140,11 @@ public final class PowerManagerService extends SystemService
nextTimeout = -1;
}
if ((mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
if (((mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
|| (mUserActivitySummary & USER_ACTIVITY_SCREEN_DIM) != 0)
&& (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) == 0) {
nextTimeout = mAttentionDetector.updateUserActivity(nextTimeout);
nextTimeout = mAttentionDetector.updateUserActivity(nextTimeout,
screenDimDuration);
}
if (nextProfileTimeout > 0) {

View File

@@ -17,6 +17,12 @@
package com.android.server.power;
import static android.os.BatteryStats.Uid.NUM_USER_ACTIVITY_TYPES;
import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
import static com.android.server.power.AttentionDetector.DEFAULT_POST_DIM_CHECK_DURATION_MILLIS;
import static com.android.server.power.AttentionDetector.DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS;
import static com.android.server.power.AttentionDetector.KEY_POST_DIM_CHECK_DURATION_MILLIS;
import static com.android.server.power.AttentionDetector.KEY_PRE_DIM_CHECK_DURATION_MILLIS;
import static com.google.common.truth.Truth.assertThat;
@@ -37,6 +43,7 @@ import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.attention.AttentionService;
import android.test.AndroidTestCase;
@@ -53,6 +60,7 @@ import org.mockito.MockitoAnnotations;
@SmallTest
public class AttentionDetectorTest extends AndroidTestCase {
private static final long DEFAULT_DIM_DURATION_MILLIS = 6_000L;
@Mock
private PackageManager mPackageManager;
@@ -63,7 +71,8 @@ public class AttentionDetectorTest extends AndroidTestCase {
@Mock
private Runnable mOnUserAttention;
private TestableAttentionDetector mAttentionDetector;
private long mAttentionTimeout;
private AttentionDetector mRealAttentionDetector;
private long mPreDimCheckDuration;
private long mNextDimming;
private int mIsSettingEnabled;
@@ -77,6 +86,7 @@ public class AttentionDetectorTest extends AndroidTestCase {
.thenReturn(true);
when(mWindowManagerInternal.isKeyguardShowingAndNotOccluded()).thenReturn(false);
mAttentionDetector = new TestableAttentionDetector();
mRealAttentionDetector = new AttentionDetector(mOnUserAttention, new Object());
mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_AWAKE);
mAttentionDetector.setAttentionServiceSupported(true);
mNextDimming = SystemClock.uptimeMillis() + 3000L;
@@ -94,6 +104,13 @@ public class AttentionDetectorTest extends AndroidTestCase {
public void tearDown() {
Settings.System.putIntForUser(getContext().getContentResolver(),
Settings.System.ADAPTIVE_SLEEP, mIsSettingEnabled, UserHandle.USER_CURRENT);
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_PRE_DIM_CHECK_DURATION_MILLIS,
Long.toString(DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS), false);
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_POST_DIM_CHECK_DURATION_MILLIS,
Long.toString(DEFAULT_POST_DIM_CHECK_DURATION_MILLIS), false);
}
@Test
@@ -175,7 +192,7 @@ public class AttentionDetectorTest extends AndroidTestCase {
long now = SystemClock.uptimeMillis();
mNextDimming = now;
mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
mAttentionDetector.updateUserActivity(mNextDimming + 5000L);
mAttentionDetector.updateUserActivity(mNextDimming + 5000L, DEFAULT_DIM_DURATION_MILLIS);
verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
}
@@ -184,7 +201,8 @@ public class AttentionDetectorTest extends AndroidTestCase {
long now = SystemClock.uptimeMillis();
mNextDimming = now;
mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
long nextTimeout = mAttentionDetector.updateUserActivity(mNextDimming + 5000L);
long nextTimeout = mAttentionDetector.updateUserActivity(mNextDimming + 5000L,
DEFAULT_DIM_DURATION_MILLIS);
assertThat(nextTimeout).isEqualTo(mNextDimming + 5000L);
}
@@ -192,7 +210,7 @@ public class AttentionDetectorTest extends AndroidTestCase {
public void testOnUserActivity_ignoresAfterMaximumExtension() {
long now = SystemClock.uptimeMillis();
mAttentionDetector.onUserActivity(now - 15000L, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
mAttentionDetector.updateUserActivity(now + 2000L);
mAttentionDetector.updateUserActivity(now + 2000L, DEFAULT_DIM_DURATION_MILLIS);
verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
}
@@ -203,7 +221,8 @@ public class AttentionDetectorTest extends AndroidTestCase {
assertThat(when).isLessThan(mNextDimming);
clearInvocations(mAttentionManagerInternal);
long redundantWhen = mAttentionDetector.updateUserActivity(mNextDimming);
long redundantWhen = mAttentionDetector.updateUserActivity(mNextDimming,
DEFAULT_DIM_DURATION_MILLIS);
assertThat(redundantWhen).isEqualTo(mNextDimming);
verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
}
@@ -212,7 +231,8 @@ public class AttentionDetectorTest extends AndroidTestCase {
public void testOnUserActivity_skipsIfAlreadyScheduled() {
registerAttention();
reset(mAttentionManagerInternal);
long when = mAttentionDetector.updateUserActivity(mNextDimming + 1);
long when = mAttentionDetector.updateUserActivity(mNextDimming + 1,
DEFAULT_DIM_DURATION_MILLIS);
verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
assertThat(when).isLessThan(mNextDimming);
}
@@ -300,11 +320,95 @@ public class AttentionDetectorTest extends AndroidTestCase {
verify(mOnUserAttention, never()).run();
}
@Test
public void testGetPreDimCheckDurationMillis_handlesGoodFlagValue() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_PRE_DIM_CHECK_DURATION_MILLIS, "555", false);
assertThat(mRealAttentionDetector.getPreDimCheckDurationMillis()).isEqualTo(555);
}
@Test
public void testGetPreDimCheckDurationMillis_rejectsNegativeValue() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_PRE_DIM_CHECK_DURATION_MILLIS, "-50", false);
assertThat(mRealAttentionDetector.getPreDimCheckDurationMillis()).isEqualTo(
DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS);
}
@Test
public void testGetPreDimCheckDurationMillis_rejectsTooBigValue() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_PRE_DIM_CHECK_DURATION_MILLIS, "20000", false);
assertThat(mRealAttentionDetector.getPreDimCheckDurationMillis()).isEqualTo(
DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS);
}
@Test
public void testGetPreDimCheckDurationMillis_handlesBadFlagValue() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_PRE_DIM_CHECK_DURATION_MILLIS, "20000k", false);
assertThat(mRealAttentionDetector.getPreDimCheckDurationMillis()).isEqualTo(
DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS);
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_PRE_DIM_CHECK_DURATION_MILLIS, "0.25", false);
assertThat(mRealAttentionDetector.getPreDimCheckDurationMillis()).isEqualTo(
DEFAULT_PRE_DIM_CHECK_DURATION_MILLIS);
}
@Test
public void testGetPostDimCheckDurationMillis_handlesGoodFlagValue() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_POST_DIM_CHECK_DURATION_MILLIS, "333", false);
assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(333);
}
@Test
public void testGetPostDimCheckDurationMillis_capsGoodFlagValueByMaxDimDuration() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_POST_DIM_CHECK_DURATION_MILLIS, "7000", false);
assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(6500)).isEqualTo(6500);
}
@Test
public void testGetPostDimCheckDurationMillis_rejectsNegativeValue() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_POST_DIM_CHECK_DURATION_MILLIS, "-50", false);
assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(
DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
}
@Test
public void testGetPostDimCheckDurationMillis_rejectsTooBigValue() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_POST_DIM_CHECK_DURATION_MILLIS, "20000", false);
assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(
DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
}
@Test
public void testGetPostDimCheckDurationMillis_handlesBadFlagValue() {
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_POST_DIM_CHECK_DURATION_MILLIS, "20000k", false);
assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(
DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
DeviceConfig.setProperty(NAMESPACE_ATTENTION_MANAGER_SERVICE,
KEY_POST_DIM_CHECK_DURATION_MILLIS, "0.25", false);
assertThat(mRealAttentionDetector.getPostDimCheckDurationMillis(
DEFAULT_DIM_DURATION_MILLIS)).isEqualTo(
DEFAULT_POST_DIM_CHECK_DURATION_MILLIS);
}
private long registerAttention() {
mAttentionTimeout = 4000L;
mPreDimCheckDuration = 4000L;
mAttentionDetector.onUserActivity(SystemClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_TOUCH);
return mAttentionDetector.updateUserActivity(mNextDimming);
return mAttentionDetector.updateUserActivity(mNextDimming, DEFAULT_DIM_DURATION_MILLIS);
}
private class TestableAttentionDetector extends AttentionDetector {
@@ -329,8 +433,8 @@ public class AttentionDetectorTest extends AndroidTestCase {
}
@Override
public long getAttentionTimeout() {
return mAttentionTimeout;
public long getPreDimCheckDurationMillis() {
return mPreDimCheckDuration;
}
}
}