Loading services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java +37 −16 Original line number Diff line number Diff line Loading @@ -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); } } } } services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java +29 −23 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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); } Loading @@ -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++) { Loading @@ -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); } } services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +109 −96 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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()); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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) { Loading @@ -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; Loading Loading
services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java +37 −16 Original line number Diff line number Diff line Loading @@ -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); } } } }
services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java +29 −23 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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); } Loading @@ -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++) { Loading @@ -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); } }
services/tests/servicestests/src/com/android/server/am/UserControllerTest.java +109 −96 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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()); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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); Loading @@ -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) { Loading @@ -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; Loading