Merge "Made TaskViewTransitions less rigid" into udc-dev

This commit is contained in:
Evan Rosky
2023-02-20 06:12:07 +00:00
committed by Android (Google) Code Review
3 changed files with 81 additions and 30 deletions

View File

@@ -131,7 +131,7 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
mShellExecutor.execute(() -> { mShellExecutor.execute(() -> {
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.startShortcut(mContext.getPackageName(), shortcut, options.toBundle()); wct.startShortcut(mContext.getPackageName(), shortcut, options.toBundle());
mTaskViewTransitions.startTaskView(wct, this); mTaskViewTransitions.startTaskView(wct, this, options.getLaunchCookie());
}); });
return; return;
} }
@@ -158,7 +158,7 @@ public class TaskViewTaskController implements ShellTaskOrganizer.TaskListener {
mShellExecutor.execute(() -> { mShellExecutor.execute(() -> {
WindowContainerTransaction wct = new WindowContainerTransaction(); WindowContainerTransaction wct = new WindowContainerTransaction();
wct.sendPendingIntent(pendingIntent, fillInIntent, options.toBundle()); wct.sendPendingIntent(pendingIntent, fillInIntent, options.toBundle());
mTaskViewTransitions.startTaskView(wct, this); mTaskViewTransitions.startTaskView(wct, this, options.getLaunchCookie());
}); });
return; return;
} }

View File

