Fix the regression that closing transition disappeared.
For hierarchical animation, there are missing some handling around mNeedsZBoost, when closing an activity the transition did not applied. 1. Move some codes around mNeedsZBoost from ActivityRecord to WindowContainer so Task can also benefit from it. 2. TaskDisplayArea#assignChildLayers should combined needsZBoost so this attribute can apply on root task. 3. If next top activity will move to top in #finishIfPossible and the finishing activity is on top, provide it a higher layer to remain on top. Otherwise user will see flicker because the transition need to be applied until next activity resumed. Bug: 159200318 Test: atest ActivityRecordTests TaskDisplayAreaTests AppWindowTokenAnimationTests TransitionSelectionTests Change-Id: I85ec3307b31444e09179abca30298af2ce538834
This commit is contained in:
@@ -2560,7 +2560,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
if (mayAdjustTop && ((ActivityStack) task).topRunningActivity(true /* focusableOnly */)
|
||||
== null) {
|
||||
task.adjustFocusToNextFocusableTask("finish-top", false /* allowFocusSelf */,
|
||||
shouldAdjustGlobalFocus);
|
||||
shouldAdjustGlobalFocus);
|
||||
}
|
||||
|
||||
finishActivityResults(resultCode, resultData, resultGrants);
|
||||
@@ -2580,7 +2580,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
if (DEBUG_VISIBILITY || DEBUG_TRANSITION) {
|
||||
Slog.v(TAG_TRANSITION, "Prepare close transition: finishing " + this);
|
||||
}
|
||||
getDisplay().mDisplayContent.prepareAppTransition(transit, false);
|
||||
mDisplayContent.prepareAppTransition(transit, false);
|
||||
|
||||
// When finishing the activity preemptively take the snapshot before the app window
|
||||
// is marked as hidden and any configuration changes take place
|
||||
@@ -2605,6 +2605,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
|
||||
if (endTask) {
|
||||
mAtmService.getLockTaskController().clearLockedTask(task);
|
||||
// This activity was in the top focused stack and this is the last activity in
|
||||
// that task, give this activity a higher layer so it can stay on top before the
|
||||
// closing task transition be executed.
|
||||
if (mayAdjustTop) {
|
||||
mNeedsZBoost = true;
|
||||
mDisplayContent.assignWindowLayers(false /* setLayoutNeeded */);
|
||||
}
|
||||
}
|
||||
} else if (!isState(PAUSING)) {
|
||||
if (mVisibleRequested) {
|
||||
@@ -6105,7 +6112,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AR#onAnimationFinished");
|
||||
mTransit = TRANSIT_UNSET;
|
||||
mTransitFlags = 0;
|
||||
mNeedsZBoost = false;
|
||||
mNeedsAnimationBoundsLayer = false;
|
||||
|
||||
setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
|
||||
|
||||
@@ -52,6 +52,7 @@ import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.util.IntArray;
|
||||
import android.util.Slog;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.WindowContainerTransaction;
|
||||
@@ -106,6 +107,9 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
private final ArrayList<ActivityStack> mTmpAlwaysOnTopStacks = new ArrayList<>();
|
||||
private final ArrayList<ActivityStack> mTmpNormalStacks = new ArrayList<>();
|
||||
private final ArrayList<ActivityStack> mTmpHomeStacks = new ArrayList<>();
|
||||
private final IntArray mTmpNeedsZBoostIndexes = new IntArray();
|
||||
private int mTmpLayerForSplitScreenDividerAnchor;
|
||||
private int mTmpLayerForAnimationLayer;
|
||||
|
||||
private ArrayList<Task> mTmpTasks = new ArrayList<>();
|
||||
|
||||
@@ -633,39 +637,72 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
|
||||
|
||||
int layer = 0;
|
||||
// Place home stacks to the bottom.
|
||||
for (int i = 0; i < mTmpHomeStacks.size(); i++) {
|
||||
mTmpHomeStacks.get(i).assignLayer(t, layer++);
|
||||
}
|
||||
layer = adjustRootTaskLayer(t, mTmpHomeStacks, layer, false /* normalStacks */);
|
||||
// The home animation layer is between the home stacks and the normal stacks.
|
||||
final int layerForHomeAnimationLayer = layer++;
|
||||
int layerForSplitScreenDividerAnchor = layer++;
|
||||
int layerForAnimationLayer = layer++;
|
||||
for (int i = 0; i < mTmpNormalStacks.size(); i++) {
|
||||
final ActivityStack s = mTmpNormalStacks.get(i);
|
||||
s.assignLayer(t, layer++);
|
||||
if (s.inSplitScreenWindowingMode()) {
|
||||
// The split screen divider anchor is located above the split screen window.
|
||||
layerForSplitScreenDividerAnchor = layer++;
|
||||
}
|
||||
if (s.isTaskAnimating() || s.isAppTransitioning()) {
|
||||
// The animation layer is located above the highest animating stack and no
|
||||
// higher.
|
||||
layerForAnimationLayer = layer++;
|
||||
}
|
||||
}
|
||||
mTmpLayerForSplitScreenDividerAnchor = layer++;
|
||||
mTmpLayerForAnimationLayer = layer++;
|
||||
layer = adjustRootTaskLayer(t, mTmpNormalStacks, layer, true /* normalStacks */);
|
||||
|
||||
// The boosted animation layer is between the normal stacks and the always on top
|
||||
// stacks.
|
||||
final int layerForBoostedAnimationLayer = layer++;
|
||||
for (int i = 0; i < mTmpAlwaysOnTopStacks.size(); i++) {
|
||||
mTmpAlwaysOnTopStacks.get(i).assignLayer(t, layer++);
|
||||
}
|
||||
adjustRootTaskLayer(t, mTmpAlwaysOnTopStacks, layer, false /* normalStacks */);
|
||||
|
||||
t.setLayer(mHomeAppAnimationLayer, layerForHomeAnimationLayer);
|
||||
t.setLayer(mAppAnimationLayer, layerForAnimationLayer);
|
||||
t.setLayer(mSplitScreenDividerAnchor, layerForSplitScreenDividerAnchor);
|
||||
t.setLayer(mAppAnimationLayer, mTmpLayerForAnimationLayer);
|
||||
t.setLayer(mSplitScreenDividerAnchor, mTmpLayerForSplitScreenDividerAnchor);
|
||||
t.setLayer(mBoostedAppAnimationLayer, layerForBoostedAnimationLayer);
|
||||
}
|
||||
|
||||
private int adjustNormalStackLayer(ActivityStack s, int layer) {
|
||||
if (s.inSplitScreenWindowingMode()) {
|
||||
// The split screen divider anchor is located above the split screen window.
|
||||
mTmpLayerForSplitScreenDividerAnchor = layer++;
|
||||
}
|
||||
if (s.isTaskAnimating() || s.isAppTransitioning()) {
|
||||
// The animation layer is located above the highest animating stack and no
|
||||
// higher.
|
||||
mTmpLayerForAnimationLayer = layer++;
|
||||
}
|
||||
return layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the layer of the stack which belongs to the same group.
|
||||
* Note that there are three stack groups: home stacks, always on top stacks, and normal stacks.
|
||||
*
|
||||
* @param startLayer The beginning layer of this group of stacks.
|
||||
* @param normalStacks Set {@code true} if this group is neither home nor always on top.
|
||||
* @return The adjusted layer value.
|
||||
*/
|
||||
private int adjustRootTaskLayer(SurfaceControl.Transaction t, ArrayList<ActivityStack> stacks,
|
||||
int startLayer, boolean normalStacks) {
|
||||
mTmpNeedsZBoostIndexes.clear();
|
||||
final int stackSize = stacks.size();
|
||||
for (int i = 0; i < stackSize; i++) {
|
||||
final ActivityStack stack = stacks.get(i);
|
||||
if (!stack.needsZBoost()) {
|
||||
stack.assignLayer(t, startLayer++);
|
||||
if (normalStacks) {
|
||||
startLayer = adjustNormalStackLayer(stack, startLayer);
|
||||
}
|
||||
} else {
|
||||
mTmpNeedsZBoostIndexes.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
final int zBoostSize = mTmpNeedsZBoostIndexes.size();
|
||||
for (int i = 0; i < zBoostSize; i++) {
|
||||
final ActivityStack stack = stacks.get(mTmpNeedsZBoostIndexes.get(i));
|
||||
stack.assignLayer(t, startLayer++);
|
||||
if (normalStacks) {
|
||||
startLayer = adjustNormalStackLayer(stack, startLayer);
|
||||
}
|
||||
}
|
||||
return startLayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
SurfaceControl getAppAnimationLayer(@AnimationLayer int animationLayer) {
|
||||
switch (animationLayer) {
|
||||
|
||||
@@ -2440,6 +2440,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
|
||||
protected void onAnimationFinished(@AnimationType int type, AnimationAdapter anim) {
|
||||
doAnimationFinished(type, anim);
|
||||
mWmService.onAnimationFinished();
|
||||
mNeedsZBoost = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user