blob: a2f1f01b689fb8bf6c120a60289cfdc10d47d46c [file] [log] [blame]
/*
* Copyright (C) 2019 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.os.BatteryStats.Uid.NUM_USER_ACTIVITY_TYPES;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.attention.AttentionManagerInternal;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.attention.AttentionService;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@SmallTest
public class AttentionDetectorTest extends AndroidTestCase {
private @Mock AttentionManagerInternal mAttentionManagerInternal;
private @Mock Runnable mOnUserAttention;
private TestableAttentionDetector mAttentionDetector;
private long mAttentionTimeout;
private long mNextDimming;
private int mIsSettingEnabled;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mAttentionManagerInternal.checkAttention(anyInt(), anyLong(), any()))
.thenReturn(true);
mAttentionDetector = new TestableAttentionDetector();
mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_AWAKE);
mAttentionDetector.setAttentionServiceSupported(true);
mNextDimming = SystemClock.uptimeMillis() + 3000L;
// Save the existing state.
mIsSettingEnabled = Settings.System.getIntForUser(getContext().getContentResolver(),
Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT);
Settings.System.putIntForUser(getContext().getContentResolver(),
Settings.System.ADAPTIVE_SLEEP, 1, UserHandle.USER_CURRENT);
mAttentionDetector.updateEnabledFromSettings(getContext());
}
@After
public void tearDown() {
Settings.System.putIntForUser(getContext().getContentResolver(),
Settings.System.ADAPTIVE_SLEEP, mIsSettingEnabled, UserHandle.USER_CURRENT);
}
@Test
public void testOnUserActivity_checksAttention() {
long when = registerAttention();
verify(mAttentionManagerInternal).checkAttention(anyInt(), anyLong(), any());
assertThat(when).isLessThan(mNextDimming);
}
@Test
public void testOnUserActivity_doesntCheckIfNotEnabled() {
Settings.System.putIntForUser(getContext().getContentResolver(),
Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT);
mAttentionDetector.updateEnabledFromSettings(getContext());
long when = registerAttention();
verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
assertThat(mNextDimming).isEqualTo(when);
}
@Test
public void testOnUserActivity_doesntCheckIfNotSupported() {
mAttentionDetector.setAttentionServiceSupported(false);
long when = registerAttention();
verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
assertThat(mNextDimming).isEqualTo(when);
}
@Test
public void onUserActivity_ignoresWhiteListedActivityTypes() {
for (int i = 0; i < NUM_USER_ACTIVITY_TYPES; i++) {
int result = mAttentionDetector.onUserActivity(SystemClock.uptimeMillis(), i);
if (result == -1) {
throw new AssertionError("User activity " + i + " isn't listed in"
+ " AttentionDetector#onUserActivity. Please consider how this new activity"
+ " type affects the attention service.");
}
}
}
@Test
public void testUpdateUserActivity_ignoresWhenItsNotTimeYet() {
long now = SystemClock.uptimeMillis();
mNextDimming = now;
mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
mAttentionDetector.updateUserActivity(mNextDimming + 5000L);
verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
}
@Test
public void testUpdateUserActivity_schedulesTheNextCheck() {
long now = SystemClock.uptimeMillis();
mNextDimming = now;
mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
long nextTimeout = mAttentionDetector.updateUserActivity(mNextDimming + 5000L);
assertThat(nextTimeout).isEqualTo(mNextDimming + 5000L);
}
@Test
public void testOnUserActivity_ignoresAfterMaximumExtension() {
long now = SystemClock.uptimeMillis();
mAttentionDetector.onUserActivity(now - 15000L, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
mAttentionDetector.updateUserActivity(now + 2000L);
verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
}
@Test
public void testOnUserActivity_skipsIfAlreadyScheduled() {
registerAttention();
reset(mAttentionManagerInternal);
long when = mAttentionDetector.updateUserActivity(mNextDimming);
verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
assertThat(when).isLessThan(mNextDimming);
}
@Test
public void testOnWakefulnessChangeStarted_cancelsRequestWhenNotAwake() {
registerAttention();
mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_ASLEEP);
verify(mAttentionManagerInternal).cancelAttentionCheck(anyInt());
}
@Test
public void testCallbackOnSuccess_ignoresIfNoAttention() {
registerAttention();
mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
AttentionService.ATTENTION_SUCCESS_ABSENT, SystemClock.uptimeMillis());
verify(mOnUserAttention, never()).run();
}
@Test
public void testCallbackOnSuccess_callsCallback() {
registerAttention();
mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
AttentionService.ATTENTION_SUCCESS_PRESENT, SystemClock.uptimeMillis());
verify(mOnUserAttention).run();
}
@Test
public void testCallbackOnFailure_unregistersCurrentRequestCode() {
registerAttention();
mAttentionDetector.mCallback.onFailure(mAttentionDetector.getRequestCode(),
AttentionService.ATTENTION_FAILURE_UNKNOWN);
mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
AttentionService.ATTENTION_SUCCESS_PRESENT, SystemClock.uptimeMillis());
verify(mOnUserAttention, never()).run();
}
private long registerAttention() {
mAttentionTimeout = 4000L;
mAttentionDetector.onUserActivity(SystemClock.uptimeMillis(),
PowerManager.USER_ACTIVITY_EVENT_TOUCH);
return mAttentionDetector.updateUserActivity(mNextDimming);
}
private class TestableAttentionDetector extends AttentionDetector {
private boolean mAttentionServiceSupported;
TestableAttentionDetector() {
super(AttentionDetectorTest.this.mOnUserAttention, new Object());
mAttentionManager = mAttentionManagerInternal;
mMaximumExtensionMillis = 10000L;
}
void setAttentionServiceSupported(boolean supported) {
mAttentionServiceSupported = supported;
}
@Override
public boolean isAttentionServiceSupported() {
return mAttentionServiceSupported;
}
@Override
public long getAttentionTimeout() {
return mAttentionTimeout;
}
}
}