@@ -57,12 +57,21 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
final @NonNull TaskViewTaskController mTaskView; final @NonNull TaskViewTaskController mTaskView;
IBinder mClaimed; IBinder mClaimed;
/**
* This is needed because arbitrary activity launches can still "intrude" into any
* transition since `startActivity` is a synchronous call. Once that is solved, we can
* remove this.
*/
final IBinder mLaunchCookie;
PendingTransition(@WindowManager.TransitionType int type, PendingTransition(@WindowManager.TransitionType int type,
@Nullable WindowContainerTransaction wct, @Nullable WindowContainerTransaction wct,
@NonNull TaskViewTaskController taskView) { @NonNull TaskViewTaskController taskView,
@Nullable IBinder launchCookie) {
mType = type; mType = type;
mWct = wct; mWct = wct;
mTaskView = taskView; mTaskView = taskView;
mLaunchCookie = launchCookie;
} }
} }
@@ -142,7 +151,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
if (!Transitions.isClosingType(request.getType())) return null; if (!Transitions.isClosingType(request.getType())) return null;
PendingTransition pending = findPending(taskView, true /* closing */, false /* latest */); PendingTransition pending = findPending(taskView, true /* closing */, false /* latest */);
if (pending == null) { if (pending == null) {
pending = new PendingTransition(request.getType(), null, taskView); pending = new PendingTransition(request.getType(), null, taskView, null /* cookie */);
} }
if (pending.mClaimed != null) { if (pending.mClaimed != null) {
throw new IllegalStateException("Task is closing in 2 collecting transitions?" throw new IllegalStateException("Task is closing in 2 collecting transitions?"
@@ -162,8 +171,9 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
return null; return null;
} }
void startTaskView(WindowContainerTransaction wct, TaskViewTaskController taskView) { void startTaskView(@NonNull WindowContainerTransaction wct,
mPending.add(new PendingTransition(TRANSIT_OPEN, wct, taskView)); @NonNull TaskViewTaskController taskView, @NonNull IBinder launchCookie) {
mPending.add(new PendingTransition(TRANSIT_OPEN, wct, taskView, launchCookie));
startNextTransition(); startNextTransition();
} }
@@ -180,7 +190,7 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
wct.setHidden(taskView.getTaskInfo().token, !visible /* hidden */); wct.setHidden(taskView.getTaskInfo().token, !visible /* hidden */);
pending = new PendingTransition( pending = new PendingTransition(
visible ? TRANSIT_TO_FRONT : TRANSIT_TO_BACK, wct, taskView); visible ? TRANSIT_TO_FRONT : TRANSIT_TO_BACK, wct, taskView, null /* cookie */);
mPending.add(pending); mPending.add(pending);
startNextTransition(); startNextTransition();
// visibility is reported in transition. // visibility is reported in transition.
@@ -196,6 +206,16 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
pending.mClaimed = mTransitions.startTransition(pending.mType, pending.mWct, this); pending.mClaimed = mTransitions.startTransition(pending.mType, pending.mWct, this);
} }
@Override
public void onTransitionConsumed(@NonNull IBinder transition, boolean aborted,
@NonNull SurfaceControl.Transaction finishTransaction) {
if (!aborted) return;
final PendingTransition pending = findPending(transition);
if (pending == null) return;
mPending.remove(pending);
startNextTransition();
}
@Override @Override
public boolean startAnimation(@NonNull IBinder transition, public boolean startAnimation(@NonNull IBinder transition,
@NonNull TransitionInfo info, @NonNull TransitionInfo info,
@@ -203,52 +223,76 @@ public class TaskViewTransitions implements Transitions.TransitionHandler {
@NonNull SurfaceControl.Transaction finishTransaction, @NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) { @NonNull Transitions.TransitionFinishCallback finishCallback) {
PendingTransition pending = findPending(transition); PendingTransition pending = findPending(transition);
if (pending == null) return false; if (pending != null) {
mPending.remove(pending); mPending.remove(pending);
TaskViewTaskController taskView = pending.mTaskView; }
final ArrayList<TransitionInfo.Change> tasks = new ArrayList<>(); if (mTaskViews.isEmpty()) {
if (pending != null) {
Slog.e(TAG, "Pending taskview transition but no task-views");
}
return false;
}
boolean stillNeedsMatchingLaunch = pending != null && pending.mLaunchCookie != null;
int changesHandled = 0;
WindowContainerTransaction wct = null;
for (int i = 0; i < info.getChanges().size(); ++i) { for (int i = 0; i < info.getChanges().size(); ++i) {
final TransitionInfo.Change chg = info.getChanges().get(i); final TransitionInfo.Change chg = info.getChanges().get(i);
if (chg.getTaskInfo() == null) continue; if (chg.getTaskInfo() == null) continue;
tasks.add(chg);
}
if (tasks.isEmpty()) {
Slog.e(TAG, "Got a TaskView transition with no task.");
return false;
}
WindowContainerTransaction wct = null;
for (int i = 0; i < tasks.size(); ++i) {
TransitionInfo.Change chg = tasks.get(i);
if (Transitions.isClosingType(chg.getMode())) { if (Transitions.isClosingType(chg.getMode())) {
final boolean isHide = chg.getMode() == TRANSIT_TO_BACK; final boolean isHide = chg.getMode() == TRANSIT_TO_BACK;
TaskViewTaskController tv = findTaskView(chg.getTaskInfo()); TaskViewTaskController tv = findTaskView(chg.getTaskInfo());
if (tv == null) { if (tv == null) {
throw new IllegalStateException("TaskView transition is closing a " if (pending != null) {
+ "non-taskview task "); Slog.w(TAG, "Found a non-TaskView task in a TaskView Transition. This "
+ "shouldn't happen, so there may be a visual artifact: "
+ chg.getTaskInfo().taskId);
}
continue;
} }
if (isHide) { if (isHide) {
tv.prepareHideAnimation(finishTransaction); tv.prepareHideAnimation(finishTransaction);
} else { } else {
tv.prepareCloseAnimation(); tv.prepareCloseAnimation();
} }
changesHandled++;
} else if (Transitions.isOpeningType(chg.getMode())) { } else if (Transitions.isOpeningType(chg.getMode())) {
final boolean taskIsNew = chg.getMode() == TRANSIT_OPEN; final boolean taskIsNew = chg.getMode() == TRANSIT_OPEN;
if (wct == null) wct = new WindowContainerTransaction(); final TaskViewTaskController tv;
TaskViewTaskController tv = taskView; if (taskIsNew) {
if (!taskIsNew) { if (pending == null
|| !chg.getTaskInfo().containsLaunchCookie(pending.mLaunchCookie)) {
Slog.e(TAG, "Found a launching TaskView in the wrong transition. All "
+ "TaskView launches should be initiated by shell and in their "
+ "own transition: " + chg.getTaskInfo().taskId);
continue;
}
stillNeedsMatchingLaunch = false;
tv = pending.mTaskView;
} else {
tv = findTaskView(chg.getTaskInfo()); tv = findTaskView(chg.getTaskInfo());
if (tv == null) { if (tv == null) {
throw new IllegalStateException("TaskView transition is showing a " if (pending != null) {
+ "non-taskview task "); Slog.w(TAG, "Found a non-TaskView task in a TaskView Transition. This "
+ "shouldn't happen, so there may be a visual artifact: "
+ chg.getTaskInfo().taskId);
}
continue;
} }
} }
if (wct == null) wct = new WindowContainerTransaction();
tv.prepareOpenAnimation(taskIsNew, startTransaction, finishTransaction, tv.prepareOpenAnimation(taskIsNew, startTransaction, finishTransaction,
chg.getTaskInfo(), chg.getLeash(), wct); chg.getTaskInfo(), chg.getLeash(), wct);
} else { changesHandled++;
throw new IllegalStateException("Claimed transition isn't an opening or closing"
+ " type: " + chg.getMode());
} }
} }
if (stillNeedsMatchingLaunch) {
throw new IllegalStateException("Expected a TaskView launch in this transition but"
+ " didn't get one.");
}
if (wct == null && pending == null && changesHandled != info.getChanges().size()) {
// Just some house-keeping, let another handler animate.
return false;
}
// No animation, just show it immediately. // No animation, just show it immediately.
startTransaction.apply(); startTransaction.apply();
finishTransaction.apply(); finishTransaction.apply();

View File

@@ -89,6 +89,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED; import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_RELAUNCH; import static android.view.WindowManager.TRANSIT_RELAUNCH;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale; import static android.view.WindowManager.fixScale;
import static android.view.WindowManagerGlobal.ADD_OKAY; import static android.view.WindowManagerGlobal.ADD_OKAY;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW; import static android.view.WindowManagerGlobal.RELAYOUT_RES_CANCEL_AND_REDRAW;
@@ -8689,7 +8690,13 @@ public class WindowManagerService extends IWindowManager.Stub
} }
} }
// focus-transfer can re-order windows and thus potentially causes visible changes:
final Transition transition = mAtmService.getTransitionController()
.requestTransitionIfNeeded(TRANSIT_TO_FRONT, task);
mAtmService.setFocusedTask(task.mTaskId, touchedActivity); mAtmService.setFocusedTask(task.mTaskId, touchedActivity);
if (transition != null) {
transition.setReady(task, true /* ready */);
}
} }
/** /**