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

Commit 9b2b4f55 authored by Yi Jiang's avatar Yi Jiang Committed by Android (Google) Code Review
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
parents e7ef0a61 f9c9c162
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;
        }
    }
}