summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java86
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java6
2 files changed, 66 insertions, 26 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index e4db7b636ed9..0beda678e79a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -95,6 +95,7 @@ import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
@@ -1273,42 +1274,42 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
// Copy initial changes to final transition
final TransitionInfo init = mOpenTransitionInfo;
- // find prepare open target
+ // Find prepare open target
boolean openShowWallpaper = false;
- ComponentName openComponent = null;
+ final ArrayList<OpenChangeInfo> targets = new ArrayList<>();
int tmpSize;
- int openTaskId = INVALID_TASK_ID;
- WindowContainerToken openToken = null;
for (int j = init.getChanges().size() - 1; j >= 0; --j) {
final TransitionInfo.Change change = init.getChanges().get(j);
- if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
- openComponent = findComponentName(change);
- openTaskId = findTaskId(change);
- openToken = findToken(change);
+ if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)
+ && TransitionUtil.isOpeningMode(change.getMode())) {
+ final ComponentName openComponent = findComponentName(change);
+ final int openTaskId = findTaskId(change);
+ final WindowContainerToken openToken = findToken(change);
+ if (openComponent == null && openTaskId == INVALID_TASK_ID
+ && openToken == null) {
+ continue;
+ }
+ targets.add(new OpenChangeInfo(openComponent, openTaskId, openToken));
if (change.hasFlags(FLAG_SHOW_WALLPAPER)) {
openShowWallpaper = true;
}
- break;
}
}
- if (openComponent == null && openTaskId == INVALID_TASK_ID && openToken == null) {
+ if (targets.isEmpty()) {
// This shouldn't happen, but if that happen, consume the initial transition anyway.
Log.e(TAG, "Unable to merge following transition, cannot find the gesture "
+ "animated target from the open transition=" + mOpenTransitionInfo);
mOpenTransitionInfo = null;
return;
}
- // find first non-prepare open target
+ // Find first non-prepare open target
boolean isOpen = false;
tmpSize = info.getChanges().size();
for (int j = 0; j < tmpSize; ++j) {
final TransitionInfo.Change change = info.getChanges().get(j);
- final ComponentName firstNonOpen = findComponentName(change);
- final int firstTaskId = findTaskId(change);
- if ((firstNonOpen != null && firstNonOpen != openComponent)
- || (firstTaskId != INVALID_TASK_ID && firstTaskId != openTaskId)) {
- // this is original close target, potential be close, but cannot determine from
- // it
+ if (isOpenChangeMatched(targets, change)) {
+ // This is original close target, potential be close, but cannot determine
+ // from it.
if (change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
isOpen = !TransitionUtil.isClosingMode(change.getMode());
} else {
@@ -1317,33 +1318,44 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
}
}
-
if (!isOpen) {
// Close transition, the transition info should be:
// init info(open A & wallpaper)
// current info(close B target)
// remove init info(open/change A target & wallpaper)
boolean moveToTop = false;
+ boolean excludeOpenTarget = false;
+ boolean mergePredictive = false;
for (int j = info.getChanges().size() - 1; j >= 0; --j) {
final TransitionInfo.Change change = info.getChanges().get(j);
- if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) {
+ if (isOpenChangeMatched(targets, change)) {
+ if (TransitionUtil.isClosingMode(change.getMode())) {
+ excludeOpenTarget = true;
+ }
moveToTop = change.hasFlags(FLAG_MOVED_TO_TOP);
info.getChanges().remove(j);
} else if ((openShowWallpaper && change.hasFlags(FLAG_IS_WALLPAPER))
|| !change.hasFlags(FLAG_BACK_GESTURE_ANIMATED)) {
info.getChanges().remove(j);
+ } else if (!mergePredictive && TransitionUtil.isClosingMode(change.getMode())) {
+ mergePredictive = true;
}
}
// Ignore merge if there is no close target
- if (!info.getChanges().isEmpty()) {
+ if (!info.getChanges().isEmpty() && mergePredictive) {
tmpSize = init.getChanges().size();
for (int i = 0; i < tmpSize; ++i) {
final TransitionInfo.Change change = init.getChanges().get(i);
if (change.hasFlags(FLAG_IS_WALLPAPER)) {
continue;
}
- if (moveToTop) {
- if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) {
+ if (isOpenChangeMatched(targets, change)) {
+ if (excludeOpenTarget) {
+ // App has triggered another change during predictive back
+ // transition, filter out predictive back target.
+ continue;
+ }
+ if (moveToTop) {
change.setFlags(change.getFlags() | FLAG_MOVED_TO_TOP);
}
}
@@ -1372,7 +1384,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
if (nonBackClose && nonBackOpen) {
for (int j = info.getChanges().size() - 1; j >= 0; --j) {
final TransitionInfo.Change change = info.getChanges().get(j);
- if (isSameChangeTarget(openComponent, openTaskId, openToken, change)) {
+ if (isOpenChangeMatched(targets, change)) {
info.getChanges().remove(j);
} else if ((openShowWallpaper && change.hasFlags(FLAG_IS_WALLPAPER))) {
info.getChanges().remove(j);
@@ -1655,9 +1667,21 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
final ComponentName openChange = findComponentName(change);
final int firstTaskId = findTaskId(change);
final WindowContainerToken openToken = findToken(change);
- return (openChange != null && openChange == topActivity)
+ return (openChange != null && openChange.equals(topActivity))
|| (firstTaskId != INVALID_TASK_ID && firstTaskId == taskId)
- || (openToken != null && token == openToken);
+ || (openToken != null && openToken.equals(token));
+ }
+
+ static boolean isOpenChangeMatched(@NonNull ArrayList<OpenChangeInfo> targets,
+ TransitionInfo.Change change) {
+ for (int i = targets.size() - 1; i >= 0; --i) {
+ final OpenChangeInfo next = targets.get(i);
+ if (isSameChangeTarget(next.mOpenComponent, next.mOpenTaskId, next.mOpenToken,
+ change)) {
+ return true;
+ }
+ }
+ return false;
}
private static boolean canBeTransitionTarget(TransitionInfo.Change change) {
@@ -1717,4 +1741,16 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
}
}
}
+
+ static class OpenChangeInfo {
+ final ComponentName mOpenComponent;
+ final int mOpenTaskId;
+ final WindowContainerToken mOpenToken;
+ OpenChangeInfo(ComponentName openComponent, int openTaskId,
+ WindowContainerToken openToken) {
+ mOpenComponent = openComponent;
+ mOpenTaskId = openTaskId;
+ mOpenToken = openToken;
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index dee0b23a42f5..f99e96109f88 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -51,6 +51,7 @@ import android.content.pm.ApplicationInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.input.InputManager;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -804,7 +805,10 @@ public class BackAnimationControllerTest extends ShellTestCase {
if (taskId != INVALID_TASK_ID) {
final ActivityManager.RunningTaskInfo taskInfo = new ActivityManager.RunningTaskInfo();
taskInfo.taskId = taskId;
- taskInfo.token = new WindowContainerToken(mock(IWindowContainerToken.class));
+ final IWindowContainerToken mockT = mock(IWindowContainerToken.class);
+ Binder binder = new Binder();
+ doReturn(binder).when(mockT).asBinder();
+ taskInfo.token = new WindowContainerToken(mockT);
change = new TransitionInfo.Change(
taskInfo.token, b.build());
change.setTaskInfo(taskInfo);