Merge "Adds unit tests in attention manager service for two interfaces: -checkAttention() -cancelAttentionCheck()" into qt-dev
This commit is contained in:
@@ -58,6 +58,7 @@ import android.util.StatsLog;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.DumpUtils;
|
||||
import com.android.internal.util.IndentingPrintWriter;
|
||||
import com.android.internal.util.Preconditions;
|
||||
@@ -100,16 +101,25 @@ public class AttentionManagerService extends SystemService {
|
||||
private final Object mLock;
|
||||
@GuardedBy("mLock")
|
||||
private final SparseArray<UserState> mUserStates = new SparseArray<>();
|
||||
private final AttentionHandler mAttentionHandler;
|
||||
private AttentionHandler mAttentionHandler;
|
||||
|
||||
private ComponentName mComponentName;
|
||||
@VisibleForTesting
|
||||
ComponentName mComponentName;
|
||||
|
||||
public AttentionManagerService(Context context) {
|
||||
this(context, (PowerManager) context.getSystemService(Context.POWER_SERVICE),
|
||||
new Object(), null);
|
||||
mAttentionHandler = new AttentionHandler();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
AttentionManagerService(Context context, PowerManager powerManager, Object lock,
|
||||
AttentionHandler handler) {
|
||||
super(context);
|
||||
mContext = Preconditions.checkNotNull(context);
|
||||
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||
mLock = new Object();
|
||||
mAttentionHandler = new AttentionHandler();
|
||||
mPowerManager = powerManager;
|
||||
mLock = lock;
|
||||
mAttentionHandler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,7 +157,8 @@ public class AttentionManagerService extends SystemService {
|
||||
return isServiceEnabled() && isServiceAvailable();
|
||||
}
|
||||
|
||||
private boolean isServiceEnabled() {
|
||||
@VisibleForTesting
|
||||
protected boolean isServiceEnabled() {
|
||||
return DeviceConfig.getBoolean(NAMESPACE_ATTENTION_MANAGER_SERVICE, SERVICE_ENABLED,
|
||||
DEFAULT_SERVICE_ENABLED);
|
||||
}
|
||||
@@ -161,7 +172,8 @@ public class AttentionManagerService extends SystemService {
|
||||
*
|
||||
* @return {@code true} if the framework was able to dispatch the request
|
||||
*/
|
||||
private boolean checkAttention(long timeout, AttentionCallbackInternal callbackInternal) {
|
||||
@VisibleForTesting
|
||||
boolean checkAttention(long timeout, AttentionCallbackInternal callbackInternal) {
|
||||
Preconditions.checkNotNull(callbackInternal);
|
||||
|
||||
if (!isAttentionServiceSupported()) {
|
||||
@@ -257,24 +269,24 @@ public class AttentionManagerService extends SystemService {
|
||||
}
|
||||
|
||||
/** Cancels the specified attention check. */
|
||||
private void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) {
|
||||
@VisibleForTesting
|
||||
void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) {
|
||||
synchronized (mLock) {
|
||||
final UserState userState = peekCurrentUserStateLocked();
|
||||
if (userState == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!userState.mCurrentAttentionCheck.mCallbackInternal.equals(callbackInternal)) {
|
||||
Slog.e(LOG_TAG, "Cannot cancel a non-current request");
|
||||
return;
|
||||
}
|
||||
|
||||
cancel(userState);
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void freeIfInactiveLocked() {
|
||||
@VisibleForTesting
|
||||
protected void freeIfInactiveLocked() {
|
||||
// If we are called here, it means someone used the API again - reset the timer then.
|
||||
mAttentionHandler.removeMessages(AttentionHandler.CHECK_CONNECTION_EXPIRATION);
|
||||
|
||||
@@ -291,7 +303,8 @@ public class AttentionManagerService extends SystemService {
|
||||
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private UserState getOrCreateCurrentUserStateLocked() {
|
||||
@VisibleForTesting
|
||||
protected UserState getOrCreateCurrentUserStateLocked() {
|
||||
return getOrCreateUserStateLocked(ActivityManager.getCurrentUser());
|
||||
}
|
||||
|
||||
@@ -307,7 +320,8 @@ public class AttentionManagerService extends SystemService {
|
||||
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private UserState peekCurrentUserStateLocked() {
|
||||
@VisibleForTesting
|
||||
protected UserState peekCurrentUserStateLocked() {
|
||||
return peekUserStateLocked(ActivityManager.getCurrentUser());
|
||||
}
|
||||
|
||||
@@ -418,7 +432,8 @@ public class AttentionManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class AttentionCheck {
|
||||
@VisibleForTesting
|
||||
static final class AttentionCheck {
|
||||
private final AttentionCallbackInternal mCallbackInternal;
|
||||
private final IAttentionCallback mIAttentionCallback;
|
||||
private boolean mIsDispatched;
|
||||
@@ -435,7 +450,8 @@ public class AttentionManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UserState {
|
||||
@VisibleForTesting
|
||||
protected static class UserState {
|
||||
final ComponentName mComponentName;
|
||||
final AttentionServiceConnection mConnection = new AttentionServiceConnection();
|
||||
|
||||
@@ -453,7 +469,7 @@ public class AttentionManagerService extends SystemService {
|
||||
final Context mContext;
|
||||
final Object mLock;
|
||||
|
||||
private UserState(int userId, Context context, Object lock, ComponentName componentName) {
|
||||
UserState(int userId, Context context, Object lock, ComponentName componentName) {
|
||||
mUserId = userId;
|
||||
mContext = Preconditions.checkNotNull(context);
|
||||
mLock = Preconditions.checkNotNull(lock);
|
||||
@@ -509,7 +525,7 @@ public class AttentionManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private final class AttentionServiceConnection implements ServiceConnection {
|
||||
private class AttentionServiceConnection implements ServiceConnection {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
init(IAttentionService.Stub.asInterface(service));
|
||||
@@ -544,7 +560,8 @@ public class AttentionManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private class AttentionHandler extends Handler {
|
||||
@VisibleForTesting
|
||||
protected class AttentionHandler extends Handler {
|
||||
private static final int CHECK_CONNECTION_EXPIRATION = 1;
|
||||
private static final int ATTENTION_CHECK_TIMEOUT = 2;
|
||||
|
||||
@@ -576,7 +593,8 @@ public class AttentionManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void cancel(UserState userState) {
|
||||
@VisibleForTesting
|
||||
void cancel(UserState userState) {
|
||||
if (userState == null || userState.mCurrentAttentionCheck == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.attention;
|
||||
|
||||
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.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.attention.AttentionManagerInternal.AttentionCallbackInternal;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.IPowerManager;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.service.attention.IAttentionCallback;
|
||||
import android.service.attention.IAttentionService;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.server.attention.AttentionManagerService.AttentionCheck;
|
||||
import com.android.server.attention.AttentionManagerService.AttentionHandler;
|
||||
import com.android.server.attention.AttentionManagerService.UserState;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
/**
|
||||
* Tests for {@link com.android.server.attention.AttentionManagerService}
|
||||
*/
|
||||
@SmallTest
|
||||
public class AttentionManagerServiceTest {
|
||||
private AttentionManagerService mSpyAttentionManager;
|
||||
private UserState mSpyUserState;
|
||||
private final int mTimeout = 1000;
|
||||
@Mock private AttentionCallbackInternal mMockAttentionCallbackInternal;
|
||||
@Mock private AttentionHandler mMockHandler;
|
||||
@Mock private IAttentionCallback mMockIAttentionCallback;
|
||||
@Mock private IPowerManager mMockIPowerManager;
|
||||
@Mock Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws RemoteException {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
// setup context mock
|
||||
doReturn(true).when(mContext).bindServiceAsUser(any(), any(), anyInt(), any());
|
||||
// setup power manager mock
|
||||
PowerManager mPowerManager;
|
||||
doReturn(true).when(mMockIPowerManager).isInteractive();
|
||||
mPowerManager = new PowerManager(mContext, mMockIPowerManager, null);
|
||||
|
||||
Object mLock = new Object();
|
||||
// setup a spy on attention manager
|
||||
AttentionManagerService mAttentionManager = new AttentionManagerService(
|
||||
mContext,
|
||||
mPowerManager,
|
||||
mLock,
|
||||
mMockHandler);
|
||||
mSpyAttentionManager = Mockito.spy(mAttentionManager);
|
||||
// setup a spy on user state
|
||||
ComponentName componentName = new ComponentName("a", "b");
|
||||
mSpyAttentionManager.mComponentName = componentName;
|
||||
UserState mUserState = new UserState(0,
|
||||
mContext,
|
||||
mLock,
|
||||
componentName);
|
||||
mUserState.mService = new MockIAttentionService();
|
||||
mSpyUserState = spy(mUserState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelAttentionCheck_noCrashWhenNoUserStateLocked() {
|
||||
mSpyAttentionManager.cancelAttentionCheck(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelAttentionCheck_noCrashWhenCallbackMismatched() {
|
||||
mSpyUserState.mCurrentAttentionCheck =
|
||||
new AttentionCheck(mMockAttentionCallbackInternal, mMockIAttentionCallback);
|
||||
doReturn(mSpyUserState).when(mSpyAttentionManager).peekCurrentUserStateLocked();
|
||||
mSpyAttentionManager.cancelAttentionCheck(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelAttentionCheck_cancelCallbackWhenMatched() {
|
||||
mSpyUserState.mCurrentAttentionCheck =
|
||||
new AttentionCheck(mMockAttentionCallbackInternal, mMockIAttentionCallback);
|
||||
doReturn(mSpyUserState).when(mSpyAttentionManager).peekCurrentUserStateLocked();
|
||||
mSpyAttentionManager.cancelAttentionCheck(mMockAttentionCallbackInternal);
|
||||
verify(mSpyAttentionManager).cancel(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAttention_returnFalseWhenPowerManagerNotInteract() throws RemoteException {
|
||||
doReturn(false).when(mMockIPowerManager).isInteractive();
|
||||
AttentionCallbackInternal callback = Mockito.mock(AttentionCallbackInternal.class);
|
||||
assertThat(mSpyAttentionManager.checkAttention(mTimeout, callback)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAttention_callOnSuccess() throws RemoteException {
|
||||
doReturn(true).when(mSpyAttentionManager).isServiceEnabled();
|
||||
doReturn(true).when(mMockIPowerManager).isInteractive();
|
||||
doReturn(mSpyUserState).when(mSpyAttentionManager).getOrCreateCurrentUserStateLocked();
|
||||
doNothing().when(mSpyAttentionManager).freeIfInactiveLocked();
|
||||
|
||||
AttentionCallbackInternal callback = Mockito.mock(AttentionCallbackInternal.class);
|
||||
mSpyAttentionManager.checkAttention(mTimeout, callback);
|
||||
verify(callback).onSuccess(anyInt(), anyLong());
|
||||
}
|
||||
|
||||
private class MockIAttentionService implements IAttentionService {
|
||||
public void checkAttention(IAttentionCallback callback) throws RemoteException {
|
||||
callback.onSuccess(0, 0);
|
||||
}
|
||||
public void cancelAttentionCheck(IAttentionCallback callback) {
|
||||
}
|
||||
public IBinder asBinder() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user