Merge "Consolidate finally block of startActivityInner" into tm-dev

This commit is contained in:
Riddle Hsu
2022-03-24 05:30:19 +00:00
committed by Android (Google) Code Review
2 changed files with 85 additions and 93 deletions

View File

@@ -544,10 +544,8 @@ public class ActivityStartController {
if (mLastHomeActivityStartRecord != null && (!dumpPackagePresent
|| dumpPackage.equals(mLastHomeActivityStartRecord.packageName))) {
if (!dumped) {
dumped = true;
dumpLastHomeActivityStartResult(pw, prefix);
}
dumped = true;
dumpLastHomeActivityStartResult(pw, prefix);
pw.print(prefix);
pw.println("mLastHomeActivityStartRecord:");
mLastHomeActivityStartRecord.dump(pw, prefix + " ", true /* dumpAll */);
@@ -565,6 +563,7 @@ public class ActivityStartController {
dumpLastHomeActivityStartResult(pw, prefix);
}
pw.print(prefix);
pw.println("mLastStarter:");
mLastStarter.dump(pw, prefix + " ");
if (dumpPackagePresent) {

View File

@@ -614,6 +614,9 @@ class ActivityStarter {
mVoiceInteractor = starter.mVoiceInteractor;
mIntentDelivered = starter.mIntentDelivered;
mLastStartActivityResult = starter.mLastStartActivityResult;
mLastStartActivityTimeMs = starter.mLastStartActivityTimeMs;
mLastStartReason = starter.mLastStartReason;
mRequest.set(starter.mRequest);
}
@@ -1599,7 +1602,6 @@ class ActivityStarter {
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
int result = START_CANCELED;
boolean startResultSuccessful = false;
final Task startedActivityRootTask;
// Create a transition now to record the original intent of actions taken within
@@ -1615,75 +1617,18 @@ class ActivityStarter {
newTransition.setRemoteTransition(remoteTransition);
}
transitionController.collect(r);
final boolean isTransient = r.getOptions() != null && r.getOptions().getTransientLaunch();
try {
mService.deferWindowLayout();
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,
intentGrants);
startResultSuccessful = ActivityManager.isStartResultSuccessful(result);
final boolean taskAlwaysOnTop = options != null && options.getTaskAlwaysOnTop();
// Apply setAlwaysOnTop when starting an Activity is successful regardless of creating
// a new Activity or recycling the existing Activity.
if (taskAlwaysOnTop && startResultSuccessful) {
final Task targetRootTask =
mTargetRootTask != null ? mTargetRootTask : mTargetTask.getRootTask();
targetRootTask.setAlwaysOnTop(true);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
startedActivityRootTask = handleStartResult(r, result);
startedActivityRootTask = handleStartResult(r, options, result, newTransition,
remoteTransition);
mService.continueWindowLayout();
mSupervisor.mUserLeaving = false;
// Transition housekeeping
if (!startResultSuccessful) {
if (newTransition != null) {
newTransition.abort();
}
} else {
if (!mAvoidMoveToFront && mDoResume
&& mRootWindowContainer.hasVisibleWindowAboveButDoesNotOwnNotificationShade(
r.launchedFromUid)) {
// If the UID launching the activity has a visible window on top of the
// notification shade and it's launching an activity that's going to be at the
// front, we should move the shade out of the way so the user can see it.
// We want to avoid the case where the activity is launched on top of a
// background task which is not moved to the front.
StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal();
if (statusBar != null) {
// This results in a async call since the interface is one-way
statusBar.collapsePanels();
}
}
final boolean started = result == START_SUCCESS || result == START_TASK_TO_FRONT;
if (started) {
// The activity is started new rather than just brought forward, so record
// it as an existence change.
transitionController.collectExistenceChange(r);
} else if (result == START_DELIVERED_TO_TOP && newTransition != null) {
// We just delivered to top, so there isn't an actual transition here
newTransition.abort();
newTransition = null;
}
if (isTransient) {
// `r` isn't guaranteed to be the actual relevant activity, so we must wait
// until after we launched to identify the relevant activity.
transitionController.setTransientLaunch(mLastStartActivityRecord,
mPriorAboveTask);
}
if (newTransition != null) {
transitionController.requestStartTransition(newTransition,
mTargetTask == null ? r.getTask() : mTargetTask,
remoteTransition, null /* displayChange */);
} else if (started) {
// Make the collecting transition wait until this request is ready.
transitionController.setReady(r, false);
}
}
}
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
@@ -1695,40 +1640,89 @@ class ActivityStarter {
*
* @return the root task where the successful started activity resides.
*/
private @Nullable Task handleStartResult(@NonNull ActivityRecord started, int result) {
private @Nullable Task handleStartResult(@NonNull ActivityRecord started,
ActivityOptions options, int result, Transition newTransition,
RemoteTransition remoteTransition) {
mSupervisor.mUserLeaving = false;
final Task currentRootTask = started.getRootTask();
Task startedActivityRootTask = currentRootTask != null ? currentRootTask : mTargetRootTask;
final Task startedActivityRootTask =
currentRootTask != null ? currentRootTask : mTargetRootTask;
if (ActivityManager.isStartResultSuccessful(result)) {
if (startedActivityRootTask != null) {
// If there is no state change (e.g. a resumed activity is reparented to top of
// another display) to trigger a visibility/configuration checking, we have to
// update the configuration for changing to different display.
final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity();
if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
mRootWindowContainer.ensureVisibilityAndConfig(
currentTop, currentTop.getDisplayId(),
true /* markFrozenIfConfigChanged */, false /* deferResume */);
}
if (!ActivityManager.isStartResultSuccessful(result) || startedActivityRootTask == null) {
// If we are not able to proceed, disassociate the activity from the task. Leaving an
// activity in an incomplete state can lead to issues, such as performing operations
// without a window container.
if (mStartActivity.getTask() != null) {
mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
} else if (mStartActivity.getParent() != null) {
mStartActivity.getParent().removeChild(mStartActivity);
}
return startedActivityRootTask;
// Root task should also be detached from display and be removed if it's empty.
if (startedActivityRootTask != null && startedActivityRootTask.isAttached()
&& !startedActivityRootTask.hasActivity()
&& !startedActivityRootTask.isActivityTypeHome()) {
startedActivityRootTask.removeIfPossible("handleStartResult");
}
if (newTransition != null) {
newTransition.abort();
}
return null;
}
// If we are not able to proceed, disassociate the activity from the task. Leaving an
// activity in an incomplete state can lead to issues, such as performing operations
// without a window container.
if (mStartActivity.getTask() != null) {
mStartActivity.finishIfPossible("startActivity", true /* oomAdj */);
} else if (mStartActivity.getParent() != null) {
mStartActivity.getParent().removeChild(mStartActivity);
// Apply setAlwaysOnTop when starting an activity is successful regardless of creating
// a new Activity or reusing the existing activity.
if (options != null && options.getTaskAlwaysOnTop()) {
startedActivityRootTask.setAlwaysOnTop(true);
}
// Root task should also be detached from display and be removed if it's empty.
if (startedActivityRootTask != null && startedActivityRootTask.isAttached()
&& !startedActivityRootTask.hasActivity()
&& !startedActivityRootTask.isActivityTypeHome()) {
startedActivityRootTask.removeIfPossible("handleStartResult");
startedActivityRootTask = null;
// If there is no state change (e.g. a resumed activity is reparented to top of
// another display) to trigger a visibility/configuration checking, we have to
// update the configuration for changing to different display.
final ActivityRecord currentTop = startedActivityRootTask.topRunningActivity();
if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
mRootWindowContainer.ensureVisibilityAndConfig(
currentTop, currentTop.getDisplayId(),
true /* markFrozenIfConfigChanged */, false /* deferResume */);
}
if (!mAvoidMoveToFront && mDoResume && mRootWindowContainer
.hasVisibleWindowAboveButDoesNotOwnNotificationShade(started.launchedFromUid)) {
// If the UID launching the activity has a visible window on top of the notification
// shade and it's launching an activity that's going to be at the front, we should move
// the shade out of the way so the user can see it. We want to avoid the case where the
// activity is launched on top of a background task which is not moved to the front.
final StatusBarManagerInternal statusBar = mService.getStatusBarManagerInternal();
if (statusBar != null) {
// This results in a async call since the interface is one-way.
statusBar.collapsePanels();
}
}
// Transition housekeeping.
final TransitionController transitionController = started.mTransitionController;
final boolean isStarted = result == START_SUCCESS || result == START_TASK_TO_FRONT;
if (isStarted) {
// The activity is started new rather than just brought forward, so record it as an
// existence change.
transitionController.collectExistenceChange(started);
} else if (result == START_DELIVERED_TO_TOP && newTransition != null) {
// We just delivered to top, so there isn't an actual transition here.
newTransition.abort();
newTransition = null;
}
if (options != null && options.getTransientLaunch()) {
// `started` isn't guaranteed to be the actual relevant activity, so we must wait
// until after we launched to identify the relevant activity.
transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
}
if (newTransition != null) {
transitionController.requestStartTransition(newTransition,
mTargetTask == null ? started.getTask() : mTargetTask,
remoteTransition, null /* displayChange */);
} else if (isStarted) {
// Make the collecting transition wait until this request is ready.
transitionController.setReady(started, false);
}
return startedActivityRootTask;
}
@@ -3170,7 +3164,6 @@ class ActivityStarter {
}
void dump(PrintWriter pw, String prefix) {
prefix = prefix + " ";
pw.print(prefix);
pw.print("mCurrentUser=");
pw.println(mRootWindowContainer.mCurrentUser);
@@ -3216,7 +3209,7 @@ class ActivityStarter {
pw.print(" mDoResume=");
pw.print(mDoResume);
pw.print(" mAddingToTask=");
pw.println(mAddingToTask);
pw.print(mAddingToTask);
pw.print(" mInTaskFragment=");
pw.println(mInTaskFragment);
}