Fix freeze issue after launch single app am: 7f05e1a97a
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21611429 Change-Id: I22b4ace7e3a8985f023c769298ff8bf0c3ed6ab1 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -764,17 +764,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
if (options1 == null) options1 = new Bundle();
|
if (options1 == null) options1 = new Bundle();
|
||||||
if (pendingIntent2 == null) {
|
if (pendingIntent2 == null) {
|
||||||
// Launching a solo task.
|
// Launching a solo intent or shortcut as fullscreen.
|
||||||
ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
|
launchAsFullscreenWithRemoteAnimation(pendingIntent1, fillInIntent1, shortcutInfo1,
|
||||||
activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
|
options1, adapter, wct);
|
||||||
options1 = activityOptions.toBundle();
|
|
||||||
addActivityOptions(options1, null /* launchTarget */);
|
|
||||||
if (shortcutInfo1 != null) {
|
|
||||||
wct.startShortcut(mContext.getPackageName(), shortcutInfo1, options1);
|
|
||||||
} else {
|
|
||||||
wct.sendPendingIntent(pendingIntent1, fillInIntent1, options1);
|
|
||||||
}
|
|
||||||
mSyncQueue.queue(wct);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -797,13 +789,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
if (options1 == null) options1 = new Bundle();
|
if (options1 == null) options1 = new Bundle();
|
||||||
if (taskId == INVALID_TASK_ID) {
|
if (taskId == INVALID_TASK_ID) {
|
||||||
// Launching a solo task.
|
// Launching a solo intent as fullscreen.
|
||||||
ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
|
launchAsFullscreenWithRemoteAnimation(pendingIntent, fillInIntent, null, options1,
|
||||||
activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
|
adapter, wct);
|
||||||
options1 = activityOptions.toBundle();
|
|
||||||
addActivityOptions(options1, null /* launchTarget */);
|
|
||||||
wct.sendPendingIntent(pendingIntent, fillInIntent, options1);
|
|
||||||
mSyncQueue.queue(wct);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -822,13 +810,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||||
if (options1 == null) options1 = new Bundle();
|
if (options1 == null) options1 = new Bundle();
|
||||||
if (taskId == INVALID_TASK_ID) {
|
if (taskId == INVALID_TASK_ID) {
|
||||||
// Launching a solo task.
|
// Launching a solo shortcut as fullscreen.
|
||||||
ActivityOptions activityOptions = ActivityOptions.fromBundle(options1);
|
launchAsFullscreenWithRemoteAnimation(null, null, shortcutInfo, options1, adapter, wct);
|
||||||
activityOptions.update(ActivityOptions.makeRemoteAnimation(adapter));
|
|
||||||
options1 = activityOptions.toBundle();
|
|
||||||
addActivityOptions(options1, null /* launchTarget */);
|
|
||||||
wct.startShortcut(mContext.getPackageName(), shortcutInfo, options1);
|
|
||||||
mSyncQueue.queue(wct);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,6 +821,49 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
instanceId);
|
instanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void launchAsFullscreenWithRemoteAnimation(@Nullable PendingIntent pendingIntent,
|
||||||
|
@Nullable Intent fillInIntent, @Nullable ShortcutInfo shortcutInfo,
|
||||||
|
@Nullable Bundle options, RemoteAnimationAdapter adapter,
|
||||||
|
WindowContainerTransaction wct) {
|
||||||
|
LegacyTransitions.ILegacyTransition transition =
|
||||||
|
(transit, apps, wallpapers, nonApps, finishedCallback, t) -> {
|
||||||
|
if (apps == null || apps.length == 0) {
|
||||||
|
onRemoteAnimationFinished(apps);
|
||||||
|
t.apply();
|
||||||
|
try {
|
||||||
|
adapter.getRunner().onAnimationCancelled(mKeyguardShowing);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Error starting remote animation", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < apps.length; ++i) {
|
||||||
|
if (apps[i].mode == MODE_OPENING) {
|
||||||
|
t.show(apps[i].leash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.apply();
|
||||||
|
|
||||||
|
try {
|
||||||
|
adapter.getRunner().onAnimationStart(
|
||||||
|
transit, apps, wallpapers, nonApps, finishedCallback);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Error starting remote animation", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addActivityOptions(options, null /* launchTarget */);
|
||||||
|
if (shortcutInfo != null) {
|
||||||
|
wct.startShortcut(mContext.getPackageName(), shortcutInfo, options);
|
||||||
|
} else if (pendingIntent != null) {
|
||||||
|
wct.sendPendingIntent(pendingIntent, fillInIntent, options);
|
||||||
|
} else {
|
||||||
|
Slog.e(TAG, "Pending intent and shortcut are null is invalid case.");
|
||||||
|
}
|
||||||
|
mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
|
||||||
|
}
|
||||||
|
|
||||||
private void startWithLegacyTransition(WindowContainerTransaction wct,
|
private void startWithLegacyTransition(WindowContainerTransaction wct,
|
||||||
@Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
|
@Nullable PendingIntent mainPendingIntent, @Nullable Intent mainFillInIntent,
|
||||||
@Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle mainOptions,
|
@Nullable ShortcutInfo mainShortcutInfo, @Nullable Bundle mainOptions,
|
||||||
@@ -894,23 +920,25 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
|
|
||||||
if (options == null) options = new Bundle();
|
if (options == null) options = new Bundle();
|
||||||
addActivityOptions(options, mMainStage);
|
addActivityOptions(options, mMainStage);
|
||||||
options = wrapAsSplitRemoteAnimation(adapter, options);
|
|
||||||
|
|
||||||
updateWindowBounds(mSplitLayout, wct);
|
updateWindowBounds(mSplitLayout, wct);
|
||||||
|
|
||||||
// TODO(b/268008375): Merge APIs to start a split pair into one.
|
|
||||||
if (mainTaskId != INVALID_TASK_ID) {
|
|
||||||
wct.startTask(mainTaskId, options);
|
|
||||||
} else if (mainShortcutInfo != null) {
|
|
||||||
wct.startShortcut(mContext.getPackageName(), mainShortcutInfo, options);
|
|
||||||
} else {
|
|
||||||
wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
wct.reorder(mRootTaskInfo.token, true);
|
wct.reorder(mRootTaskInfo.token, true);
|
||||||
wct.setForceTranslucent(mRootTaskInfo.token, false);
|
wct.setForceTranslucent(mRootTaskInfo.token, false);
|
||||||
|
|
||||||
mSyncQueue.queue(wct);
|
// TODO(b/268008375): Merge APIs to start a split pair into one.
|
||||||
|
if (mainTaskId != INVALID_TASK_ID) {
|
||||||
|
options = wrapAsSplitRemoteAnimation(adapter, options);
|
||||||
|
wct.startTask(mainTaskId, options);
|
||||||
|
mSyncQueue.queue(wct);
|
||||||
|
} else {
|
||||||
|
if (mainShortcutInfo != null) {
|
||||||
|
wct.startShortcut(mContext.getPackageName(), mainShortcutInfo, options);
|
||||||
|
} else {
|
||||||
|
wct.sendPendingIntent(mainPendingIntent, mainFillInIntent, options);
|
||||||
|
}
|
||||||
|
mSyncQueue.queue(wrapAsSplitRemoteAnimation(adapter), WindowManager.TRANSIT_OPEN, wct);
|
||||||
|
}
|
||||||
|
|
||||||
mSyncQueue.runInSync(t -> {
|
mSyncQueue.runInSync(t -> {
|
||||||
setDividerVisibility(true, t);
|
setDividerVisibility(true, t);
|
||||||
});
|
});
|
||||||
@@ -967,6 +995,54 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
return activityOptions.toBundle();
|
return activityOptions.toBundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LegacyTransitions.ILegacyTransition wrapAsSplitRemoteAnimation(
|
||||||
|
RemoteAnimationAdapter adapter) {
|
||||||
|
LegacyTransitions.ILegacyTransition transition =
|
||||||
|
(transit, apps, wallpapers, nonApps, finishedCallback, t) -> {
|
||||||
|
if (apps == null || apps.length == 0) {
|
||||||
|
onRemoteAnimationFinished(apps);
|
||||||
|
t.apply();
|
||||||
|
try {
|
||||||
|
adapter.getRunner().onAnimationCancelled(mKeyguardShowing);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Error starting remote animation", e);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap the divider bar into non-apps target to animate together.
|
||||||
|
nonApps = ArrayUtils.appendElement(RemoteAnimationTarget.class, nonApps,
|
||||||
|
getDividerBarLegacyTarget());
|
||||||
|
|
||||||
|
for (int i = 0; i < apps.length; ++i) {
|
||||||
|
if (apps[i].mode == MODE_OPENING) {
|
||||||
|
t.show(apps[i].leash);
|
||||||
|
// Reset the surface position of the opening app to prevent offset.
|
||||||
|
t.setPosition(apps[i].leash, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.apply();
|
||||||
|
|
||||||
|
IRemoteAnimationFinishedCallback wrapCallback =
|
||||||
|
new IRemoteAnimationFinishedCallback.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationFinished() throws RemoteException {
|
||||||
|
onRemoteAnimationFinished(apps);
|
||||||
|
finishedCallback.onAnimationFinished();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Transitions.setRunningRemoteTransitionDelegate(adapter.getCallingApplication());
|
||||||
|
try {
|
||||||
|
adapter.getRunner().onAnimationStart(
|
||||||
|
transit, apps, wallpapers, nonApps, wrapCallback);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Slog.e(TAG, "Error starting remote animation", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return transition;
|
||||||
|
}
|
||||||
|
|
||||||
private void setEnterInstanceId(InstanceId instanceId) {
|
private void setEnterInstanceId(InstanceId instanceId) {
|
||||||
if (instanceId != null) {
|
if (instanceId != null) {
|
||||||
mLogger.enterRequested(instanceId, ENTER_REASON_LAUNCHER);
|
mLogger.enterRequested(instanceId, ENTER_REASON_LAUNCHER);
|
||||||
@@ -993,6 +1069,27 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onRemoteAnimationFinished(RemoteAnimationTarget[] apps) {
|
||||||
|
mIsDividerRemoteAnimating = false;
|
||||||
|
mShouldUpdateRecents = true;
|
||||||
|
mSplitRequest = null;
|
||||||
|
// If any stage has no child after finished animation, that side of the split will display
|
||||||
|
// nothing. This might happen if starting the same app on the both sides while not
|
||||||
|
// supporting multi-instance. Exit the split screen and expand that app to full screen.
|
||||||
|
if (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0) {
|
||||||
|
mMainExecutor.execute(() -> exitSplitScreen(mMainStage.getChildCount() == 0
|
||||||
|
? mSideStage : mMainStage, EXIT_REASON_UNKNOWN));
|
||||||
|
mSplitUnsupportedToast.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final WindowContainerTransaction evictWct = new WindowContainerTransaction();
|
||||||
|
prepareEvictNonOpeningChildTasks(SPLIT_POSITION_TOP_OR_LEFT, apps, evictWct);
|
||||||
|
prepareEvictNonOpeningChildTasks(SPLIT_POSITION_BOTTOM_OR_RIGHT, apps, evictWct);
|
||||||
|
mSyncQueue.queue(evictWct);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all the current child tasks of a specific split and prepares transaction to evict
|
* Collects all the current child tasks of a specific split and prepares transaction to evict
|
||||||
* them to display.
|
* them to display.
|
||||||
|
|||||||
Reference in New Issue
Block a user