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