Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61886126 authored by Yi Jiang's avatar Yi Jiang Committed by android-build-merger
Browse files

Merge "Adds unit tests in attention manager service for two interfaces:...

Merge "Adds unit tests in attention manager service for two interfaces: -checkAttention() -cancelAttentionCheck()" into qt-dev
am: 9b2b4f55

Change-Id: I1bd75ddc203bc247ddf38a3012edd5ec1696447c
parents c728f75a 9b2b4f55
Loading
Loading
Loading
Loading
+37 −19
Original line number Diff line number Diff line
@@ -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;
        }
+145 −0
Original line number Diff line number Diff line
/*
 * 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;
        }
    }
}