Merge "Tracking launch activity to decide next splash screen style." into sc-dev

This commit is contained in:
Wei Sheng Shih
2021-05-21 04:42:00 +00:00
committed by Android (Google) Code Review
9 changed files with 198 additions and 75 deletions

View File

@@ -103,7 +103,7 @@ public final class StartingWindowInfo implements Parcelable {
TYPE_PARAMETER_PROCESS_RUNNING,
TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT,
TYPE_PARAMETER_ACTIVITY_CREATED,
TYPE_PARAMETER_SAME_PACKAGE
TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN
})
public @interface StartingTypeParams {}
@@ -121,7 +121,7 @@ public final class StartingWindowInfo implements Parcelable {
/** @hide */
public static final int TYPE_PARAMETER_ACTIVITY_CREATED = 0x00000010;
/** @hide */
public static final int TYPE_PARAMETER_SAME_PACKAGE = 0x00000020;
public static final int TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN = 0x00000020;
/**
* The parameters which effect the starting window type.

View File

@@ -25,8 +25,8 @@ import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_SAME_PACKAGE;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;
import static com.android.wm.shell.startingsurface.StartingWindowController.DEBUG_SPLASH_SCREEN;
import static com.android.wm.shell.startingsurface.StartingWindowController.DEBUG_TASK_SNAPSHOT;
@@ -52,7 +52,8 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor
final boolean processRunning = (parameter & TYPE_PARAMETER_PROCESS_RUNNING) != 0;
final boolean allowTaskSnapshot = (parameter & TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT) != 0;
final boolean activityCreated = (parameter & TYPE_PARAMETER_ACTIVITY_CREATED) != 0;
final boolean samePackage = (parameter & TYPE_PARAMETER_SAME_PACKAGE) != 0;
final boolean useEmptySplashScreen =
(parameter & TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN) != 0;
final boolean topIsHome = windowInfo.taskInfo.topActivityType == ACTIVITY_TYPE_HOME;
if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) {
@@ -61,19 +62,19 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor
+ " processRunning " + processRunning
+ " allowTaskSnapshot " + allowTaskSnapshot
+ " activityCreated " + activityCreated
+ " samePackage " + samePackage
+ " useEmptySplashScreen " + useEmptySplashScreen
+ " topIsHome " + topIsHome);
}
if (!topIsHome) {
if (!processRunning) {
return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
return useEmptySplashScreen
? STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
: STARTING_WINDOW_TYPE_SPLASH_SCREEN;
}
if (newTask) {
if (samePackage) {
return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
} else {
return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
}
return useEmptySplashScreen
? STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
: STARTING_WINDOW_TYPE_SPLASH_SCREEN;
}
if (taskSwitch && !activityCreated) {
return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
@@ -84,7 +85,7 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor
return STARTING_WINDOW_TYPE_SNAPSHOT;
}
if (!topIsHome) {
return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
}
}
return STARTING_WINDOW_TYPE_NONE;

View File

@@ -1170,7 +1170,7 @@ class ActivityClientController extends IActivityClientController.Stub {
final boolean activityIsBaseActivity = baseIntent != null
&& r.mActivityComponent.equals(baseIntent.getComponent());
baseActivityIntent = activityIsBaseActivity ? r.intent : null;
launchedFromHome = r.launchedFromHomeProcess;
launchedFromHome = r.isLaunchSourceType(ActivityRecord.LAUNCH_SOURCE_TYPE_HOME);
}
// If the activity is one of the main entry points for the application, then we should

View File

@@ -437,7 +437,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final int launchedFromUid; // always the uid who started the activity.
final String launchedFromPackage; // always the package who started the activity.
final @Nullable String launchedFromFeatureId; // always the feature in launchedFromPackage
final boolean launchedFromHomeProcess; // as per original caller
private final int mLaunchSourceType; // original launch source type
final Intent intent; // the original intent that generated us
final String shortComponentName; // the short component name of the intent
final String resolvedType; // as per original caller;
@@ -540,6 +540,25 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
static final int STARTING_WINDOW_SHOWN = 1;
static final int STARTING_WINDOW_REMOVED = 2;
int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
// Tracking splash screen status from previous activity
boolean mSplashScreenStyleEmpty = false;
static final int LAUNCH_SOURCE_TYPE_SYSTEM = 1;
static final int LAUNCH_SOURCE_TYPE_HOME = 2;
static final int LAUNCH_SOURCE_TYPE_SYSTEMUI = 3;
static final int LAUNCH_SOURCE_TYPE_APPLICATION = 4;
/**
* The type of launch source.
*/
@IntDef(prefix = {"LAUNCH_SOURCE_TYPE_"}, value = {
LAUNCH_SOURCE_TYPE_SYSTEM,
LAUNCH_SOURCE_TYPE_HOME,
LAUNCH_SOURCE_TYPE_SYSTEMUI,
LAUNCH_SOURCE_TYPE_APPLICATION
})
@interface LaunchSourceType {}
private boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
// Marking the reason why this activity is being relaunched. Mainly used to track that this
@@ -1582,7 +1601,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
launchedFromUid = _launchedFromUid;
launchedFromPackage = _launchedFromPackage;
launchedFromFeatureId = _launchedFromFeature;
launchedFromHomeProcess = _caller != null && _caller.isHomeProcess();
mLaunchSourceType = determineLaunchSourceType(_launchedFromUid, _caller);
shortComponentName = _intent.getComponent().flattenToShortString();
resolvedType = _resolvedType;
componentSpecified = _componentSpecified;
@@ -1774,12 +1793,34 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return selectedTheme;
}
// Whether this activity launched from system or Home or SystemUI
/**
* @return Whether this {@link ActivityRecord} was launched from a system surface (e.g
* Launcher, Notification,...)
*/
private boolean launchedFromSystemSurface() {
return launchedFromUid == Process.SYSTEM_UID || launchedFromUid == Process.ROOT_UID
|| launchedFromHomeProcess
|| mAtmService.getSysUiServiceComponentLocked().getPackageName().equals(
launchedFromPackage);
return mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEM
|| mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME
|| mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEMUI;
}
boolean isLaunchSourceType(@LaunchSourceType int type) {
return mLaunchSourceType == type;
}
private int determineLaunchSourceType(int launchFromUid, WindowProcessController caller) {
if (launchFromUid == Process.SYSTEM_UID || launchFromUid == Process.ROOT_UID) {
return LAUNCH_SOURCE_TYPE_SYSTEM;
}
if (caller != null) {
if (caller.isHomeProcess()) {
return LAUNCH_SOURCE_TYPE_HOME;
}
if (mAtmService.getSysUiServiceComponentLocked().getPackageName()
.equals(caller.mInfo.packageName)) {
return LAUNCH_SOURCE_TYPE_SYSTEMUI;
}
}
return LAUNCH_SOURCE_TYPE_APPLICATION;
}
private boolean validateStartingWindowTheme(String pkg, int theme) {
@@ -1787,36 +1828,39 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// effect (a full-screen opaque starting window that fades away to the real contents
// when it is ready) does not work for this.
ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Checking theme of starting window: 0x%x", theme);
if (theme != 0) {
AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
com.android.internal.R.styleable.Window,
mWmService.mCurrentUserId);
if (ent == null) {
// Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
// see that.
return false;
}
final boolean windowIsTranslucent = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsTranslucent, false);
final boolean windowIsFloating = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsFloating, false);
final boolean windowShowWallpaper = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false);
final boolean windowDisableStarting = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowDisablePreview, false);
ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
"Translucent=%s Floating=%s ShowWallpaper=%s Disable=%s",
windowIsTranslucent, windowIsFloating, windowShowWallpaper,
windowDisableStarting);
// If this activity is launched from system surface, ignore windowDisableStarting
if (windowIsTranslucent || windowIsFloating
|| (windowDisableStarting && !launchedFromSystemSurface())) {
return false;
}
if (windowShowWallpaper
&& getDisplayContent().mWallpaperController.getWallpaperTarget() != null) {
return false;
}
if (theme == 0) {
return false;
}
final AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
com.android.internal.R.styleable.Window, mWmService.mCurrentUserId);
if (ent == null) {
// Whoops! App doesn't exist. Um. Okay. We'll just pretend like we didn't
// see that.
return false;
}
final boolean windowIsTranslucent = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsTranslucent, false);
final boolean windowIsFloating = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsFloating, false);
final boolean windowShowWallpaper = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false);
final boolean windowDisableStarting = ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowDisablePreview, false);
ProtoLog.v(WM_DEBUG_STARTING_WINDOW,
"Translucent=%s Floating=%s ShowWallpaper=%s Disable=%s",
windowIsTranslucent, windowIsFloating, windowShowWallpaper,
windowDisableStarting);
// If this activity is launched from system surface, ignore windowDisableStarting
if (windowIsTranslucent || windowIsFloating) {
return false;
}
if (windowShowWallpaper
&& getDisplayContent().mWallpaperController.getWallpaperTarget() != null) {
return false;
}
if (windowDisableStarting && !launchedFromSystemSurface()) {
return false;
}
return true;
}
@@ -1846,7 +1890,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
boolean addStartingWindow(String pkg, int resolvedTheme, CompatibilityInfo compatInfo,
CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
boolean allowTaskSnapshot, boolean activityCreated, boolean samePackage) {
boolean allowTaskSnapshot, boolean activityCreated, boolean useEmpty) {
// If the display is frozen, we won't do anything until the actual window is
// displayed so there is no reason to put in the starting window.
if (!okToDisplay()) {
@@ -1868,7 +1912,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
false /* restoreFromDisk */, false /* isLowResolution */);
final int typeParameter = mWmService.mStartingSurfaceController
.makeStartingWindowTypeParameter(newTask, taskSwitch, processRunning,
allowTaskSnapshot, activityCreated, samePackage);
allowTaskSnapshot, activityCreated, useEmpty);
final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
allowTaskSnapshot, activityCreated, snapshot);
@@ -5673,6 +5717,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
firstWindowDrawn = true;
// stop tracking
mSplashScreenStyleEmpty = true;
// We now have a good window to show, remove dead placeholders
removeDeadWindows();
@@ -5691,6 +5737,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
void onStartingWindowDrawn() {
if (task != null) {
mSplashScreenStyleEmpty = true;
task.setHasBeenVisible(true);
}
}
@@ -6097,11 +6144,62 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
void showStartingWindow(boolean taskSwitch) {
showStartingWindow(null /* prev */, false /* newTask */, taskSwitch,
0 /* splashScreenTheme */, true /* samePackage */);
0 /* splashScreenTheme */, null);
}
/**
* Search for the candidate launching activity from currently visible activities.
*
* This activity could be launched from service, so we need to check whether there is existing a
* foreground activity from the same process or same package.
*
*/
private ActivityRecord searchCandidateLaunchingActivity() {
// Get previous activity below self
ActivityRecord below = task.getActivityBelow(this);
if (below == null) {
below = task.getParent().getActivityBelow(this);
}
if (below == null || below.isActivityTypeHome()) {
return null;
}
final WindowProcessController myProcess = app != null
? app : mAtmService.mProcessNames.get(processName, info.applicationInfo.uid);
final WindowProcessController candidateProcess = below.app != null
? below.app
: mAtmService.mProcessNames.get(below.processName,
below.info.applicationInfo.uid);
// same process or same package
if (candidateProcess == myProcess
|| mActivityComponent.getPackageName()
.equals(below.mActivityComponent.getPackageName())) {
return below;
}
return null;
}
private boolean shouldUseEmptySplashScreen(ActivityRecord sourceRecord) {
if (sourceRecord == null) {
sourceRecord = searchCandidateLaunchingActivity();
}
if (sourceRecord != null && !sourceRecord.isActivityTypeHome()) {
return sourceRecord.mSplashScreenStyleEmpty;
}
// If this activity was launched from a system surface, never use an empty splash screen
// Need to check sourceRecord before in case this activity is launched from service.
if (launchedFromSystemSurface()) {
return false;
}
// Otherwise use empty.
return true;
}
void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
int splashScreenTheme, boolean samePackage) {
int splashScreenTheme, ActivityRecord sourceRecord) {
if (mTaskOverlay) {
// We don't show starting window for overlay activities.
return;
@@ -6115,14 +6213,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final CompatibilityInfo compatInfo =
mAtmService.compatibilityInfoForPackageLocked(info.applicationInfo);
mSplashScreenStyleEmpty = shouldUseEmptySplashScreen(sourceRecord);
final int resolvedTheme = evaluateStartingWindowTheme(packageName, theme,
splashScreenTheme);
final boolean shown = addStartingWindow(packageName, resolvedTheme,
compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
allowTaskSnapshot(),
mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
samePackage);
mSplashScreenStyleEmpty);
if (shown) {
mStartingWindowState = STARTING_WINDOW_SHOWN;
}

View File

@@ -1123,6 +1123,14 @@ class ActivityStarter {
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
}
// TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
// Pending intent launched from systemui also depends on caller app
if (callerApp == null && realCallingPid > 0) {
final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
if (wpc != null) {
callerApp = wpc;
}
}
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
@@ -1752,17 +1760,9 @@ class ActivityStarter {
mRootWindowContainer.startPowerModeLaunchIfNeeded(
false /* forceSend */, mStartActivity);
final boolean startFromSamePackage;
if (sourceRecord != null && sourceRecord.mActivityComponent != null) {
startFromSamePackage = mStartActivity.mActivityComponent
.getPackageName().equals(sourceRecord.mActivityComponent.getPackageName());
} else {
startFromSamePackage = false;
}
mTargetRootTask.startActivityLocked(mStartActivity,
topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask,
mKeepCurTransition, mOptions, startFromSamePackage);
mKeepCurTransition, mOptions, sourceRecord);
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTask().topRunningActivityLocked();

View File

@@ -20,8 +20,8 @@ import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_SAME_PACKAGE;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -70,7 +70,7 @@ public class StartingSurfaceController {
int makeStartingWindowTypeParameter(boolean newTask, boolean taskSwitch,
boolean processRunning, boolean allowTaskSnapshot, boolean activityCreated,
boolean samePackage) {
boolean useEmpty) {
int parameter = 0;
if (newTask) {
parameter |= TYPE_PARAMETER_NEW_TASK;
@@ -87,8 +87,8 @@ public class StartingSurfaceController {
if (activityCreated) {
parameter |= TYPE_PARAMETER_ACTIVITY_CREATED;
}
if (samePackage) {
parameter |= TYPE_PARAMETER_SAME_PACKAGE;
if (useEmpty) {
parameter |= TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;
}
return parameter;
}

View File

@@ -6581,7 +6581,7 @@ class Task extends WindowContainer<WindowContainer> {
void startActivityLocked(ActivityRecord r, @Nullable ActivityRecord focusedTopActivity,
boolean newTask, boolean keepCurTransition, ActivityOptions options,
boolean samePackage) {
@Nullable ActivityRecord sourceRecord) {
Task rTask = r.getTask();
final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
final boolean isOrhasTask = rTask == this || hasChild(rTask);
@@ -6725,7 +6725,7 @@ class Task extends WindowContainer<WindowContainer> {
}
r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity),
splashScreenThemeResId, samePackage);
splashScreenThemeResId, sourceRecord);
}
} else {
// If this is the first activity, don't do any fancy animations,

View File

@@ -112,6 +112,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.util.MergedConfiguration;
@@ -2484,6 +2485,26 @@ public class ActivityRecordTests extends WindowTestsBase {
doReturn(true).when(activity2).isAnimating();
assertTrue(activity2.applyAnimation(null, TRANSIT_OLD_ACTIVITY_OPEN, true, false, sources));
}
@Test
public void testTrackingStartingWindowThroughTrampoline() {
final ActivityRecord sourceRecord = new ActivityBuilder(mAtm)
.setCreateTask(true).setLaunchedFromUid(Process.SYSTEM_UID).build();
sourceRecord.showStartingWindow(null /* prev */, true /* newTask */, false,
0 /* splashScreenTheme */, null);
final ActivityRecord secondRecord = new ActivityBuilder(mAtm)
.setTask(sourceRecord.getTask()).build();
secondRecord.showStartingWindow(null /* prev */, true /* newTask */, false,
0 /* splashScreenTheme */, sourceRecord);
assertFalse(secondRecord.mSplashScreenStyleEmpty);
secondRecord.onStartingWindowDrawn();
final ActivityRecord finalRecord = new ActivityBuilder(mAtm)
.setTask(sourceRecord.getTask()).build();
finalRecord.showStartingWindow(null /* prev */, true /* newTask */, false,
0 /* splashScreenTheme */, secondRecord);
assertTrue(finalRecord.mSplashScreenStyleEmpty);
}
@Test
public void testTransferStartingWindowFromFinishingActivity() {
@@ -2494,13 +2515,13 @@ public class ActivityRecordTests extends WindowTestsBase {
"Test", 0 /* labelRes */, 0 /* icon */, 0 /* logo */, 0 /* windowFlags */,
null /* transferFrom */, true /* newTask */, true /* taskSwitch */,
false /* processRunning */, false /* allowTaskSnapshot */,
false /* activityCreate */, false /* samePackage */);
false /* activityCreate */, false /* suggestEmpty */);
waitUntilHandlersIdle();
assertHasStartingWindow(activity);
activity.mStartingWindowState = ActivityRecord.STARTING_WINDOW_SHOWN;
doCallRealMethod().when(task).startActivityLocked(
any(), any(), anyBoolean(), anyBoolean(), any(), anyBoolean());
any(), any(), anyBoolean(), anyBoolean(), any(), any());
// In normal case, resumeFocusedTasksTopActivities() should be called after
// startActivityLocked(). So skip resumeFocusedTasksTopActivities() in ActivityBuilder.
doReturn(false).when(mRootWindowContainer).resumeFocusedTasksTopActivities();
@@ -2508,7 +2529,7 @@ public class ActivityRecordTests extends WindowTestsBase {
final ActivityRecord middle = new ActivityBuilder(mAtm).setTask(task).build();
task.startActivityLocked(middle, null /* focusedTopActivity */,
false /* newTask */, false /* keepCurTransition */, null /* options */,
false /* samePackage */);
null /* sourceRecord */);
middle.makeFinishingLocked();
assertNull(activity.mStartingWindow);
@@ -2521,7 +2542,7 @@ public class ActivityRecordTests extends WindowTestsBase {
// The finishing middle should be able to transfer starting window to top.
task.startActivityLocked(top, null /* focusedTopActivity */,
false /* newTask */, false /* keepCurTransition */, null /* options */,
false /* samePackage */);
null /* sourceRecord */);
assertNull(middle.mStartingWindow);
assertHasStartingWindow(top);

View File

@@ -1204,7 +1204,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
spyOn(rootTask);
}
doNothing().when(rootTask).startActivityLocked(
any(), any(), anyBoolean(), anyBoolean(), any(), anyBoolean());
any(), any(), anyBoolean(), anyBoolean(), any(), any());
// Create child task with activity.
if (mCreateActivity) {