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

Commit 4554207a authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Revert "Revert "Remove obsolete AndroidTestCase""

This reverts commit 1965af25.

Reason for revert: the main cause has been fixed b/117880789.

Bug: 117924387
Change-Id: I32fcf72c9262d10364dfb1e31a6eacf69652be5f
parent 1965af25
Loading
Loading
Loading
Loading
+37 −16
Original line number Diff line number Diff line
@@ -16,39 +16,60 @@

package com.android.server.am;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;

import android.app.ActivityManager;
import android.app.ActivityManager.RecentTaskInfo;
import android.app.IActivityManager;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.RemoteException;
import android.test.AndroidTestCase;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;

import org.junit.Before;
import org.junit.Test;

import java.util.List;

public class ActivityManagerTest extends AndroidTestCase {
import androidx.test.filters.FlakyTest;

    IActivityManager service;
    @Override
/**
 * Tests for {@link ActivityManager}.
 *
 * Build/Install/Run:
 *  atest FrameworksServicesTests:com.android.server.am.ActivityManagerTest
 */
@Presubmit
@FlakyTest(detail = "Promote to presubmit if stable")
public class ActivityManagerTest {

    private IActivityManager service;

    @Before
    public void setUp() throws Exception {
        super.setUp();
        service = ActivityManager.getService();
    }

