1 /*
2  * Copyright (C) 2018 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 com.android.server.wm;
18 
19 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
20 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
21 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
22 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
23 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
24 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
25 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
26 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
27 
28 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
29 
30 import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
31 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
32 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
33 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
34 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
35 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
36 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
37 
38 import android.app.ActivityManager;
39 import android.app.ActivityOptions;
40 import android.app.IApplicationThread;
41 import android.app.WindowConfiguration;
42 import android.content.ComponentName;
43 import android.content.Context;
44 import android.content.Intent;
45 import android.content.pm.ActivityInfo;
46 import android.content.pm.ApplicationInfo;
47 import android.content.res.Configuration;
48 import android.os.Build;
49 import android.os.Bundle;
50 import android.os.UserHandle;
51 import android.service.voice.IVoiceInteractionSession;
52 import android.view.SurfaceControl;
53 import android.window.ITaskOrganizer;
54 import android.window.WindowContainerToken;
55 
56 import com.android.server.AttributeCache;
57 
58 import org.junit.Before;
59 import org.junit.BeforeClass;
60 
61 /**
62  * A base class to handle common operations in activity related unit tests.
63  */
64 class ActivityTestsBase extends SystemServiceTestsBase {
65     final Context mContext = getInstrumentation().getTargetContext();
66 
67     ActivityTaskManagerService mService;
68     RootWindowContainer mRootWindowContainer;
69     ActivityStackSupervisor mSupervisor;
70 
71     // Default package name
72     static final String DEFAULT_COMPONENT_PACKAGE_NAME = "com.foo";
73 
74     // Default base activity name
75     private static final String DEFAULT_COMPONENT_CLASS_NAME = ".BarActivity";
76 
77     @BeforeClass
setUpOnceBase()78     public static void setUpOnceBase() {
79         AttributeCache.init(getInstrumentation().getTargetContext());
80     }
81 
82     @Before
setUpBase()83     public void setUpBase() {
84         mService = mSystemServicesTestRule.getActivityTaskManagerService();
85         mSupervisor = mService.mStackSupervisor;
86         mRootWindowContainer = mService.mRootWindowContainer;
87     }
88 
89     /** Creates and adds a {@link TestDisplayContent} to supervisor at the given position. */
addNewDisplayContentAt(int position)90     TestDisplayContent addNewDisplayContentAt(int position) {
91         return new TestDisplayContent.Builder(mService, 1000, 1500).setPosition(position).build();
92     }
93 
94     /** Sets the default minimum task size to 1 so that tests can use small task sizes */
removeGlobalMinSizeRestriction()95     public void removeGlobalMinSizeRestriction() {
96         mService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
97     }
98 
99     /**
100      * Builder for creating new activities.
101      */
102     protected static class ActivityBuilder {
103         // An id appended to the end of the component name to make it unique
104         private static int sCurrentActivityId = 0;
105 
106         private final ActivityTaskManagerService mService;
107 
108         private ComponentName mComponent;
109         private String mTargetActivity;
110         private Task mTask;
111         private String mProcessName = "name";
112         private String mAffinity;
113         private int mUid = 12345;
114         private boolean mCreateTask;
115         private ActivityStack mStack;
116         private int mActivityFlags;
117         private int mLaunchMode;
118         private int mResizeMode = RESIZE_MODE_RESIZEABLE;
119         private float mMaxAspectRatio;
120         private int mScreenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
121         private boolean mLaunchTaskBehind;
122         private int mConfigChanges;
123         private int mLaunchedFromPid;
124         private int mLaunchedFromUid;
125         private WindowProcessController mWpc;
126         private Bundle mIntentExtras;
127 
ActivityBuilder(ActivityTaskManagerService service)128         ActivityBuilder(ActivityTaskManagerService service) {
129             mService = service;
130         }
131 
setComponent(ComponentName component)132         ActivityBuilder setComponent(ComponentName component) {
133             mComponent = component;
134             return this;
135         }
136 
setTargetActivity(String targetActivity)137         ActivityBuilder setTargetActivity(String targetActivity) {
138             mTargetActivity = targetActivity;
139             return this;
140         }
141 
setIntentExtras(Bundle extras)142         ActivityBuilder setIntentExtras(Bundle extras) {
143             mIntentExtras = extras;
144             return this;
145         }
146 
getDefaultComponent()147         static ComponentName getDefaultComponent() {
148             return ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
149                     DEFAULT_COMPONENT_PACKAGE_NAME);
150         }
151 
setTask(Task task)152         ActivityBuilder setTask(Task task) {
153             mTask = task;
154             return this;
155         }
156 
setActivityFlags(int flags)157         ActivityBuilder setActivityFlags(int flags) {
158             mActivityFlags = flags;
159             return this;
160         }
161 
setLaunchMode(int launchMode)162         ActivityBuilder setLaunchMode(int launchMode) {
163             mLaunchMode = launchMode;
164             return this;
165         }
166 
setStack(ActivityStack stack)167         ActivityBuilder setStack(ActivityStack stack) {
168             mStack = stack;
169             return this;
170         }
171 
setCreateTask(boolean createTask)172         ActivityBuilder setCreateTask(boolean createTask) {
173             mCreateTask = createTask;
174             return this;
175         }
176 
setProcessName(String name)177         ActivityBuilder setProcessName(String name) {
178             mProcessName = name;
179             return this;
180         }
181 
setUid(int uid)182         ActivityBuilder setUid(int uid) {
183             mUid = uid;
184             return this;
185         }
186 
setResizeMode(int resizeMode)187         ActivityBuilder setResizeMode(int resizeMode) {
188             mResizeMode = resizeMode;
189             return this;
190         }
191 
setMaxAspectRatio(float maxAspectRatio)192         ActivityBuilder setMaxAspectRatio(float maxAspectRatio) {
193             mMaxAspectRatio = maxAspectRatio;
194             return this;
195         }
196 
setScreenOrientation(int screenOrientation)197         ActivityBuilder setScreenOrientation(int screenOrientation) {
198             mScreenOrientation = screenOrientation;
199             return this;
200         }
201 
setLaunchTaskBehind(boolean launchTaskBehind)202         ActivityBuilder setLaunchTaskBehind(boolean launchTaskBehind) {
203             mLaunchTaskBehind = launchTaskBehind;
204             return this;
205         }
206 
setConfigChanges(int configChanges)207         ActivityBuilder setConfigChanges(int configChanges) {
208             mConfigChanges = configChanges;
209             return this;
210         }
211 
setLaunchedFromPid(int pid)212         ActivityBuilder setLaunchedFromPid(int pid) {
213             mLaunchedFromPid = pid;
214             return this;
215         }
216 
setLaunchedFromUid(int uid)217         ActivityBuilder setLaunchedFromUid(int uid) {
218             mLaunchedFromUid = uid;
219             return this;
220         }
221 
setUseProcess(WindowProcessController wpc)222         ActivityBuilder setUseProcess(WindowProcessController wpc) {
223             mWpc = wpc;
224             return this;
225         }
226 
setAffinity(String affinity)227         ActivityBuilder setAffinity(String affinity) {
228             mAffinity = affinity;
229             return this;
230         }
231 
build()232         ActivityRecord build() {
233             SystemServicesTestRule.checkHoldsLock(mService.mGlobalLock);
234             try {
235                 mService.deferWindowLayout();
236                 return buildInner();
237             } finally {
238                 mService.continueWindowLayout();
239             }
240         }
241 
buildInner()242         ActivityRecord buildInner() {
243             if (mComponent == null) {
244                 final int id = sCurrentActivityId++;
245                 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
246                         DEFAULT_COMPONENT_CLASS_NAME + id);
247             }
248 
249             if (mCreateTask) {
250                 mTask = new TaskBuilder(mService.mStackSupervisor)
251                         .setComponent(mComponent)
252                         .setStack(mStack).build();
253             } else if (mTask == null && mStack != null && DisplayContent.alwaysCreateStack(
254                     mStack.getWindowingMode(), mStack.getActivityType())) {
255                 // The stack can be the task root.
256                 mTask = mStack;
257             }
258 
259             Intent intent = new Intent();
260             intent.setComponent(mComponent);
261             if (mIntentExtras != null) {
262                 intent.putExtras(mIntentExtras);
263             }
264             final ActivityInfo aInfo = new ActivityInfo();
265             aInfo.applicationInfo = new ApplicationInfo();
266             aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
267             aInfo.applicationInfo.packageName = mComponent.getPackageName();
268             aInfo.applicationInfo.uid = mUid;
269             aInfo.processName = mProcessName;
270             aInfo.packageName = mComponent.getPackageName();
271             aInfo.name = mComponent.getClassName();
272             if (mTargetActivity != null) {
273                 aInfo.targetActivity = mTargetActivity;
274             }
275             aInfo.flags |= mActivityFlags;
276             aInfo.launchMode = mLaunchMode;
277             aInfo.resizeMode = mResizeMode;
278             aInfo.maxAspectRatio = mMaxAspectRatio;
279             aInfo.screenOrientation = mScreenOrientation;
280             aInfo.configChanges |= mConfigChanges;
281             aInfo.taskAffinity = mAffinity;
282 
283             ActivityOptions options = null;
284             if (mLaunchTaskBehind) {
285                 options = ActivityOptions.makeTaskLaunchBehind();
286             }
287 
288             final ActivityRecord activity = new ActivityRecord(mService, null /* caller */,
289                     mLaunchedFromPid /* launchedFromPid */, mLaunchedFromUid /* launchedFromUid */,
290                     null, null, intent, null, aInfo /*aInfo*/, new Configuration(),
291                     null /* resultTo */, null /* resultWho */, 0 /* reqCode */,
292                     false /*componentSpecified*/, false /* rootVoiceInteraction */,
293                     mService.mStackSupervisor, options, null /* sourceRecord */);
294             spyOn(activity);
295             if (mTask != null) {
296                 // fullscreen value is normally read from resources in ctor, so for testing we need
297                 // to set it somewhere else since we can't mock resources.
298                 doReturn(true).when(activity).occludesParent();
299                 doReturn(true).when(activity).fillsParent();
300                 mTask.addChild(activity);
301                 // Make visible by default...
302                 activity.setVisible(true);
303             }
304 
305             final WindowProcessController wpc;
306             if (mWpc != null) {
307                 wpc = mWpc;
308             } else {
309                 wpc = new WindowProcessController(mService,
310                         mService.mContext.getApplicationInfo(), mProcessName, mUid,
311                         UserHandle.getUserId(12345), mock(Object.class),
312                         mock(WindowProcessListener.class));
313                 wpc.setThread(mock(IApplicationThread.class));
314             }
315             wpc.setThread(mock(IApplicationThread.class));
316             activity.setProcess(wpc);
317             doReturn(wpc).when(mService).getProcessController(
318                     activity.processName, activity.info.applicationInfo.uid);
319 
320             // Resume top activities to make sure all other signals in the system are connected.
321             mService.mRootWindowContainer.resumeFocusedStacksTopActivities();
322             return activity;
323         }
324     }
325 
326     /**
327      * Builder for creating new tasks.
328      */
329     protected static class TaskBuilder {
330         private final ActivityStackSupervisor mSupervisor;
331 
332         private ComponentName mComponent;
333         private String mPackage;
334         private int mFlags = 0;
335         // Task id 0 is reserved in ARC for the home app.
336         private int mTaskId = SystemServicesTestRule.sNextTaskId++;
337         private int mUserId = 0;
338         private IVoiceInteractionSession mVoiceSession;
339         private boolean mCreateStack = true;
340 
341         private ActivityStack mStack;
342         private TaskDisplayArea mTaskDisplayArea;
343 
TaskBuilder(ActivityStackSupervisor supervisor)344         TaskBuilder(ActivityStackSupervisor supervisor) {
345             mSupervisor = supervisor;
346         }
347 
setComponent(ComponentName component)348         TaskBuilder setComponent(ComponentName component) {
349             mComponent = component;
350             return this;
351         }
352 
setPackage(String packageName)353         TaskBuilder setPackage(String packageName) {
354             mPackage = packageName;
355             return this;
356         }
357 
358         /**
359          * Set to {@code true} by default, set to {@code false} to prevent the task from
360          * automatically creating a parent stack.
361          */
setCreateStack(boolean createStack)362         TaskBuilder setCreateStack(boolean createStack) {
363             mCreateStack = createStack;
364             return this;
365         }
366 
setVoiceSession(IVoiceInteractionSession session)367         TaskBuilder setVoiceSession(IVoiceInteractionSession session) {
368             mVoiceSession = session;
369             return this;
370         }
371 
setFlags(int flags)372         TaskBuilder setFlags(int flags) {
373             mFlags = flags;
374             return this;
375         }
376 
setTaskId(int taskId)377         TaskBuilder setTaskId(int taskId) {
378             mTaskId = taskId;
379             return this;
380         }
381 
setUserId(int userId)382         TaskBuilder setUserId(int userId) {
383             mUserId = userId;
384             return this;
385         }
386 
setStack(ActivityStack stack)387         TaskBuilder setStack(ActivityStack stack) {
388             mStack = stack;
389             return this;
390         }
391 
setDisplay(DisplayContent display)392         TaskBuilder setDisplay(DisplayContent display) {
393             mTaskDisplayArea = display.getDefaultTaskDisplayArea();
394             return this;
395         }
396 
build()397         Task build() {
398             SystemServicesTestRule.checkHoldsLock(mSupervisor.mService.mGlobalLock);
399 
400             if (mStack == null && mCreateStack) {
401                 TaskDisplayArea displayArea = mTaskDisplayArea != null ? mTaskDisplayArea
402                         : mSupervisor.mRootWindowContainer.getDefaultTaskDisplayArea();
403                 mStack = displayArea.createStack(
404                         WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
405                 spyOn(mStack);
406             }
407 
408             final ActivityInfo aInfo = new ActivityInfo();
409             aInfo.applicationInfo = new ApplicationInfo();
410             aInfo.applicationInfo.packageName = mPackage;
411 
412             Intent intent = new Intent();
413             if (mComponent == null) {
414                 mComponent = ComponentName.createRelative(DEFAULT_COMPONENT_PACKAGE_NAME,
415                         DEFAULT_COMPONENT_CLASS_NAME);
416             }
417 
418             intent.setComponent(mComponent);
419             intent.setFlags(mFlags);
420 
421             final Task task = new ActivityStack(mSupervisor.mService, mTaskId, aInfo,
422                     intent /*intent*/, mVoiceSession, null /*_voiceInteractor*/,
423                     null /*taskDescription*/, mStack);
424             spyOn(task);
425             task.mUserId = mUserId;
426 
427             if (mStack != null) {
428                 mStack.moveToFront("test");
429                 mStack.addChild(task, true, true);
430             }
431 
432             return task;
433         }
434     }
435 
436     static class StackBuilder {
437         private final RootWindowContainer mRootWindowContainer;
438         private DisplayContent mDisplay;
439         private TaskDisplayArea mTaskDisplayArea;
440         private int mStackId = -1;
441         private int mWindowingMode = WINDOWING_MODE_UNDEFINED;
442         private int mActivityType = ACTIVITY_TYPE_STANDARD;
443         private boolean mOnTop = true;
444         private boolean mCreateActivity = true;
445         private ActivityInfo mInfo;
446         private Intent mIntent;
447 
StackBuilder(RootWindowContainer root)448         StackBuilder(RootWindowContainer root) {
449             mRootWindowContainer = root;
450             mDisplay = mRootWindowContainer.getDefaultDisplay();
451             mTaskDisplayArea = mDisplay.getDefaultTaskDisplayArea();
452         }
453 
setWindowingMode(int windowingMode)454         StackBuilder setWindowingMode(int windowingMode) {
455             mWindowingMode = windowingMode;
456             return this;
457         }
458 
setActivityType(int activityType)459         StackBuilder setActivityType(int activityType) {
460             mActivityType = activityType;
461             return this;
462         }
463 
setStackId(int stackId)464         StackBuilder setStackId(int stackId) {
465             mStackId = stackId;
466             return this;
467         }
468 
469         /**
470          * Set the parent {@link DisplayContent} and use the default task display area. Overrides
471          * the task display area, if was set before.
472          */
setDisplay(DisplayContent display)473         StackBuilder setDisplay(DisplayContent display) {
474             mDisplay = display;
475             mTaskDisplayArea = mDisplay.getDefaultTaskDisplayArea();
476             return this;
477         }
478 
479         /** Set the parent {@link TaskDisplayArea}. Overrides the display, if was set before. */
setTaskDisplayArea(TaskDisplayArea taskDisplayArea)480         StackBuilder setTaskDisplayArea(TaskDisplayArea taskDisplayArea) {
481             mTaskDisplayArea = taskDisplayArea;
482             mDisplay = mTaskDisplayArea.mDisplayContent;
483             return this;
484         }
485 
setOnTop(boolean onTop)486         StackBuilder setOnTop(boolean onTop) {
487             mOnTop = onTop;
488             return this;
489         }
490 
setCreateActivity(boolean createActivity)491         StackBuilder setCreateActivity(boolean createActivity) {
492             mCreateActivity = createActivity;
493             return this;
494         }
495 
setActivityInfo(ActivityInfo info)496         StackBuilder setActivityInfo(ActivityInfo info) {
497             mInfo = info;
498             return this;
499         }
500 
setIntent(Intent intent)501         StackBuilder setIntent(Intent intent) {
502             mIntent = intent;
503             return this;
504         }
505 
build()506         ActivityStack build() {
507             SystemServicesTestRule.checkHoldsLock(mRootWindowContainer.mWmService.mGlobalLock);
508 
509             final int stackId = mStackId >= 0 ? mStackId : mTaskDisplayArea.getNextStackId();
510             final ActivityStack stack = mTaskDisplayArea.createStackUnchecked(
511                     mWindowingMode, mActivityType, stackId, mOnTop, mInfo, mIntent,
512                     false /* createdByOrganizer */);
513             final ActivityStackSupervisor supervisor = mRootWindowContainer.mStackSupervisor;
514 
515             if (mCreateActivity) {
516                 new ActivityBuilder(supervisor.mService)
517                         .setCreateTask(true)
518                         .setStack(stack)
519                         .build();
520                 if (mOnTop) {
521                     // We move the task to front again in order to regain focus after activity
522                     // added to the stack. Or {@link DisplayContent#mPreferredTopFocusableStack}
523                     // could be other stacks (e.g. home stack).
524                     stack.moveToFront("createActivityStack");
525                 } else {
526                     stack.moveToBack("createActivityStack", null);
527                 }
528             }
529             spyOn(stack);
530 
531             doNothing().when(stack).startActivityLocked(
532                     any(), any(), anyBoolean(), anyBoolean(), any());
533 
534             return stack;
535         }
536 
537     }
538 
539     static class TestSplitOrganizer extends ITaskOrganizer.Stub {
540         final ActivityTaskManagerService mService;
541         Task mPrimary;
542         Task mSecondary;
543         boolean mInSplit = false;
544         // moves everything to secondary. Most tests expect this since sysui usually does it.
545         boolean mMoveToSecondaryOnEnter = true;
546         int mDisplayId;
TestSplitOrganizer(ActivityTaskManagerService service, int displayId)547         TestSplitOrganizer(ActivityTaskManagerService service, int displayId) {
548             mService = service;
549             mDisplayId = displayId;
550             mService.mTaskOrganizerController.registerTaskOrganizer(this,
551                     WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
552             mService.mTaskOrganizerController.registerTaskOrganizer(this,
553                     WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
554             WindowContainerToken primary = mService.mTaskOrganizerController.createRootTask(
555                     displayId, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY).token;
556             mPrimary = WindowContainer.fromBinder(primary.asBinder()).asTask();
557             WindowContainerToken secondary = mService.mTaskOrganizerController.createRootTask(
558                     displayId, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY).token;
559             mSecondary = WindowContainer.fromBinder(secondary.asBinder()).asTask();
560         }
TestSplitOrganizer(ActivityTaskManagerService service)561         TestSplitOrganizer(ActivityTaskManagerService service) {
562             this(service,
563                     service.mStackSupervisor.mRootWindowContainer.getDefaultDisplay().mDisplayId);
564         }
setMoveToSecondaryOnEnter(boolean move)565         public void setMoveToSecondaryOnEnter(boolean move) {
566             mMoveToSecondaryOnEnter = move;
567         }
568         @Override
onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash)569         public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
570         }
571         @Override
onTaskVanished(ActivityManager.RunningTaskInfo info)572         public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
573         }
574         @Override
onTaskInfoChanged(ActivityManager.RunningTaskInfo info)575         public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
576             if (mInSplit) {
577                 return;
578             }
579             if (info.topActivityType == ACTIVITY_TYPE_UNDEFINED) {
580                 // Not populated
581                 return;
582             }
583             if (info.configuration.windowConfiguration.getWindowingMode()
584                     != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
585                 return;
586             }
587             mInSplit = true;
588             if (!mMoveToSecondaryOnEnter) {
589                 return;
590             }
591             mService.mTaskOrganizerController.setLaunchRoot(mDisplayId,
592                     mSecondary.mRemoteToken.toWindowContainerToken());
593             DisplayContent dc = mService.mRootWindowContainer.getDisplayContent(mDisplayId);
594             for (int tdaNdx = dc.getTaskDisplayAreaCount() - 1; tdaNdx >= 0; --tdaNdx) {
595                 final TaskDisplayArea taskDisplayArea = dc.getTaskDisplayAreaAt(tdaNdx);
596                 for (int sNdx = taskDisplayArea.getStackCount() - 1; sNdx >= 0; --sNdx) {
597                     final ActivityStack stack = taskDisplayArea.getStackAt(sNdx);
598                     if (!WindowConfiguration.isSplitScreenWindowingMode(stack.getWindowingMode())) {
599                         stack.reparent(mSecondary, POSITION_BOTTOM);
600                     }
601                 }
602             }
603         }
604         @Override
onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo)605         public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo taskInfo) {
606         }
607     };
608 }
609