• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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