2 * Copyright (C) 2019 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.power;
19 import static android.os.BatteryStats.Uid.NUM_USER_ACTIVITY_TYPES;
21 import static com.google.common.truth.Truth.assertThat;
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.anyLong;
25 import static org.mockito.Mockito.atMost;
26 import static org.mockito.Mockito.clearInvocations;
27 import static org.mockito.Mockito.doAnswer;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.reset;
30 import static org.mockito.Mockito.verify;
31 import static org.mockito.Mockito.when;
33 import android.attention.AttentionManagerInternal;
34 import android.attention.AttentionManagerInternal.AttentionCallbackInternal;
35 import android.content.pm.PackageManager;
36 import android.os.PowerManager;
37 import android.os.PowerManagerInternal;
38 import android.os.SystemClock;
39 import android.os.UserHandle;
40 import android.provider.Settings;
41 import android.service.attention.AttentionService;
42 import android.test.AndroidTestCase;
43 import android.test.suitebuilder.annotation.SmallTest;
45 import com.android.server.wm.WindowManagerInternal;
47 import org.junit.After;
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.mockito.ArgumentCaptor;
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
55 public class AttentionDetectorTest extends AndroidTestCase {
58 private PackageManager mPackageManager;
60 private AttentionManagerInternal mAttentionManagerInternal;
62 private WindowManagerInternal mWindowManagerInternal;
64 private Runnable mOnUserAttention;
65 private TestableAttentionDetector mAttentionDetector;
66 private long mAttentionTimeout;
67 private long mNextDimming;
68 private int mIsSettingEnabled;
72 MockitoAnnotations.initMocks(this);
73 when(mPackageManager.getAttentionServicePackageName()).thenReturn("com.google.android.as");
74 when(mPackageManager.checkPermission(any(), any())).thenReturn(
75 PackageManager.PERMISSION_GRANTED);
76 when(mAttentionManagerInternal.checkAttention(anyLong(), any()))
78 when(mWindowManagerInternal.isKeyguardShowingAndNotOccluded()).thenReturn(false);
79 mAttentionDetector = new TestableAttentionDetector();
80 mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_AWAKE);
81 mAttentionDetector.setAttentionServiceSupported(true);
82 mNextDimming = SystemClock.uptimeMillis() + 3000L;
84 // Save the existing state.
85 mIsSettingEnabled = Settings.System.getIntForUser(getContext().getContentResolver(),
86 Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT);
88 Settings.System.putIntForUser(getContext().getContentResolver(),
89 Settings.System.ADAPTIVE_SLEEP, 1, UserHandle.USER_CURRENT);
90 mAttentionDetector.updateEnabledFromSettings(getContext());
94 public void tearDown() {
95 Settings.System.putIntForUser(getContext().getContentResolver(),
96 Settings.System.ADAPTIVE_SLEEP, mIsSettingEnabled, UserHandle.USER_CURRENT);
100 public void testOnUserActivity_checksAttention() {
101 long when = registerAttention();
102 verify(mAttentionManagerInternal).checkAttention(anyLong(), any());
103 assertThat(when).isLessThan(mNextDimming);
107 public void testOnUserActivity_doesntCheckIfNotEnabled() {
108 Settings.System.putIntForUser(getContext().getContentResolver(),
109 Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT);
110 mAttentionDetector.updateEnabledFromSettings(getContext());
111 long when = registerAttention();
112 verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
113 assertThat(mNextDimming).isEqualTo(when);
117 public void testOnUserActivity_doesntCheckIfNotSupported() {
118 mAttentionDetector.setAttentionServiceSupported(false);
119 long when = registerAttention();
120 verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
121 assertThat(mNextDimming).isEqualTo(when);
125 public void testOnUserActivity_doesntCheckIfInLockscreen() {
126 when(mWindowManagerInternal.isKeyguardShowingAndNotOccluded()).thenReturn(true);
128 long when = registerAttention();
129 verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
130 assertThat(mNextDimming).isEqualTo(when);
134 public void testOnUserActivity_doesntCheckIfNotSufficientPermissions() {
135 when(mPackageManager.checkPermission(any(), any())).thenReturn(
136 PackageManager.PERMISSION_DENIED);
138 long when = registerAttention();
139 verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
140 assertThat(mNextDimming).isEqualTo(when);
144 public void testOnUserActivity_disablesSettingIfNotSufficientPermissions() {
145 when(mPackageManager.checkPermission(any(), any())).thenReturn(
146 PackageManager.PERMISSION_DENIED);
149 boolean enabled = Settings.System.getIntForUser(getContext().getContentResolver(),
150 Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT) == 1;
151 assertFalse(enabled);
155 public void testOnUserActivity_doesntCrashIfNoAttentionService() {
156 mAttentionManagerInternal = null;
162 public void onUserActivity_ignoresWhiteListedActivityTypes() {
163 for (int i = 0; i < NUM_USER_ACTIVITY_TYPES; i++) {
164 int result = mAttentionDetector.onUserActivity(SystemClock.uptimeMillis(), i);
166 throw new AssertionError("User activity " + i + " isn't listed in"
167 + " AttentionDetector#onUserActivity. Please consider how this new activity"
168 + " type affects the attention service.");
174 public void testUpdateUserActivity_ignoresWhenItsNotTimeYet() {
175 long now = SystemClock.uptimeMillis();
177 mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
178 mAttentionDetector.updateUserActivity(mNextDimming + 5000L);
179 verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
183 public void testUpdateUserActivity_schedulesTheNextCheck() {
184 long now = SystemClock.uptimeMillis();
186 mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
187 long nextTimeout = mAttentionDetector.updateUserActivity(mNextDimming + 5000L);
188 assertThat(nextTimeout).isEqualTo(mNextDimming + 5000L);
192 public void testOnUserActivity_ignoresAfterMaximumExtension() {
193 long now = SystemClock.uptimeMillis();
194 mAttentionDetector.onUserActivity(now - 15000L, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
195 mAttentionDetector.updateUserActivity(now + 2000L);
196 verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
200 public void testOnUserActivity_ignoresIfAlreadyDoneForThatNextScreenDimming() {
201 long when = registerAttention();
202 verify(mAttentionManagerInternal).checkAttention(anyLong(), any());
203 assertThat(when).isLessThan(mNextDimming);
204 clearInvocations(mAttentionManagerInternal);
206 long redundantWhen = mAttentionDetector.updateUserActivity(mNextDimming);
207 assertThat(redundantWhen).isEqualTo(mNextDimming);
208 verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
212 public void testOnUserActivity_skipsIfAlreadyScheduled() {
214 reset(mAttentionManagerInternal);
215 long when = mAttentionDetector.updateUserActivity(mNextDimming + 1);
216 verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
217 assertThat(when).isLessThan(mNextDimming);
221 public void testOnWakefulnessChangeStarted_cancelsRequestWhenNotAwake() {
223 mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_ASLEEP);
225 ArgumentCaptor<AttentionCallbackInternal> callbackCaptor = ArgumentCaptor.forClass(
226 AttentionCallbackInternal.class);
227 verify(mAttentionManagerInternal).cancelAttentionCheck(callbackCaptor.capture());
228 assertEquals(callbackCaptor.getValue(), mAttentionDetector.mCallback);
232 public void testCallbackOnSuccess_ignoresIfNoAttention() {
234 mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_ABSENT,
235 SystemClock.uptimeMillis());
236 verify(mOnUserAttention, never()).run();
240 public void testCallbackOnSuccess_callsCallback() {
242 mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
243 SystemClock.uptimeMillis());
244 verify(mOnUserAttention).run();
248 public void testCallbackOnSuccess_doesNotCallNonCurrentCallback() {
249 mAttentionDetector.mRequestId = 5;
250 registerAttention(); // mRequestId = 6;
251 mAttentionDetector.mRequestId = 55;
253 mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
254 SystemClock.uptimeMillis());
255 verify(mOnUserAttention, never()).run();
259 public void testCallbackOnSuccess_callsCallbackAfterOldCallbackCame() {
260 mAttentionDetector.mRequestId = 5;
261 registerAttention(); // mRequestId = 6;
262 mAttentionDetector.mRequestId = 55;
264 mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
265 SystemClock.uptimeMillis()); // old callback came
266 mAttentionDetector.mRequestId = 6; // now back to current
267 mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
268 SystemClock.uptimeMillis());
269 verify(mOnUserAttention).run();
273 public void testCallbackOnSuccess_DoesNotGoIntoInfiniteLoop() {
274 // Mimic real behavior
275 doAnswer((invocation) -> {
276 // Mimic a cache hit: calling onSuccess() immediately
278 mAttentionDetector.mRequestId++;
279 mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
280 SystemClock.uptimeMillis());
282 }).when(mOnUserAttention).run();
285 // This test fails with literal stack overflow:
286 // e.g. java.lang.StackOverflowError: stack size 1039KB
287 mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
288 SystemClock.uptimeMillis());
290 // We don't actually get here when the test fails
291 verify(mOnUserAttention, atMost(1)).run();
295 public void testCallbackOnFailure_unregistersCurrentRequestCode() {
297 mAttentionDetector.mCallback.onFailure(AttentionService.ATTENTION_FAILURE_UNKNOWN);
298 mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
299 SystemClock.uptimeMillis());
300 verify(mOnUserAttention, never()).run();
303 private long registerAttention() {
304 mAttentionTimeout = 4000L;
305 mAttentionDetector.onUserActivity(SystemClock.uptimeMillis(),
306 PowerManager.USER_ACTIVITY_EVENT_TOUCH);
307 return mAttentionDetector.updateUserActivity(mNextDimming);
310 private class TestableAttentionDetector extends AttentionDetector {
311 private boolean mAttentionServiceSupported;
313 TestableAttentionDetector() {
314 super(AttentionDetectorTest.this.mOnUserAttention, new Object());
315 mAttentionManager = mAttentionManagerInternal;
316 mWindowManager = mWindowManagerInternal;
317 mPackageManager = AttentionDetectorTest.this.mPackageManager;
318 mContentResolver = getContext().getContentResolver();
319 mMaximumExtensionMillis = 10000L;
322 void setAttentionServiceSupported(boolean supported) {
323 mAttentionServiceSupported = supported;
327 public boolean isAttentionServiceSupported() {
328 return mAttentionServiceSupported;
332 public long getAttentionTimeout() {
333 return mAttentionTimeout;