    @Test
    public void testTaskIdsForRunningUsers() throws RemoteException {
        for(int userId : service.getRunningUserIds()) {
        int[] runningUserIds = service.getRunningUserIds();
        assertThat(runningUserIds).isNotEmpty();
        for (int userId : runningUserIds) {
            testTaskIdsForUser(userId);
        }
    }

    private void testTaskIdsForUser(int userId) throws RemoteException {
        List<ActivityManager.RecentTaskInfo> recentTasks = service.getRecentTasks(
                100, 0, userId).getList();
        if(recentTasks != null) {
            for(ActivityManager.RecentTaskInfo recentTask : recentTasks) {
                int taskId = recentTask.persistentId;
        List<?> recentTasks = service.getRecentTasks(100, 0, userId).getList();
        assertThat(recentTasks).isNotNull();
        assertThat(recentTasks).isNotEmpty();
        for (Object elem : recentTasks) {
            assertThat(elem).isInstanceOf(RecentTaskInfo.class);
            RecentTaskInfo recentTask = (RecentTaskInfo) elem;
            int taskId = recentTask.taskId;
            assertEquals("The task id " + taskId + " should not belong to user " + userId,
                    taskId / UserHandle.PER_USER_RANGE, userId);
        }
    }
}
}
+29 −23
Original line number Diff line number Diff line
@@ -16,34 +16,43 @@

package com.android.server.am;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import static androidx.test.InstrumentationRegistry.getTargetContext;

import android.content.pm.UserInfo;
import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
import android.test.AndroidTestCase;
import android.util.Log;
import android.platform.test.annotations.Presubmit;
import android.util.SparseBooleanArray;

import com.android.server.am.TaskPersister;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.util.Random;
import androidx.test.filters.FlakyTest;

/**
 * Tests for {@link TaskPersister}.
 *
 * Build/Install/Run:
 *  atest FrameworksServicesTests:TaskPersisterTest
 */
public class TaskPersisterTest extends AndroidTestCase {
@Presubmit
@FlakyTest(detail = "Promote to presubmit if stable")
public class TaskPersisterTest {
    private static final String TEST_USER_NAME = "AM-Test-User";

    private TaskPersister mTaskPersister;
    private int testUserId;
    private UserManager mUserManager;

    @Override
    @Before
    public void setUp() throws Exception {
        super.setUp();
        mUserManager = UserManager.get(getContext());
        mTaskPersister = new TaskPersister(getContext().getFilesDir());
        mUserManager = UserManager.get(getTargetContext());
        mTaskPersister = new TaskPersister(getTargetContext().getFilesDir());
        // In ARC, the maximum number of supported users is one, which is different from the ones of
        // most phones (more than 4). This prevents TaskPersisterTest from creating another user for
        // test. However, since guest users can be added as much as possible, we create guest user
@@ -51,9 +60,8 @@ public class TaskPersisterTest extends AndroidTestCase {
        testUserId = createUser(TEST_USER_NAME, UserInfo.FLAG_GUEST);
    }

    @Override
    @After
    public void tearDown() throws Exception {
        super.tearDown();
        mTaskPersister.unloadUserDataFromMemory(testUserId);
        removeUser(testUserId);
    }
@@ -64,6 +72,7 @@ public class TaskPersisterTest extends AndroidTestCase {
        return taskId;
    }

    @Test
    public void testTaskIdsPersistence() {
        SparseBooleanArray taskIdsOnFile = new SparseBooleanArray();
        for (int i = 0; i < 100; i++) {
@@ -72,21 +81,18 @@ public class TaskPersisterTest extends AndroidTestCase {
        mTaskPersister.writePersistedTaskIdsForUser(taskIdsOnFile, testUserId);
        SparseBooleanArray newTaskIdsOnFile = mTaskPersister
                .loadPersistedTaskIdsForUser(testUserId);
        assertTrue("TaskIds written differ from TaskIds read back from file",
                taskIdsOnFile.equals(newTaskIdsOnFile));
        assertEquals("TaskIds written differ from TaskIds read back from file",
                taskIdsOnFile, newTaskIdsOnFile);
    }

    private int createUser(String name, int flags) {
        UserInfo user = mUserManager.createUser(name, flags);
        if (user == null) {
            fail("Error while creating the test user: " + TEST_USER_NAME);
        }
        assertNotNull("Error while creating the test user: " + TEST_USER_NAME, user);
        return user.id;
    }

    private void removeUser(int userId) {
        if (!mUserManager.removeUser(userId)) {
            fail("Error while removing the test user: " + TEST_USER_NAME);
        }
        boolean userRemoved = mUserManager.removeUser(userId);
        assertTrue("Error while removing the test user: " + TEST_USER_NAME, userRemoved);
    }
}
+109 −96
Original line number Diff line number Diff line
@@ -16,6 +16,41 @@

package com.android.server.am;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;

import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG;
import static com.android.server.am.UserController.SYSTEM_USER_START_MSG;
import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;

import static com.google.android.collect.Lists.newArrayList;
import static com.google.android.collect.Sets.newHashSet;
import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import static androidx.test.InstrumentationRegistry.getTargetContext;

import android.app.IUserSwitchObserver;
import android.content.Context;
import android.content.IIntentReceiver;
@@ -31,80 +66,62 @@ import android.os.Message;
import android.os.RemoteException;
import android.os.UserManagerInternal;
import android.platform.test.annotations.Presubmit;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;

import com.android.server.pm.UserManagerService;
import com.android.server.wm.WindowManagerService;

import org.mockito.Mockito;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG;
import static com.android.server.am.UserController.SYSTEM_USER_START_MSG;
import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import androidx.test.filters.SmallTest;

/**
 * Usage: bit FrameworksServicesTests:com.android.server.am.UserControllerTest
 * Tests for {@link UserController}.
 *
 * Build/Install/Run:
 *  atest FrameworksServicesTests:com.android.server.am.UserControllerTest
 */
@Presubmit
public class UserControllerTest extends AndroidTestCase {
@SmallTest
public class UserControllerTest {
    private static final int TEST_USER_ID = 10;
    private static final int NONEXIST_USER_ID = 2;
    private static String TAG = UserControllerTest.class.getSimpleName();
    private UserController mUserController;
    private TestInjector mInjector;

    private static final List<String> START_FOREGROUND_USER_ACTIONS =
            Arrays.asList(
    private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList(
            Intent.ACTION_USER_STARTED,
            Intent.ACTION_USER_SWITCHED,
            Intent.ACTION_USER_STARTING);

    private static final List<String> START_BACKGROUND_USER_ACTIONS =
            Arrays.asList(
    private static final List<String> START_BACKGROUND_USER_ACTIONS = newArrayList(
            Intent.ACTION_USER_STARTED,
            Intent.ACTION_LOCKED_BOOT_COMPLETED,
            Intent.ACTION_USER_STARTING);

    private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES =
            new HashSet<>(Arrays.asList(REPORT_USER_SWITCH_MSG, USER_SWITCH_TIMEOUT_MSG,
                    SYSTEM_USER_START_MSG, SYSTEM_USER_CURRENT_MSG));
    private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES = newHashSet(
            REPORT_USER_SWITCH_MSG,
            USER_SWITCH_TIMEOUT_MSG,
            SYSTEM_USER_START_MSG,
            SYSTEM_USER_CURRENT_MSG);

    private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES =
            new HashSet<>(Arrays.asList(SYSTEM_USER_START_MSG, REPORT_LOCKED_BOOT_COMPLETE_MSG));
    private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
            SYSTEM_USER_START_MSG,
            REPORT_LOCKED_BOOT_COMPLETE_MSG);

    @Override
    @Before
    public void setUp() throws Exception {
        super.setUp();
        runWithDexmakerShareClassLoader(() -> {
            mInjector = Mockito.spy(new TestInjector(getContext()));
            mInjector = spy(new TestInjector(getTargetContext()));
            doNothing().when(mInjector).clearAllLockedTasks(anyString());
            doNothing().when(mInjector).startHomeActivity(anyInt(), anyString());
            doReturn(false).when(mInjector).stackSupervisorSwitchUser(anyInt(), any());
@@ -114,58 +131,54 @@ public class UserControllerTest extends AndroidTestCase {
        });
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
    @After
    public void tearDown() throws Exception {
        mInjector.handlerThread.quit();
        Mockito.validateMockitoUsage();
        validateMockitoUsage();
    }

    @SmallTest
    public void testStartUser_foreground() throws RemoteException {
    @Test
    public void testStartUser_foreground() {
        mUserController.startUser(TEST_USER_ID, true /* foreground */);
        Mockito.verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt());
        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
        Mockito.verify(mInjector.getWindowManager()).setSwitchingUser(true);
        Mockito.verify(mInjector).clearAllLockedTasks(anyString());
        verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt());
        verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
        verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
        verify(mInjector.getWindowManager()).setSwitchingUser(true);
        verify(mInjector).clearAllLockedTasks(anyString());
        startForegroundUserAssertions();
    }

    @SmallTest
    public void testStartUser_background() throws RemoteException {
    @Test
    public void testStartUser_background() {
        mUserController.startUser(TEST_USER_ID, false /* foreground */);
        Mockito.verify(
                mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
        Mockito.verify(mInjector, never()).clearAllLockedTasks(anyString());
        verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
        verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
        verify(mInjector, never()).clearAllLockedTasks(anyString());
        startBackgroundUserAssertions();
    }

    @SmallTest
    public void testStartUserUIDisabled() throws RemoteException {
    @Test
    public void testStartUserUIDisabled() {
        mUserController.mUserSwitchUiEnabled = false;
        mUserController.startUser(TEST_USER_ID, true /* foreground */);
        Mockito.verify(mInjector.getWindowManager(), never())
                .startFreezingScreen(anyInt(), anyInt());
        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
        verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
        verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
        verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
        startForegroundUserAssertions();
    }

    private void startUserAssertions(
            List<String> expectedActions, Set<Integer> expectedMessageCodes)
            throws RemoteException {
            List<String> expectedActions, Set<Integer> expectedMessageCodes) {
        assertEquals(expectedActions, getActions(mInjector.sentIntents));
        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
        assertEquals("Unexpected message sent", expectedMessageCodes, actualCodes);
    }

    private void startBackgroundUserAssertions() throws RemoteException {
    private void startBackgroundUserAssertions() {
        startUserAssertions(START_BACKGROUND_USER_ACTIONS, START_BACKGROUND_USER_MESSAGE_CODES);
    }

    private void startForegroundUserAssertions() throws RemoteException {
    private void startForegroundUserAssertions() {
        startUserAssertions(START_FOREGROUND_USER_ACTIONS, START_FOREGROUND_USER_MESSAGE_CODES);
        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
        assertNotNull(reportMsg);
@@ -177,15 +190,15 @@ public class UserControllerTest extends AndroidTestCase {
        assertEquals("Unexpected new user id", TEST_USER_ID, reportMsg.arg2);
    }

    @SmallTest
    public void testFailedStartUserInForeground() throws RemoteException {
    @Test
    public void testFailedStartUserInForeground() {
        mUserController.mUserSwitchUiEnabled = false;
        mUserController.startUserInForeground(NONEXIST_USER_ID);
        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
        Mockito.verify(mInjector.getWindowManager()).setSwitchingUser(false);
        verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
        verify(mInjector.getWindowManager()).setSwitchingUser(false);
    }

    @SmallTest
    @Test
    public void testDispatchUserSwitch() throws RemoteException {
        // Prepare mock observer and register it
        IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
@@ -206,7 +219,7 @@ public class UserControllerTest extends AndroidTestCase {
        // Call dispatchUserSwitch and verify that observer was called only once
        mInjector.handler.clearAllRecordedMessages();
        mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
        Mockito.verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
        verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
        Set<Integer> expectedCodes = Collections.singleton(CONTINUE_USER_SWITCH_MSG);
        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
        assertEquals("Unexpected message sent", expectedCodes, actualCodes);
@@ -220,7 +233,7 @@ public class UserControllerTest extends AndroidTestCase {
        assertEquals("Unexpected new user id", TEST_USER_ID, conMsg.arg2);
    }

    @SmallTest
    @Test
    public void testDispatchUserSwitchBadReceiver() throws RemoteException {
        // Prepare mock observer which doesn't notify the callback and register it
        IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
@@ -236,14 +249,14 @@ public class UserControllerTest extends AndroidTestCase {
        // Call dispatchUserSwitch and verify that observer was called only once
        mInjector.handler.clearAllRecordedMessages();
        mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
        Mockito.verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
        verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
        // Verify that CONTINUE_USER_SWITCH_MSG is not sent (triggers timeout)
        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
        assertTrue("No messages should be sent", actualCodes.isEmpty());
        assertWithMessage("No messages should be sent").that(actualCodes).isEmpty();
    }

    @SmallTest
    public void testContinueUserSwitch() throws RemoteException {
    @Test
    public void testContinueUserSwitch() {
        // Start user -- this will update state of mUserController
        mUserController.startUser(TEST_USER_ID, true);
        Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
@@ -254,12 +267,12 @@ public class UserControllerTest extends AndroidTestCase {
        mInjector.handler.clearAllRecordedMessages();
        // Verify that continueUserSwitch worked as expected
        mUserController.continueUserSwitch(userState, oldUserId, newUserId);
        Mockito.verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
        verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
        continueUserSwitchAssertions();
    }

    @SmallTest
    public void testContinueUserSwitchUIDisabled() throws RemoteException {
    @Test
    public void testContinueUserSwitchUIDisabled() {
        mUserController.mUserSwitchUiEnabled = false;
        // Start user -- this will update state of mUserController
        mUserController.startUser(TEST_USER_ID, true);
@@ -271,11 +284,11 @@ public class UserControllerTest extends AndroidTestCase {
        mInjector.handler.clearAllRecordedMessages();
        // Verify that continueUserSwitch worked as expected
        mUserController.continueUserSwitch(userState, oldUserId, newUserId);
        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
        verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
        continueUserSwitchAssertions();
    }

    private void continueUserSwitchAssertions() throws RemoteException {
    private void continueUserSwitchAssertions() {
        Set<Integer> expectedCodes = Collections.singleton(REPORT_USER_SWITCH_COMPLETE_MSG);
        Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
        assertEquals("Unexpected message sent", expectedCodes, actualCodes);
@@ -284,7 +297,7 @@ public class UserControllerTest extends AndroidTestCase {
        assertEquals("Unexpected userId", TEST_USER_ID, msg.arg1);
    }

    @SmallTest
    @Test
    public void testDispatchUserSwitchComplete() throws RemoteException {
        // Prepare mock observer and register it
        IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
@@ -298,12 +311,12 @@ public class UserControllerTest extends AndroidTestCase {
        mInjector.handler.clearAllRecordedMessages();
        // Mockito can't reset only interactions, so just verify that this hasn't been
        // called with 'false' until after dispatchUserSwitchComplete.
        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(false);
        verify(mInjector.getWindowManager(), never()).setSwitchingUser(false);
        // Call dispatchUserSwitchComplete
        mUserController.dispatchUserSwitchComplete(newUserId);
        Mockito.verify(observer, times(1)).onUserSwitchComplete(anyInt());
        Mockito.verify(observer).onUserSwitchComplete(TEST_USER_ID);
        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false);
        verify(observer, times(1)).onUserSwitchComplete(anyInt());
        verify(observer).onUserSwitchComplete(TEST_USER_ID);
        verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false);
    }

    private void setUpUser(int userId, int flags) {
@@ -320,7 +333,7 @@ public class UserControllerTest extends AndroidTestCase {
    }

    // Should be public to allow mocking
    public static class TestInjector extends UserController.Injector {
    private static class TestInjector extends UserController.Injector {
        TestHandler handler;
        TestHandler uiHandler;
        HandlerThread handlerThread;