1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.car.cts.builtin.app; 18 19 import static android.car.builtin.app.ActivityManagerHelper.ProcessObserverCallback; 20 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 21 import static android.view.Display.DEFAULT_DISPLAY; 22 23 import static com.google.common.truth.Truth.assertThat; 24 import static com.google.common.truth.Truth.assertWithMessage; 25 26 import static org.junit.Assume.assumeFalse; 27 28 import android.app.Activity; 29 import android.app.ActivityManager; 30 import android.app.ActivityOptions; 31 import android.app.Instrumentation; 32 import android.app.TaskInfo; 33 import android.car.builtin.app.ActivityManagerHelper; 34 import android.car.cts.builtin.activity.ActivityManagerTestActivityBase; 35 import android.car.test.PermissionsCheckerRule; 36 import android.car.test.PermissionsCheckerRule.EnsureHasPermission; 37 import android.content.ComponentName; 38 import android.content.Context; 39 import android.content.Intent; 40 import android.content.pm.PackageManager; 41 import android.graphics.Rect; 42 import android.os.Process; 43 import android.os.UserHandle; 44 import android.server.wm.ActivityManagerTestBase; 45 import android.server.wm.WindowManagerState; 46 import android.util.Log; 47 48 import androidx.test.platform.app.InstrumentationRegistry; 49 import androidx.test.runner.AndroidJUnit4; 50 51 import com.android.bedstead.nene.TestApis; 52 import com.android.bedstead.permissions.PermissionContext; 53 import com.android.compatibility.common.util.PollingCheck; 54 import com.android.compatibility.common.util.SystemUtil; 55 56 import org.junit.Before; 57 import org.junit.Ignore; 58 import org.junit.Rule; 59 import org.junit.Test; 60 import org.junit.runner.RunWith; 61 62 import java.util.List; 63 import java.util.concurrent.CountDownLatch; 64 import java.util.concurrent.TimeUnit; 65 import java.util.regex.Matcher; 66 import java.util.regex.Pattern; 67 68 @RunWith(AndroidJUnit4.class) 69 public final class ActivityManagerHelperTest extends ActivityManagerTestBase { 70 71 @Rule 72 public final PermissionsCheckerRule mPermissionsCheckerRule = new PermissionsCheckerRule(); 73 74 // type values from frameworks/base/core/java/android/app/WindowConfiguration 75 enum ActivityType { 76 ACTIVITY_TYPE_UNDEFINED, 77 ACTIVITY_TYPE_STANDARD 78 } 79 80 private static final String TAG = ActivityManagerHelperTest.class.getSimpleName(); 81 82 private static final String PERMISSION_SET_ACTIVITY_WATCHER = 83 "android.permission.SET_ACTIVITY_WATCHER"; 84 private static final String NOT_REQUESTED_PERMISSION_CAR_MILEAGE = 85 "android.car.permission.CAR_MILEAGE"; 86 private static final String NOT_REQUESTED_PERMISSION_READ_CAR_POWER_POLICY = 87 "android.car.permission.READ_CAR_POWER_POLICY"; 88 89 private static final String GRANTED_PERMISSION_INTERACT_ACROSS_USERS = 90 "android.permission.INTERACT_ACROSS_USERS"; 91 92 // ActivityManagerHelper.removeTask needs this permission 93 private static final String PERMISSION_REMOVE_TASKS = "android.permission.REMOVE_TASKS"; 94 // IActivityManager.getAllRootTaskInfos called in ActivityManagerHelper.stopAllTaskForUser 95 // needs this permission. 96 private static final String PERMISSION_MANAGE_ACTIVITY_TASKS = 97 "android.permission.MANAGE_ACTIVITY_TASKS"; 98 // ActivityManager.getRunningAppProcess called in isAppRunning needs this permission 99 private static final String PERMISSION_INTERACT_ACROSS_USERS_FULL = 100 "android.permission.INTERACT_ACROSS_USERS_FULL"; 101 private static final String PERMISSION_REAL_GET_TASKS = 102 "android.permission.REAL_GET_TASKS"; 103 104 private static final String SIMPLE_APP_PACKAGE_NAME = "android.car.cts.builtin.apps.simple"; 105 private static final String SIMPLE_ACTIVITY_RELATIVE_NAME = ".SimpleActivity"; 106 private static final String SIMPLE_ACTIVITY_NAME = SIMPLE_APP_PACKAGE_NAME 107 + SIMPLE_ACTIVITY_RELATIVE_NAME; 108 private static final String START_SIMPLE_ACTIVITY_COMMAND = "am start -W -n " 109 + SIMPLE_APP_PACKAGE_NAME + "/" + SIMPLE_ACTIVITY_RELATIVE_NAME; 110 private static final ComponentName SIMPLE_ACTIVITY_COMPONENT_NAME = 111 new ComponentName(SIMPLE_APP_PACKAGE_NAME, SIMPLE_ACTIVITY_RELATIVE_NAME); 112 113 // TODO(b/230757942): replace following shell commands with direct API calls 114 private static final String CREATE_USER_COMMAND = "cmd car_service create-user "; 115 private static final String SWITCH_USER_COMMAND = "cmd car_service switch-user "; 116 private static final String REMOVE_USER_COMMAND = "cmd car_service remove-user "; 117 private static final String START_USER_COMMAND = "am start-user -w "; 118 private static final String GET_CURRENT_USER_COMMAND = "am get-current-user "; 119 private static final String CTS_CAR_TEST_USER_NAME = "CtsCarTestUser"; 120 // the value from UserHandle.USER_NULL 121 private static final int INVALID_USER_ID = -10_000; 122 123 private static final int OWNING_UID = UserHandle.ALL.getIdentifier(); 124 private static final int MAX_NUM_TASKS = 1_000; 125 private static final int TIMEOUT_MS = 4_000; 126 127 // x coordinate of the left boundary line of the animation rectangle 128 private static final int ANIMATION_RECT_LEFT = 0; 129 // y coordinate of the top boundary line of the animation rectangle 130 private static final int ANIMATION_RECT_TOP = 200; 131 // x coordinate of the right boundary line of the animation rectangle 132 private static final int ANIMATION_RECT_RIGHT = 400; 133 // y coordinate of the bottom boundary line of the animation rectangle 134 private static final int ANIMATION_RECT_BOTTOM = 0; 135 136 private static final int RANDOM_NON_DEFAULT_DISPLAY_ID = 1; 137 private static final boolean NON_DEFAULT_LOCK_TASK_MODE = true; 138 private static final boolean 139 NON_DEFAULT_PENDING_INTENT_BACKGROUND_ACTIVITY_LAUNCH_ALLOWED = true; 140 141 142 private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation(); 143 private final Context mContext = mInstrumentation.getContext(); 144 145 @Before setUp()146 public void setUp() throws Exception { 147 // Home was launched in ActivityManagerTestBase#setUp, wait until it is stable, 148 // in order not to mix the event of its TaskView Activity with the TestActivity. 149 mWmState.waitForHomeActivityVisible(); 150 } 151 152 @Test 153 @EnsureHasPermission(GRANTED_PERMISSION_INTERACT_ACROSS_USERS) testCheckComponentPermission()154 public void testCheckComponentPermission() throws Exception { 155 // not requested from Manifest 156 assertComponentPermissionNotGranted(NOT_REQUESTED_PERMISSION_CAR_MILEAGE); 157 assertComponentPermissionNotGranted(NOT_REQUESTED_PERMISSION_READ_CAR_POWER_POLICY); 158 159 // requested from Manifest and granted 160 assertComponentPermissionGranted(GRANTED_PERMISSION_INTERACT_ACROSS_USERS); 161 } 162 163 @Test testSetFocusedTask()164 public void testSetFocusedTask() throws Exception { 165 assumeFalse(hasAutomotiveSplitscreenMultitaskingFeature()); 166 // setup 167 ActivityA task1BottomActivity = launchTestActivity(ActivityA.class); 168 ActivityB task1TopActivity = launchTestActivity(ActivityB.class); 169 ActivityC task2TopActivity = launchTestActivity(ActivityC.class); 170 171 logActivityStack("amTestActivitys ", 172 task1BottomActivity, task1TopActivity, task2TopActivity); 173 174 assertWithMessage("bottom activity is the task root") 175 .that(task1BottomActivity.isTaskRoot()).isTrue(); 176 assertWithMessage("task id of the top activity in the task1") 177 .that(task1TopActivity.getTaskId()).isEqualTo(task1BottomActivity.getTaskId()); 178 assertWithMessage("task id of the top activity in the task2") 179 .that(task2TopActivity.getTaskId()).isNotEqualTo(task1TopActivity.getTaskId()); 180 assertWithMessage("task1 top activity is visible") 181 .that(task1TopActivity.isVisible()).isFalse(); 182 assertWithMessage("task2 top activity is visible") 183 .that(task2TopActivity.isVisible()).isTrue(); 184 185 // execute 186 try { 187 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 188 PERMISSION_MANAGE_ACTIVITY_TASKS); 189 190 ActivityManagerHelper.setFocusedTask(task1BottomActivity.getTaskId()); 191 } finally { 192 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 193 } 194 195 196 // assert 197 ComponentName activityName = task1TopActivity.getComponentName(); 198 waitAndAssertResumedAndFocusedActivityOnDisplay(activityName, DEFAULT_DISPLAY, 199 "Activity must be resumed"); 200 waitAndAssertFocusStatusChanged(task1TopActivity, true); 201 assertWithMessage("task1 top activity is visible") 202 .that(task1TopActivity.isVisible()).isTrue(); 203 204 // teardown 205 task1TopActivity.finish(); 206 task1BottomActivity.finish(); 207 task2TopActivity.finish(); 208 } 209 210 @Test testRemoveTask()211 public void testRemoveTask() throws Exception { 212 // setup 213 ActivityC testActivity = launchTestActivity(ActivityC.class); 214 int taskId = testActivity.getTaskId(); 215 assertThat(doesTaskExist(taskId)).isTrue(); 216 217 218 // execute 219 try (PermissionContext p = TestApis.permissions().withPermission(PERMISSION_REMOVE_TASKS)) { 220 ActivityManagerHelper.removeTask(taskId); 221 } 222 223 // assert 224 PollingCheck.waitFor(TIMEOUT_MS, () -> testActivity.isDestroyed()); 225 assertThat(doesTaskExist(taskId)).isFalse(); 226 } 227 228 @Test testProcessObserverCallback()229 public void testProcessObserverCallback() throws Exception { 230 // setup 231 ProcessObserverCallbackTestImpl callbackImpl = new ProcessObserverCallbackTestImpl(); 232 233 // execute 234 try { 235 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 236 PERMISSION_SET_ACTIVITY_WATCHER); // for registerProcessObserverCallback 237 238 ActivityManagerHelper.registerProcessObserverCallback(callbackImpl); 239 240 launchSimpleActivity(); 241 242 // assert 243 assertThat(callbackImpl.waitForForegroundActivitiesChanged()).isTrue(); 244 } finally { 245 // teardown 246 ActivityManagerHelper.unregisterProcessObserverCallback(callbackImpl); 247 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 248 } 249 } 250 251 @Test testCreateActivityOptions()252 public void testCreateActivityOptions() { 253 Rect expectedRect = new Rect(ANIMATION_RECT_LEFT, 254 ANIMATION_RECT_TOP, 255 ANIMATION_RECT_RIGHT, 256 ANIMATION_RECT_BOTTOM); 257 int expectedDisplayId = RANDOM_NON_DEFAULT_DISPLAY_ID; 258 boolean expectedLockTaskMode = NON_DEFAULT_LOCK_TASK_MODE; 259 boolean expectedLaunchAllowed = 260 NON_DEFAULT_PENDING_INTENT_BACKGROUND_ACTIVITY_LAUNCH_ALLOWED; 261 262 ActivityOptions originalOptions = 263 ActivityOptions.makeCustomAnimation(mContext, 264 /* entResId= */ android.R.anim.fade_in, 265 /* exitResId= */ android.R.anim.fade_out); 266 originalOptions.setLaunchBounds(expectedRect); 267 originalOptions.setLaunchDisplayId(expectedDisplayId); 268 originalOptions.setLockTaskEnabled(expectedLockTaskMode); 269 originalOptions.setPendingIntentBackgroundActivityLaunchAllowed(expectedLaunchAllowed); 270 271 ActivityOptions createdOptions = 272 ActivityManagerHelper.createActivityOptions(originalOptions.toBundle()); 273 274 assertThat(createdOptions.getLaunchBounds()).isEqualTo(expectedRect); 275 assertThat(createdOptions.getLaunchDisplayId()).isEqualTo(expectedDisplayId); 276 assertThat(createdOptions.getLockTaskMode()).isEqualTo(expectedLockTaskMode); 277 assertThat(createdOptions.isPendingIntentBackgroundActivityLaunchAllowed()) 278 .isEqualTo(expectedLaunchAllowed); 279 } 280 281 @Ignore("b/304870066") 282 @Test testStopAllTasksForUser()283 public void testStopAllTasksForUser() throws Exception { 284 int initialCurrentUserId = getCurrentUserId(); 285 int testUserId = INVALID_USER_ID; 286 287 try { 288 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 289 PERMISSION_MANAGE_ACTIVITY_TASKS, 290 PERMISSION_REMOVE_TASKS, 291 PERMISSION_REAL_GET_TASKS, 292 PERMISSION_INTERACT_ACROSS_USERS_FULL); 293 294 testUserId = createUser(CTS_CAR_TEST_USER_NAME); 295 startUser(testUserId); 296 297 switchUser(testUserId); 298 waitUntilUserCurrent(testUserId); 299 300 installPackageForUser(testUserId); 301 302 launchSimpleActivityInCurrentUser(); 303 assertIsAppRunning(true, SIMPLE_APP_PACKAGE_NAME); 304 305 switchUser(initialCurrentUserId); 306 waitUntilUserCurrent(initialCurrentUserId); 307 308 stopAllTasksForUser(testUserId); 309 assertIsAppRunning(false, SIMPLE_APP_PACKAGE_NAME); 310 311 removeUser(testUserId); 312 testUserId = INVALID_USER_ID; 313 } finally { 314 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 315 316 deepCleanTestStopAllTasksForUser(testUserId, initialCurrentUserId); 317 } 318 } 319 deepCleanTestStopAllTasksForUser(int testUserId, int initialCurrentUserId)320 private void deepCleanTestStopAllTasksForUser(int testUserId, int initialCurrentUserId) 321 throws Exception { 322 try { 323 if (initialCurrentUserId != getCurrentUserId()) { 324 switchUser(initialCurrentUserId); 325 waitUntilUserCurrent(initialCurrentUserId); 326 } 327 } finally { 328 if (testUserId != INVALID_USER_ID) { 329 removeUser(testUserId); 330 } 331 } 332 } 333 assertComponentPermissionGranted(String permission)334 private void assertComponentPermissionGranted(String permission) throws Exception { 335 assertThat(ActivityManagerHelper.checkComponentPermission(permission, 336 Process.myUid(), /* owningUid= */ OWNING_UID, /* exported= */ true)) 337 .isEqualTo(PackageManager.PERMISSION_GRANTED); 338 } 339 assertComponentPermissionNotGranted(String permission)340 private void assertComponentPermissionNotGranted(String permission) throws Exception { 341 assertThat(ActivityManagerHelper.checkComponentPermission(permission, 342 Process.myUid(), /* owningUid= */ OWNING_UID, /* exported= */ true)) 343 .isEqualTo(PackageManager.PERMISSION_DENIED); 344 } 345 346 private static final class ProcessObserverCallbackTestImpl extends ProcessObserverCallback { 347 private final CountDownLatch mLatch = new CountDownLatch(1); 348 349 // Use onForegroundActivitiesChanged(), because onProcessDied() can be called 350 // in very long time later even if the task was removed. 351 @Override onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities)352 public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) { 353 Log.d(TAG, "onForegroundActivitiesChanged: pid " + pid + " uid " + uid); 354 mLatch.countDown(); 355 } 356 waitForForegroundActivitiesChanged()357 public boolean waitForForegroundActivitiesChanged() throws Exception { 358 return mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS); 359 } 360 } 361 launchSimpleActivity()362 private void launchSimpleActivity() { 363 ComponentName simpleActivity = new ComponentName( 364 SIMPLE_APP_PACKAGE_NAME, SIMPLE_ACTIVITY_NAME); 365 Intent intent = new Intent() 366 .setComponent(simpleActivity) 367 .addFlags(FLAG_ACTIVITY_NEW_TASK); 368 mContext.startActivity(intent, /* options = */ null); 369 waitAndAssertResumedAndFocusedActivityOnDisplay(simpleActivity, DEFAULT_DISPLAY, 370 "Activity isn't resumed"); 371 } 372 373 // launchSimpleActivity in the current user space via the car shell instead of the calling user. 374 // The calling user could be in the background. launchSimpleActivityInCurrentUser()375 private static void launchSimpleActivityInCurrentUser() { 376 Log.d(TAG, "launchSimpleActivityInCurrentUser: " + START_SIMPLE_ACTIVITY_COMMAND); 377 String retStr = SystemUtil.runShellCommand(START_SIMPLE_ACTIVITY_COMMAND); 378 Log.d(TAG, "launchSimpleActivityInCurrentUser return: " + retStr); 379 } 380 installPackageForUser(int userId)381 private static void installPackageForUser(int userId) { 382 String fullCommand = String.format("pm install-existing --user %d %s", 383 userId, SIMPLE_APP_PACKAGE_NAME); 384 Log.d(TAG, "installPackageForUser: " + fullCommand); 385 String retStr = SystemUtil.runShellCommand(fullCommand); 386 Log.d(TAG, "installPackageForUser return: " + retStr); 387 } 388 assertIsAppRunning(boolean isRunning, String pkgName)389 private void assertIsAppRunning(boolean isRunning, String pkgName) { 390 PollingCheck.waitFor(TIMEOUT_MS, () -> isAppRunning(pkgName) == isRunning); 391 } 392 isAppRunning(String pkgName)393 private boolean isAppRunning(String pkgName) { 394 ActivityManager am = mContext.getSystemService(ActivityManager.class); 395 396 List<ActivityManager.RunningTaskInfo> runningTasks = am.getRunningTasks(MAX_NUM_TASKS); 397 398 for (ActivityManager.RunningTaskInfo taskInfo : runningTasks) { 399 if (pkgName.equals(taskInfo.baseActivity.getPackageName())) { 400 return true; 401 } 402 } 403 404 return false; 405 } 406 launchTestActivity(Class<T> type)407 private <T> T launchTestActivity(Class<T> type) { 408 Intent startIntent = new Intent(mContext, type) 409 .addFlags(FLAG_ACTIVITY_NEW_TASK); 410 411 Activity testActivity = (Activity) mInstrumentation 412 .startActivitySync(startIntent, /* options = */ null); 413 414 ComponentName testActivityName = testActivity.getComponentName(); 415 waitAndAssertResumedAndFocusedActivityOnDisplay(testActivityName, DEFAULT_DISPLAY, 416 "Activity must be resumed"); 417 418 return type.cast(testActivity); 419 } 420 421 // The logging order of the Activities follows the stack order. The first Activity 422 // in the parameter list is logged at last. logActivityStack(String msg, Activity... activityStack)423 private static void logActivityStack(String msg, Activity... activityStack) { 424 for (int index = activityStack.length - 1; index >= 0; index--) { 425 String logMsg = String.format("%s\tindex=%d taskId=%d", 426 msg, index, activityStack[index].getTaskId()); 427 Log.d(TAG, logMsg); 428 } 429 } 430 doesTaskExist(int taskId)431 private boolean doesTaskExist(int taskId) { 432 boolean retVal = false; 433 try { 434 mInstrumentation.getUiAutomation().adoptShellPermissionIdentity( 435 PERMISSION_REMOVE_TASKS); 436 ActivityManager am = mContext.getSystemService(ActivityManager.class); 437 List<ActivityManager.RunningTaskInfo> taskList = am.getRunningTasks(MAX_NUM_TASKS); 438 for (TaskInfo taskInfo : taskList) { 439 if (taskInfo.taskId == taskId) { 440 retVal = true; 441 break; 442 } 443 } 444 } finally { 445 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 446 } 447 return retVal; 448 } 449 450 public static final class ActivityA extends ActivityManagerTestActivityBase { 451 } 452 453 public static final class ActivityB extends ActivityManagerTestActivityBase { 454 } 455 456 public static final class ActivityC extends ActivityManagerTestActivityBase { 457 } 458 waitAndAssertFocusStatusChanged(ActivityManagerTestActivityBase activity, boolean expectedStatus)459 private static void waitAndAssertFocusStatusChanged(ActivityManagerTestActivityBase activity, 460 boolean expectedStatus) throws Exception { 461 PollingCheck.waitFor(TIMEOUT_MS, () -> activity.hasFocus() == expectedStatus); 462 } 463 createUser(String userName)464 private static int createUser(String userName) throws Exception { 465 Log.d(TAG, "createUser: " + userName); 466 String retStr = SystemUtil.runShellCommand(CREATE_USER_COMMAND + userName); 467 Pattern userIdPattern = Pattern.compile("id=(\\d+)"); 468 Matcher matcher = userIdPattern.matcher(retStr); 469 if (!matcher.find()) { 470 throw new Exception("failed to create user: " + userName); 471 } 472 return Integer.parseInt(matcher.group(1)); 473 } 474 switchUser(int userId)475 private static void switchUser(int userId) throws Exception { 476 Log.d(TAG, "switchUser: " + userId); 477 String retStr = SystemUtil.runShellCommand(SWITCH_USER_COMMAND + userId); 478 if (!retStr.contains("STATUS_SUCCESSFUL")) { 479 throw new Exception("failed to switch to user: " + userId); 480 } 481 Log.d(TAG, "switchUser: " + retStr); 482 } 483 removeUser(int userId)484 private static void removeUser(int userId) throws Exception { 485 Log.d(TAG, "removeUser: " + userId); 486 String retStr = SystemUtil.runShellCommand(REMOVE_USER_COMMAND + userId); 487 if (!retStr.contains("STATUS_SUCCESSFUL")) { 488 throw new Exception("failed to remove user: " + userId); 489 } 490 Log.d(TAG, "removeUser: " + retStr); 491 } 492 startUser(int userId)493 private static void startUser(int userId) throws Exception { 494 String retStr = SystemUtil.runShellCommand(START_USER_COMMAND + userId); 495 if (!retStr.contains("Success: user started")) { 496 throw new Exception("failed to start user: " + userId + " with return: " + retStr); 497 } 498 Log.d(TAG, "startUser: " + retStr); 499 } 500 getCurrentUserId()501 private static int getCurrentUserId() { 502 String retStr = SystemUtil.runShellCommand(GET_CURRENT_USER_COMMAND); 503 Log.d(TAG, "getCurrentUserId: " + retStr); 504 return Integer.parseInt(retStr.trim()); 505 } 506 waitUntilUserCurrent(int userId)507 private static void waitUntilUserCurrent(int userId) throws Exception { 508 PollingCheck.waitFor(TIMEOUT_MS, () -> userId == getCurrentUserId()); 509 } 510 511 // need to get the permission in the same user stopAllTasksForUser(int userId)512 private static void stopAllTasksForUser(int userId) { 513 ActivityManagerHelper.stopAllTasksForUser(userId); 514 } 515 checkSimpleActivityExistence()516 private static boolean checkSimpleActivityExistence() { 517 boolean foundSimpleActivity = false; 518 519 Log.d(TAG, "checkSimpleActivityExistence --- Begin"); 520 WindowManagerState wmState = new WindowManagerState(); 521 wmState.computeState(); 522 for (ActivityType activityType : ActivityType.values()) { 523 if (findSimpleActivityInType(activityType, wmState)) { 524 foundSimpleActivity = true; 525 break; 526 } 527 } 528 Log.d(TAG, "checkSimpleActivityExistence --- End with --- " + foundSimpleActivity); 529 530 return foundSimpleActivity; 531 } 532 findSimpleActivityInType(ActivityType activityType, WindowManagerState wmState)533 private static boolean findSimpleActivityInType(ActivityType activityType, 534 WindowManagerState wmState) { 535 boolean foundRootTask = false; 536 boolean foundSimpleActivity = false; 537 538 WindowManagerState.Task rootTask = 539 wmState.getRootTaskByActivityType(activityType.ordinal()); 540 if (rootTask != null) { 541 foundRootTask = true; 542 List<WindowManagerState.Activity> allActivities = rootTask.getActivities(); 543 if (rootTask.getActivity(SIMPLE_ACTIVITY_COMPONENT_NAME) != null) { 544 foundSimpleActivity = true; 545 } 546 547 // for debugging purpose only 548 for (WindowManagerState.Activity act : allActivities) { 549 Log.d(TAG, activityType.name() + ": activity name -- " + act.getName()); 550 } 551 } 552 553 Log.d(TAG, activityType.name() + " has simple activity root task:" + foundRootTask); 554 Log.d(TAG, activityType.name() + " has simple activity: " + foundSimpleActivity); 555 556 return foundSimpleActivity; 557 } 558 } 559