diff options
15 files changed, 5 insertions, 1580 deletions
diff --git a/core/java/android/window/ITaskFragmentOrganizerController.aidl b/core/java/android/window/ITaskFragmentOrganizerController.aidl index 4706dfd1a76c..2c64b8ed456d 100644 --- a/core/java/android/window/ITaskFragmentOrganizerController.aidl +++ b/core/java/android/window/ITaskFragmentOrganizerController.aidl @@ -39,19 +39,6 @@ interface ITaskFragmentOrganizerController { void unregisterOrganizer(in ITaskFragmentOrganizer organizer); /** - * Registers remote animations per transition type for the organizer. It will override the - * animations if the transition only contains windows that belong to the organized - * TaskFragments in the given Task. - */ - void registerRemoteAnimations(in ITaskFragmentOrganizer organizer, - in RemoteAnimationDefinition definition); - - /** - * Unregisters remote animations per transition type for the organizer. - */ - void unregisterRemoteAnimations(in ITaskFragmentOrganizer organizer); - - /** * Checks if an activity organized by a {@link android.window.TaskFragmentOrganizer} and * only occupies a portion of Task bounds. */ diff --git a/core/java/android/window/TaskFragmentOrganizer.java b/core/java/android/window/TaskFragmentOrganizer.java index 461eab61e393..d4c3fbee0f79 100644 --- a/core/java/android/window/TaskFragmentOrganizer.java +++ b/core/java/android/window/TaskFragmentOrganizer.java @@ -32,7 +32,6 @@ import android.annotation.TestApi; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; -import android.view.RemoteAnimationDefinition; import android.view.WindowManager; import com.android.window.flags.Flags; @@ -205,34 +204,6 @@ public class TaskFragmentOrganizer extends WindowOrganizer { } /** - * Registers remote animations per transition type for the organizer. It will override the - * animations if the transition only contains windows that belong to the organized - * TaskFragments, and at least one of the transition window is embedded (not filling the Task). - * @hide - */ - @CallSuper - public void registerRemoteAnimations(@NonNull RemoteAnimationDefinition definition) { - try { - getController().registerRemoteAnimations(mInterface, definition); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Unregisters remote animations per transition type for the organizer. - * @hide - */ - @CallSuper - public void unregisterRemoteAnimations() { - try { - getController().unregisterRemoteAnimations(mInterface); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * Notifies the server that the organizer has finished handling the given transaction. The * server should apply the given {@link WindowContainerTransaction} for the necessary changes. * diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java index 9ea2943bc6da..1eb95c1efb08 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java @@ -70,10 +70,6 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { @NonNull private final TaskFragmentCallback mCallback; - @VisibleForTesting - @Nullable - TaskFragmentAnimationController mAnimationController; - /** * Callback that notifies the controller about changes to task fragments. */ @@ -91,25 +87,6 @@ class JetpackTaskFragmentOrganizer extends TaskFragmentOrganizer { mCallback = callback; } - @Override - public void unregisterOrganizer() { - if (mAnimationController != null) { - mAnimationController.unregisterRemoteAnimations(); - mAnimationController = null; - } - super.unregisterOrganizer(); - } - - /** - * Overrides the animation for transitions of embedded activities organized by this organizer. - */ - void overrideSplitAnimation() { - if (mAnimationController == null) { - mAnimationController = new TaskFragmentAnimationController(this); - } - mAnimationController.registerRemoteAnimations(); - } - /** * Starts a new Activity and puts it into split with an existing Activity side-by-side. * @param launchingFragmentToken token for the launching TaskFragment. If it exists, it will diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 7ddda1f98809..3261a370d2ca 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -114,7 +114,6 @@ import java.util.function.BiConsumer; public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmentCallback, ActivityEmbeddingComponent, DividerPresenter.DragEventCallback { static final String TAG = "SplitController"; - static final boolean ENABLE_SHELL_TRANSITIONS = true; // TODO(b/243518738): Move to WM Extensions if we have requirement of overlay without // association. It's not set in WM Extensions nor Wm Jetpack library currently. diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java index eb1fc23d6b00..ea60b1531a3f 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java @@ -166,11 +166,6 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { mWindowLayoutComponent = windowLayoutComponent; mController = controller; registerOrganizer(); - if (!SplitController.ENABLE_SHELL_TRANSITIONS) { - // TODO(b/207070762): cleanup with legacy app transition - // Animation will be handled by WM Shell when Shell transition is enabled. - overrideSplitAnimation(); - } } /** diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java deleted file mode 100644 index 33220c44a3b5..000000000000 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationAdapter.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.window.extensions.embedding; - -import static android.graphics.Matrix.MTRANS_X; -import static android.graphics.Matrix.MTRANS_Y; -import static android.view.RemoteAnimationTarget.MODE_CLOSING; - -import android.graphics.Point; -import android.graphics.Rect; -import android.view.Choreographer; -import android.view.RemoteAnimationTarget; -import android.view.SurfaceControl; -import android.view.animation.Animation; -import android.view.animation.Transformation; - -import androidx.annotation.NonNull; - -/** - * Wrapper to handle the TaskFragment animation update in one {@link SurfaceControl.Transaction}. - * - * The base adapter can be used for {@link RemoteAnimationTarget} that is simple open/close. - */ -class TaskFragmentAnimationAdapter { - - /** - * If {@link #mOverrideLayer} is set to this value, we don't want to override the surface layer. - */ - private static final int LAYER_NO_OVERRIDE = -1; - - @NonNull - final Animation mAnimation; - @NonNull - final RemoteAnimationTarget mTarget; - @NonNull - final SurfaceControl mLeash; - /** Area in absolute coordinate that the animation surface shouldn't go beyond. */ - @NonNull - private final Rect mWholeAnimationBounds = new Rect(); - /** - * Area in absolute coordinate that should represent all the content to show for this window. - * This should be the end bounds for opening window, and start bounds for closing window in case - * the window is resizing during the open/close transition. - */ - @NonNull - private final Rect mContentBounds = new Rect(); - /** Offset relative to the window parent surface for {@link #mContentBounds}. */ - @NonNull - private final Point mContentRelOffset = new Point(); - - @NonNull - final Transformation mTransformation = new Transformation(); - @NonNull - final float[] mMatrix = new float[9]; - @NonNull - final float[] mVecs = new float[4]; - @NonNull - final Rect mRect = new Rect(); - private boolean mIsFirstFrame = true; - private int mOverrideLayer = LAYER_NO_OVERRIDE; - - TaskFragmentAnimationAdapter(@NonNull Animation animation, - @NonNull RemoteAnimationTarget target) { - this(animation, target, target.leash, target.screenSpaceBounds); - } - - /** - * @param leash the surface to animate. - * @param wholeAnimationBounds area in absolute coordinate that the animation surface shouldn't - * go beyond. - */ - TaskFragmentAnimationAdapter(@NonNull Animation animation, - @NonNull RemoteAnimationTarget target, @NonNull SurfaceControl leash, - @NonNull Rect wholeAnimationBounds) { - mAnimation = animation; - mTarget = target; - mLeash = leash; - mWholeAnimationBounds.set(wholeAnimationBounds); - if (target.mode == MODE_CLOSING) { - // When it is closing, we want to show the content at the start position in case the - // window is resizing as well. For example, when the activities is changing from split - // to stack, the bottom TaskFragment will be resized to fullscreen when hiding. - final Rect startBounds = target.startBounds; - final Rect endBounds = target.screenSpaceBounds; - mContentBounds.set(startBounds); - mContentRelOffset.set(target.localBounds.left, target.localBounds.top); - mContentRelOffset.offset( - startBounds.left - endBounds.left, - startBounds.top - endBounds.top); - } else { - mContentBounds.set(target.screenSpaceBounds); - mContentRelOffset.set(target.localBounds.left, target.localBounds.top); - } - } - - /** - * Surface layer to be set at the first frame of the animation. We will not set the layer if it - * is set to {@link #LAYER_NO_OVERRIDE}. - */ - final void overrideLayer(int layer) { - mOverrideLayer = layer; - } - - /** Called on frame update. */ - final void onAnimationUpdate(@NonNull SurfaceControl.Transaction t, long currentPlayTime) { - if (mIsFirstFrame) { - t.show(mLeash); - if (mOverrideLayer != LAYER_NO_OVERRIDE) { - t.setLayer(mLeash, mOverrideLayer); - } - mIsFirstFrame = false; - } - - // Extract the transformation to the current time. - mAnimation.getTransformation(Math.min(currentPlayTime, mAnimation.getDuration()), - mTransformation); - t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId()); - onAnimationUpdateInner(t); - } - - /** To be overridden by subclasses to adjust the animation surface change. */ - void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) { - // Update the surface position and alpha. - mTransformation.getMatrix().postTranslate(mContentRelOffset.x, mContentRelOffset.y); - t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix); - t.setAlpha(mLeash, mTransformation.getAlpha()); - - // Get current surface bounds in absolute coordinate. - // positionX/Y are in local coordinate, so minus the local offset to get the slide amount. - final int positionX = Math.round(mMatrix[MTRANS_X]); - final int positionY = Math.round(mMatrix[MTRANS_Y]); - final Rect cropRect = new Rect(mContentBounds); - cropRect.offset(positionX - mContentRelOffset.x, positionY - mContentRelOffset.y); - - // Store the current offset of the surface top left from (0,0) in absolute coordinate. - final int offsetX = cropRect.left; - final int offsetY = cropRect.top; - - // Intersect to make sure the animation happens within the whole animation bounds. - if (!cropRect.intersect(mWholeAnimationBounds)) { - // Hide the surface when it is outside of the animation area. - t.setAlpha(mLeash, 0); - } - - // cropRect is in absolute coordinate, so we need to translate it to surface top left. - cropRect.offset(-offsetX, -offsetY); - t.setCrop(mLeash, cropRect); - } - - /** Called after animation finished. */ - final void onAnimationEnd(@NonNull SurfaceControl.Transaction t) { - onAnimationUpdate(t, mAnimation.getDuration()); - } - - final long getDurationHint() { - return mAnimation.computeDurationHint(); - } - - /** - * Should be used for the animation of the snapshot of a {@link RemoteAnimationTarget} that has - * size change. - */ - static class SnapshotAdapter extends TaskFragmentAnimationAdapter { - - SnapshotAdapter(@NonNull Animation animation, @NonNull RemoteAnimationTarget target) { - // Start leash is the snapshot of the starting surface. - super(animation, target, target.startLeash, target.screenSpaceBounds); - } - - @Override - void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) { - // Snapshot should always be placed at the top left of the animation leash. - mTransformation.getMatrix().postTranslate(0, 0); - t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix); - t.setAlpha(mLeash, mTransformation.getAlpha()); - } - } - - /** - * Should be used for the animation of the {@link RemoteAnimationTarget} that has size change. - */ - static class BoundsChangeAdapter extends TaskFragmentAnimationAdapter { - - BoundsChangeAdapter(@NonNull Animation animation, @NonNull RemoteAnimationTarget target) { - super(animation, target); - } - - @Override - void onAnimationUpdateInner(@NonNull SurfaceControl.Transaction t) { - mTransformation.getMatrix().postTranslate( - mTarget.localBounds.left, mTarget.localBounds.top); - t.setMatrix(mLeash, mTransformation.getMatrix(), mMatrix); - t.setAlpha(mLeash, mTransformation.getAlpha()); - - // The following applies an inverse scale to the clip-rect so that it crops "after" the - // scale instead of before. - mVecs[1] = mVecs[2] = 0; - mVecs[0] = mVecs[3] = 1; - mTransformation.getMatrix().mapVectors(mVecs); - mVecs[0] = 1.f / mVecs[0]; - mVecs[3] = 1.f / mVecs[3]; - final Rect clipRect = mTransformation.getClipRect(); - mRect.left = (int) (clipRect.left * mVecs[0] + 0.5f); - mRect.right = (int) (clipRect.right * mVecs[0] + 0.5f); - mRect.top = (int) (clipRect.top * mVecs[3] + 0.5f); - mRect.bottom = (int) (clipRect.bottom * mVecs[3] + 0.5f); - t.setWindowCrop(mLeash, mRect); - } - } -} diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java deleted file mode 100644 index d7eb9a01f57c..000000000000 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationController.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.window.extensions.embedding; - -import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN; - -import android.util.Log; -import android.view.RemoteAnimationAdapter; -import android.view.RemoteAnimationDefinition; -import android.window.TaskFragmentOrganizer; - -import androidx.annotation.NonNull; - -import com.android.internal.annotations.VisibleForTesting; - -/** Controls the TaskFragment remote animations. */ -class TaskFragmentAnimationController { - - private static final String TAG = "TaskFragAnimationCtrl"; - static final boolean DEBUG = false; - - private final TaskFragmentOrganizer mOrganizer; - private final TaskFragmentAnimationRunner mRemoteRunner = new TaskFragmentAnimationRunner(); - @VisibleForTesting - final RemoteAnimationDefinition mDefinition; - private boolean mIsRegistered; - - TaskFragmentAnimationController(@NonNull TaskFragmentOrganizer organizer) { - mOrganizer = organizer; - mDefinition = new RemoteAnimationDefinition(); - final RemoteAnimationAdapter animationAdapter = - new RemoteAnimationAdapter(mRemoteRunner, 0, 0, true /* changeNeedsSnapshot */); - mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, animationAdapter); - mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, animationAdapter); - mDefinition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_CLOSE, animationAdapter); - mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, animationAdapter); - mDefinition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, animationAdapter); - } - - void registerRemoteAnimations() { - if (DEBUG) { - Log.v(TAG, "registerRemoteAnimations"); - } - if (mIsRegistered) { - return; - } - mOrganizer.registerRemoteAnimations(mDefinition); - mIsRegistered = true; - } - - void unregisterRemoteAnimations() { - if (DEBUG) { - Log.v(TAG, "unregisterRemoteAnimations"); - } - if (!mIsRegistered) { - return; - } - mOrganizer.unregisterRemoteAnimations(); - mIsRegistered = false; - } -} diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java deleted file mode 100644 index d9b73a8290f5..000000000000 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.window.extensions.embedding; - -import static android.os.Process.THREAD_PRIORITY_DISPLAY; -import static android.view.RemoteAnimationTarget.MODE_CHANGING; -import static android.view.RemoteAnimationTarget.MODE_CLOSING; -import static android.view.RemoteAnimationTarget.MODE_OPENING; -import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN; -import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET; - -import android.animation.Animator; -import android.animation.ValueAnimator; -import android.graphics.Rect; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.RemoteException; -import android.util.Log; -import android.view.IRemoteAnimationFinishedCallback; -import android.view.IRemoteAnimationRunner; -import android.view.RemoteAnimationTarget; -import android.view.SurfaceControl; -import android.view.WindowManager; -import android.view.animation.Animation; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; - -/** To run the TaskFragment animations. */ -class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub { - - private static final String TAG = "TaskFragAnimationRunner"; - private final Handler mHandler; - private final TaskFragmentAnimationSpec mAnimationSpec; - - TaskFragmentAnimationRunner() { - HandlerThread animationThread = new HandlerThread( - "androidx.window.extensions.embedding", THREAD_PRIORITY_DISPLAY); - animationThread.start(); - mHandler = animationThread.getThreadHandler(); - mAnimationSpec = new TaskFragmentAnimationSpec(mHandler); - } - - @Nullable - private Animator mAnimator; - - @Override - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - @NonNull RemoteAnimationTarget[] apps, - @NonNull RemoteAnimationTarget[] wallpapers, - @NonNull RemoteAnimationTarget[] nonApps, - @NonNull IRemoteAnimationFinishedCallback finishedCallback) { - if (wallpapers.length != 0 || nonApps.length != 0) { - throw new IllegalArgumentException("TaskFragment shouldn't handle animation with" - + "wallpaper or non-app windows."); - } - if (TaskFragmentAnimationController.DEBUG) { - Log.v(TAG, "onAnimationStart transit=" + transit); - } - mHandler.post(() -> startAnimation(transit, apps, finishedCallback)); - } - - @Override - public void onAnimationCancelled() { - mHandler.post(this::cancelAnimation); - } - - /** Creates and starts animation. */ - private void startAnimation(@WindowManager.TransitionOldType int transit, - @NonNull RemoteAnimationTarget[] targets, - @NonNull IRemoteAnimationFinishedCallback finishedCallback) { - if (mAnimator != null) { - Log.w(TAG, "start new animation when the previous one is not finished yet."); - mAnimator.cancel(); - } - mAnimator = createAnimator(transit, targets, finishedCallback); - mAnimator.start(); - } - - /** Cancels animation. */ - private void cancelAnimation() { - if (mAnimator == null) { - return; - } - mAnimator.cancel(); - mAnimator = null; - } - - /** Creates the animator given the transition type and windows. */ - @NonNull - private Animator createAnimator(@WindowManager.TransitionOldType int transit, - @NonNull RemoteAnimationTarget[] targets, - @NonNull IRemoteAnimationFinishedCallback finishedCallback) { - final List<TaskFragmentAnimationAdapter> adapters = - createAnimationAdapters(transit, targets); - long duration = 0; - for (TaskFragmentAnimationAdapter adapter : adapters) { - duration = Math.max(duration, adapter.getDurationHint()); - } - final ValueAnimator animator = ValueAnimator.ofFloat(0, 1); - animator.setDuration(duration); - animator.addUpdateListener((anim) -> { - // Update all adapters in the same transaction. - final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); - for (TaskFragmentAnimationAdapter adapter : adapters) { - adapter.onAnimationUpdate(t, animator.getCurrentPlayTime()); - } - t.apply(); - }); - animator.addListener(new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) {} - - @Override - public void onAnimationEnd(Animator animation) { - final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); - for (TaskFragmentAnimationAdapter adapter : adapters) { - adapter.onAnimationEnd(t); - } - t.apply(); - - try { - finishedCallback.onAnimationFinished(); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - mAnimator = null; - } - - @Override - public void onAnimationCancel(Animator animation) {} - - @Override - public void onAnimationRepeat(Animator animation) {} - }); - return animator; - } - - /** List of {@link TaskFragmentAnimationAdapter} to handle animations on all window targets. */ - @NonNull - private List<TaskFragmentAnimationAdapter> createAnimationAdapters( - @WindowManager.TransitionOldType int transit, - @NonNull RemoteAnimationTarget[] targets) { - switch (transit) { - case TRANSIT_OLD_ACTIVITY_OPEN: - case TRANSIT_OLD_TASK_FRAGMENT_OPEN: - return createOpenAnimationAdapters(targets); - case TRANSIT_OLD_ACTIVITY_CLOSE: - case TRANSIT_OLD_TASK_FRAGMENT_CLOSE: - return createCloseAnimationAdapters(targets); - case TRANSIT_OLD_TASK_FRAGMENT_CHANGE: - return createChangeAnimationAdapters(targets); - default: - throw new IllegalArgumentException("Unhandled transit type=" + transit); - } - } - - @NonNull - private List<TaskFragmentAnimationAdapter> createOpenAnimationAdapters( - @NonNull RemoteAnimationTarget[] targets) { - return createOpenCloseAnimationAdapters(targets, true /* isOpening */, - mAnimationSpec::loadOpenAnimation); - } - - @NonNull - private List<TaskFragmentAnimationAdapter> createCloseAnimationAdapters( - @NonNull RemoteAnimationTarget[] targets) { - return createOpenCloseAnimationAdapters(targets, false /* isOpening */, - mAnimationSpec::loadCloseAnimation); - } - - /** - * Creates {@link TaskFragmentAnimationAdapter} for OPEN and CLOSE types of transition. - * @param isOpening {@code true} for OPEN type, {@code false} for CLOSE type. - */ - @NonNull - private List<TaskFragmentAnimationAdapter> createOpenCloseAnimationAdapters( - @NonNull RemoteAnimationTarget[] targets, boolean isOpening, - @NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider) { - // We need to know if the target window is only a partial of the whole animation screen. - // If so, we will need to adjust it to make the whole animation screen looks like one. - final List<RemoteAnimationTarget> openingTargets = new ArrayList<>(); - final List<RemoteAnimationTarget> closingTargets = new ArrayList<>(); - final Rect openingWholeScreenBounds = new Rect(); - final Rect closingWholeScreenBounds = new Rect(); - for (RemoteAnimationTarget target : targets) { - if (target.mode != MODE_CLOSING) { - openingTargets.add(target); - openingWholeScreenBounds.union(target.screenSpaceBounds); - } else { - closingTargets.add(target); - closingWholeScreenBounds.union(target.screenSpaceBounds); - // Union the start bounds since this may be the ClosingChanging animation. - closingWholeScreenBounds.union(target.startBounds); - } - } - - // For OPEN transition, open windows should be above close windows. - // For CLOSE transition, open windows should be below close windows. - int offsetLayer = TYPE_LAYER_OFFSET; - final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>(); - for (RemoteAnimationTarget target : openingTargets) { - final TaskFragmentAnimationAdapter adapter = createOpenCloseAnimationAdapter(target, - animationProvider, openingWholeScreenBounds); - if (isOpening) { - adapter.overrideLayer(offsetLayer++); - } - adapters.add(adapter); - } - for (RemoteAnimationTarget target : closingTargets) { - final TaskFragmentAnimationAdapter adapter = createOpenCloseAnimationAdapter(target, - animationProvider, closingWholeScreenBounds); - if (!isOpening) { - adapter.overrideLayer(offsetLayer++); - } - adapters.add(adapter); - } - return adapters; - } - - @NonNull - private TaskFragmentAnimationAdapter createOpenCloseAnimationAdapter( - @NonNull RemoteAnimationTarget target, - @NonNull BiFunction<RemoteAnimationTarget, Rect, Animation> animationProvider, - @NonNull Rect wholeAnimationBounds) { - final Animation animation = animationProvider.apply(target, wholeAnimationBounds); - return new TaskFragmentAnimationAdapter(animation, target, target.leash, - wholeAnimationBounds); - } - - @NonNull - private List<TaskFragmentAnimationAdapter> createChangeAnimationAdapters( - @NonNull RemoteAnimationTarget[] targets) { - if (shouldUseJumpCutForChangeAnimation(targets)) { - return new ArrayList<>(); - } - - final List<TaskFragmentAnimationAdapter> adapters = new ArrayList<>(); - for (RemoteAnimationTarget target : targets) { - if (target.mode == MODE_CHANGING) { - // This is the target with bounds change. - final Animation[] animations = - mAnimationSpec.createChangeBoundsChangeAnimations(target); - // Adapter for the starting snapshot leash. - adapters.add(new TaskFragmentAnimationAdapter.SnapshotAdapter( - animations[0], target)); - // Adapter for the ending bounds changed leash. - adapters.add(new TaskFragmentAnimationAdapter.BoundsChangeAdapter( - animations[1], target)); - continue; - } - - // These are the other targets that don't have bounds change in the same transition. - final Animation animation; - if (target.hasAnimatingParent) { - // No-op if it will be covered by the changing parent window. - animation = TaskFragmentAnimationSpec.createNoopAnimation(target); - } else if (target.mode == MODE_CLOSING) { - animation = mAnimationSpec.createChangeBoundsCloseAnimation(target); - } else { - animation = mAnimationSpec.createChangeBoundsOpenAnimation(target); - } - adapters.add(new TaskFragmentAnimationAdapter(animation, target)); - } - return adapters; - } - - /** - * Whether we should use jump cut for the change transition. - * This normally happens when opening a new secondary with the existing primary using a - * different split layout. This can be complicated, like from horizontal to vertical split with - * new split pairs. - * Uses a jump cut animation to simplify. - */ - private boolean shouldUseJumpCutForChangeAnimation(@NonNull RemoteAnimationTarget[] targets) { - boolean hasOpeningWindow = false; - boolean hasClosingWindow = false; - for (RemoteAnimationTarget target : targets) { - if (target.hasAnimatingParent) { - continue; - } - hasOpeningWindow |= target.mode == MODE_OPENING; - hasClosingWindow |= target.mode == MODE_CLOSING; - } - return hasOpeningWindow && hasClosingWindow; - } -} diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java deleted file mode 100644 index 1f866c3b99c9..000000000000 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationSpec.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.window.extensions.embedding; - -import static android.view.RemoteAnimationTarget.MODE_CLOSING; - -import android.app.ActivityThread; -import android.content.ContentResolver; -import android.content.Context; -import android.database.ContentObserver; -import android.graphics.Rect; -import android.os.Handler; -import android.provider.Settings; -import android.view.RemoteAnimationTarget; -import android.view.WindowManager; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.view.animation.AnimationSet; -import android.view.animation.AnimationUtils; -import android.view.animation.ClipRectAnimation; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; -import android.view.animation.ScaleAnimation; -import android.view.animation.TranslateAnimation; - -import androidx.annotation.NonNull; - -import com.android.internal.R; -import com.android.internal.policy.AttributeCache; -import com.android.internal.policy.TransitionAnimation; - -/** Animation spec for TaskFragment transition. */ -// TODO(b/206557124): provide an easier way to customize animation -class TaskFragmentAnimationSpec { - - private static final String TAG = "TaskFragAnimationSpec"; - private static final int CHANGE_ANIMATION_DURATION = 517; - private static final int CHANGE_ANIMATION_FADE_DURATION = 80; - private static final int CHANGE_ANIMATION_FADE_OFFSET = 30; - - private final Context mContext; - private final TransitionAnimation mTransitionAnimation; - private final Interpolator mFastOutExtraSlowInInterpolator; - private final LinearInterpolator mLinearInterpolator; - private float mTransitionAnimationScaleSetting; - - TaskFragmentAnimationSpec(@NonNull Handler handler) { - mContext = ActivityThread.currentActivityThread().getApplication(); - mTransitionAnimation = new TransitionAnimation(mContext, false /* debug */, TAG); - // Initialize the AttributeCache for the TransitionAnimation. - AttributeCache.init(mContext); - mFastOutExtraSlowInInterpolator = AnimationUtils.loadInterpolator( - mContext, android.R.interpolator.fast_out_extra_slow_in); - mLinearInterpolator = new LinearInterpolator(); - - // The transition animation should be adjusted based on the developer option. - final ContentResolver resolver = mContext.getContentResolver(); - mTransitionAnimationScaleSetting = getTransitionAnimationScaleSetting(); - resolver.registerContentObserver( - Settings.Global.getUriFor(Settings.Global.TRANSITION_ANIMATION_SCALE), false, - new SettingsObserver(handler)); - } - - /** For target that doesn't need to be animated. */ - @NonNull - static Animation createNoopAnimation(@NonNull RemoteAnimationTarget target) { - // Noop but just keep the target showing/hiding. - final float alpha = target.mode == MODE_CLOSING ? 0f : 1f; - return new AlphaAnimation(alpha, alpha); - } - - /** Animation for target that is opening in a change transition. */ - @NonNull - Animation createChangeBoundsOpenAnimation(@NonNull RemoteAnimationTarget target) { - final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds(); - final Rect bounds = target.screenSpaceBounds; - final int startLeft; - final int startTop; - if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { - // The window will be animated in from left or right depending on its position. - startTop = 0; - startLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); - } else { - // The window will be animated in from top or bottom depending on its position. - startTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); - startLeft = 0; - } - - // The position should be 0-based as we will post translate in - // TaskFragmentAnimationAdapter#onAnimationUpdate - final Animation animation = new TranslateAnimation(startLeft, 0, startTop, 0); - animation.setInterpolator(mFastOutExtraSlowInInterpolator); - animation.setDuration(CHANGE_ANIMATION_DURATION); - animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height()); - animation.scaleCurrentDuration(mTransitionAnimationScaleSetting); - return animation; - } - - /** Animation for target that is closing in a change transition. */ - @NonNull - Animation createChangeBoundsCloseAnimation(@NonNull RemoteAnimationTarget target) { - final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds(); - // Use startBounds if the window is closing in case it may also resize. - final Rect bounds = target.startBounds; - final int endTop; - final int endLeft; - if (parentBounds.top == bounds.top && parentBounds.bottom == bounds.bottom) { - // The window will be animated out to left or right depending on its position. - endTop = 0; - endLeft = parentBounds.left == bounds.left ? -bounds.width() : bounds.width(); - } else { - // The window will be animated out to top or bottom depending on its position. - endTop = parentBounds.top == bounds.top ? -bounds.height() : bounds.height(); - endLeft = 0; - } - - // The position should be 0-based as we will post translate in - // TaskFragmentAnimationAdapter#onAnimationUpdate - final Animation animation = new TranslateAnimation(0, endLeft, 0, endTop); - animation.setInterpolator(mFastOutExtraSlowInInterpolator); - animation.setDuration(CHANGE_ANIMATION_DURATION); - animation.initialize(bounds.width(), bounds.height(), bounds.width(), bounds.height()); - animation.scaleCurrentDuration(mTransitionAnimationScaleSetting); - return animation; - } - - /** - * Animation for target that is changing (bounds change) in a change transition. - * @return the return array always has two elements. The first one is for the start leash, and - * the second one is for the end leash. - */ - @NonNull - Animation[] createChangeBoundsChangeAnimations(@NonNull RemoteAnimationTarget target) { - // Both start bounds and end bounds are in screen coordinates. We will post translate - // to the local coordinates in TaskFragmentAnimationAdapter#onAnimationUpdate - final Rect startBounds = target.startBounds; - final Rect parentBounds = target.taskInfo.configuration.windowConfiguration.getBounds(); - final Rect endBounds = target.screenSpaceBounds; - float scaleX = ((float) startBounds.width()) / endBounds.width(); - float scaleY = ((float) startBounds.height()) / endBounds.height(); - // Start leash is a child of the end leash. Reverse the scale so that the start leash won't - // be scaled up with its parent. - float startScaleX = 1.f / scaleX; - float startScaleY = 1.f / scaleY; - - // The start leash will be fade out. - final AnimationSet startSet = new AnimationSet(false /* shareInterpolator */); - final Animation startAlpha = new AlphaAnimation(1f, 0f); - startAlpha.setInterpolator(mLinearInterpolator); - startAlpha.setDuration(CHANGE_ANIMATION_FADE_DURATION); - startAlpha.setStartOffset(CHANGE_ANIMATION_FADE_OFFSET); - startSet.addAnimation(startAlpha); - final Animation startScale = new ScaleAnimation(startScaleX, startScaleX, startScaleY, - startScaleY); - startScale.setInterpolator(mFastOutExtraSlowInInterpolator); - startScale.setDuration(CHANGE_ANIMATION_DURATION); - startSet.addAnimation(startScale); - startSet.initialize(startBounds.width(), startBounds.height(), endBounds.width(), - endBounds.height()); - startSet.scaleCurrentDuration(mTransitionAnimationScaleSetting); - - // The end leash will be moved into the end position while scaling. - final AnimationSet endSet = new AnimationSet(true /* shareInterpolator */); - endSet.setInterpolator(mFastOutExtraSlowInInterpolator); - final Animation endScale = new ScaleAnimation(scaleX, 1, scaleY, 1); - endScale.setDuration(CHANGE_ANIMATION_DURATION); - endSet.addAnimation(endScale); - // The position should be 0-based as we will post translate in - // TaskFragmentAnimationAdapter#onAnimationUpdate - final Animation endTranslate = new TranslateAnimation(startBounds.left - endBounds.left, 0, - startBounds.top - endBounds.top, 0); - endTranslate.setDuration(CHANGE_ANIMATION_DURATION); - endSet.addAnimation(endTranslate); - // The end leash is resizing, we should update the window crop based on the clip rect. - final Rect startClip = new Rect(startBounds); - final Rect endClip = new Rect(endBounds); - startClip.offsetTo(0, 0); - endClip.offsetTo(0, 0); - final Animation clipAnim = new ClipRectAnimation(startClip, endClip); - clipAnim.setDuration(CHANGE_ANIMATION_DURATION); - endSet.addAnimation(clipAnim); - endSet.initialize(startBounds.width(), startBounds.height(), parentBounds.width(), - parentBounds.height()); - endSet.scaleCurrentDuration(mTransitionAnimationScaleSetting); - - return new Animation[]{startSet, endSet}; - } - - @NonNull - Animation loadOpenAnimation(@NonNull RemoteAnimationTarget target, - @NonNull Rect wholeAnimationBounds) { - final boolean isEnter = target.mode != MODE_CLOSING; - final Animation animation; - // Background color on TaskDisplayArea has already been set earlier in - // WindowContainer#getAnimationAdapter. - if (target.showBackdrop) { - animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter - ? com.android.internal.R.anim.task_fragment_clear_top_open_enter - : com.android.internal.R.anim.task_fragment_clear_top_open_exit); - } else { - animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter - ? com.android.internal.R.anim.task_fragment_open_enter - : com.android.internal.R.anim.task_fragment_open_exit); - } - // Use the whole animation bounds instead of the change bounds, so that when multiple change - // targets are opening at the same time, the animation applied to each will be the same. - // Otherwise, we may see gap between the activities that are launching together. - animation.initialize(wholeAnimationBounds.width(), wholeAnimationBounds.height(), - wholeAnimationBounds.width(), wholeAnimationBounds.height()); - animation.scaleCurrentDuration(mTransitionAnimationScaleSetting); - return animation; - } - - @NonNull - Animation loadCloseAnimation(@NonNull RemoteAnimationTarget target, - @NonNull Rect wholeAnimationBounds) { - final boolean isEnter = target.mode != MODE_CLOSING; - final Animation animation; - if (target.showBackdrop) { - animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter - ? com.android.internal.R.anim.task_fragment_clear_top_close_enter - : com.android.internal.R.anim.task_fragment_clear_top_close_exit); - } else { - animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter - ? com.android.internal.R.anim.task_fragment_close_enter - : com.android.internal.R.anim.task_fragment_close_exit); - } - // Use the whole animation bounds instead of the change bounds, so that when multiple change - // targets are closing at the same time, the animation applied to each will be the same. - // Otherwise, we may see gap between the activities that are finishing together. - animation.initialize(wholeAnimationBounds.width(), wholeAnimationBounds.height(), - wholeAnimationBounds.width(), wholeAnimationBounds.height()); - animation.scaleCurrentDuration(mTransitionAnimationScaleSetting); - return animation; - } - - private float getTransitionAnimationScaleSetting() { - return WindowManager.fixScale(Settings.Global.getFloat(mContext.getContentResolver(), - Settings.Global.TRANSITION_ANIMATION_SCALE, mContext.getResources().getFloat( - R.dimen.config_appTransitionAnimationDurationScaleDefault))); - } - - private class SettingsObserver extends ContentObserver { - SettingsObserver(@NonNull Handler handler) { - super(handler); - } - - @Override - public void onChange(boolean selfChange) { - mTransitionAnimationScaleSetting = getTransitionAnimationScaleSetting(); - } - } -} diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java index 7b473b04548c..ad41b18dcbc6 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizerTest.java @@ -23,8 +23,6 @@ import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTest import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -86,24 +84,6 @@ public class JetpackTaskFragmentOrganizerTest { } @Test - public void testUnregisterOrganizer() { - mOrganizer.overrideSplitAnimation(); - mOrganizer.unregisterOrganizer(); - - verify(mOrganizer).unregisterRemoteAnimations(); - } - - @Test - public void testOverrideSplitAnimation() { - assertNull(mOrganizer.mAnimationController); - - mOrganizer.overrideSplitAnimation(); - - assertNotNull(mOrganizer.mAnimationController); - verify(mOrganizer).registerRemoteAnimations(mOrganizer.mAnimationController.mDefinition); - } - - @Test public void testExpandTaskFragment() { final TaskContainer taskContainer = createTestTaskContainer(); doReturn(taskContainer).when(mSplitController).getTaskContainer(anyInt()); diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java deleted file mode 100644 index a1e9f08585f6..000000000000 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentAnimationControllerTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.window.extensions.embedding; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; - -import static org.mockito.Mockito.never; - -import android.platform.test.annotations.Presubmit; -import android.window.TaskFragmentOrganizer; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -/** - * Test class for {@link TaskFragmentAnimationController}. - * - * Build/Install/Run: - * atest WMJetpackUnitTests:TaskFragmentAnimationControllerTest - */ -@Presubmit -@SmallTest -@RunWith(AndroidJUnit4.class) -public class TaskFragmentAnimationControllerTest { - @Rule - public MockitoRule rule = MockitoJUnit.rule(); - - @Mock - private TaskFragmentOrganizer mOrganizer; - private TaskFragmentAnimationController mAnimationController; - - @Before - public void setup() { - mAnimationController = new TaskFragmentAnimationController(mOrganizer); - } - - @Test - public void testRegisterRemoteAnimations() { - mAnimationController.registerRemoteAnimations(); - - verify(mOrganizer).registerRemoteAnimations(mAnimationController.mDefinition); - - mAnimationController.registerRemoteAnimations(); - - // No extra call if it has been registered. - verify(mOrganizer).registerRemoteAnimations(mAnimationController.mDefinition); - } - - @Test - public void testUnregisterRemoteAnimations() { - mAnimationController.unregisterRemoteAnimations(); - - // No call if it is not registered. - verify(mOrganizer, never()).unregisterRemoteAnimations(); - - mAnimationController.registerRemoteAnimations(); - mAnimationController.unregisterRemoteAnimations(); - - verify(mOrganizer).unregisterRemoteAnimations(); - - mAnimationController.unregisterRemoteAnimations(); - - // No extra call if it has been unregistered. - verify(mOrganizer).unregisterRemoteAnimations(); - } -} diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java index 44b414f1ea7e..78636a7870cf 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -98,7 +98,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.function.Consumer; import java.util.function.Predicate; /** @@ -290,12 +289,10 @@ public class AppTransitionController { getTopApp(mDisplayContent.mChangingContainers, false /* ignoreHidden */); final WindowManager.LayoutParams animLp = getAnimLp(animLpActivity); - // Check if there is any override - if (!overrideWithTaskFragmentRemoteAnimation(transit, activityTypes)) { - // Unfreeze the windows that were previously frozen for TaskFragment animation. - unfreezeEmbeddedChangingWindows(); - overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes); - } + // No AE remote animation with Shell transition. + // Unfreeze the windows that were previously frozen for TaskFragment animation. + unfreezeEmbeddedChangingWindows(); + overrideWithRemoteAnimationIfSet(animLpActivity, transit, activityTypes); final boolean voiceInteraction = containsVoiceInteraction(mDisplayContent.mClosingApps) || containsVoiceInteraction(mDisplayContent.mOpeningApps); @@ -726,64 +723,6 @@ public class AppTransitionController { } /** - * Overrides the pending transition with the remote animation defined by the - * {@link ITaskFragmentOrganizer} if all windows in the transition are children of - * {@link TaskFragment} that are organized by the same organizer. - * - * @return {@code true} if the transition is overridden. - */ - private boolean overrideWithTaskFragmentRemoteAnimation(@TransitionOldType int transit, - ArraySet<Integer> activityTypes) { - if (transitionMayContainNonAppWindows(transit)) { - return false; - } - if (!transitionContainsTaskFragmentWithBoundsOverride()) { - // No need to play TaskFragment remote animation if all embedded TaskFragment in the - // transition fill the Task. - return false; - } - - final Task task = findParentTaskForAllEmbeddedWindows(); - final ITaskFragmentOrganizer organizer = findTaskFragmentOrganizer(task); - final RemoteAnimationDefinition definition = organizer != null - ? mDisplayContent.mAtmService.mTaskFragmentOrganizerController - .getRemoteAnimationDefinition(organizer) - : null; - final RemoteAnimationAdapter adapter = definition != null - ? definition.getAdapter(transit, activityTypes) - : null; - if (adapter == null) { - return false; - } - mDisplayContent.mAppTransition.overridePendingAppTransitionRemote( - adapter, false /* sync */, true /*isActivityEmbedding*/); - ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, - "Override with TaskFragment remote animation for transit=%s", - AppTransition.appTransitionOldToString(transit)); - - final int organizerUid = mDisplayContent.mAtmService.mTaskFragmentOrganizerController - .getTaskFragmentOrganizerUid(organizer); - final boolean shouldDisableInputForRemoteAnimation = !task.isFullyTrustedEmbedding( - organizerUid); - final RemoteAnimationController remoteAnimationController = - mDisplayContent.mAppTransition.getRemoteAnimationController(); - if (shouldDisableInputForRemoteAnimation && remoteAnimationController != null) { - // We are going to use client-driven animation, Disable all input on activity windows - // during the animation (unless it is fully trusted) to ensure it is safe to allow - // client to animate the surfaces. - // This is needed for all activity windows in the animation Task. - remoteAnimationController.setOnRemoteAnimationReady(() -> { - final Consumer<ActivityRecord> updateActivities = - activity -> activity.setDropInputForAnimation(true); - task.forAllActivities(updateActivities); - }); - ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "Task=%d contains embedded TaskFragment." - + " Disabled all input during TaskFragment remote animation.", task.mTaskId); - } - return true; - } - - /** * Overrides the pending transition with the remote animation defined for the transition in the * set of defined remote animations in the app window token. */ diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java index b6b6cf2dc430..439c7bb4050b 100644 --- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java @@ -46,7 +46,6 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; -import android.view.RemoteAnimationDefinition; import android.view.WindowManager; import android.window.ITaskFragmentOrganizer; import android.window.ITaskFragmentOrganizerController; @@ -58,8 +57,8 @@ import android.window.TaskFragmentTransaction; import android.window.WindowContainerTransaction; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.protolog.ProtoLogGroup; import com.android.internal.protolog.ProtoLog; +import com.android.internal.protolog.ProtoLogGroup; import com.android.window.flags.Flags; import java.lang.annotation.Retention; @@ -146,13 +145,6 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr private final boolean mIsSystemOrganizer; /** - * {@link RemoteAnimationDefinition} for embedded activities transition animation that is - * organized by this organizer. - */ - @Nullable - private RemoteAnimationDefinition mRemoteAnimationDefinition; - - /** * Map from {@link TaskFragmentTransaction#getTransactionToken()} to the * {@link Transition#getSyncId()} that has been deferred. {@link TransitionController} will * wait until the organizer finished handling the {@link TaskFragmentTransaction}. @@ -533,50 +525,6 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } @Override - public void registerRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer, - @NonNull RemoteAnimationDefinition definition) { - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - synchronized (mGlobalLock) { - ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, - "Register remote animations for organizer=%s uid=%d pid=%d", - organizer.asBinder(), uid, pid); - final TaskFragmentOrganizerState organizerState = - mTaskFragmentOrganizerState.get(organizer.asBinder()); - if (organizerState == null) { - throw new IllegalStateException("The organizer hasn't been registered."); - } - if (organizerState.mRemoteAnimationDefinition != null) { - throw new IllegalStateException( - "The organizer has already registered remote animations=" - + organizerState.mRemoteAnimationDefinition); - } - - definition.setCallingPidUid(pid, uid); - organizerState.mRemoteAnimationDefinition = definition; - } - } - - @Override - public void unregisterRemoteAnimations(@NonNull ITaskFragmentOrganizer organizer) { - final int pid = Binder.getCallingPid(); - final long uid = Binder.getCallingUid(); - synchronized (mGlobalLock) { - ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, - "Unregister remote animations for organizer=%s uid=%d pid=%d", - organizer.asBinder(), uid, pid); - final TaskFragmentOrganizerState organizerState = - mTaskFragmentOrganizerState.get(organizer.asBinder()); - if (organizerState == null) { - Slog.e(TAG, "The organizer hasn't been registered."); - return; - } - - organizerState.mRemoteAnimationDefinition = null; - } - } - - @Override public void onTransactionHandled(@NonNull IBinder transactionToken, @NonNull WindowContainerTransaction wct, @WindowManager.TransitionType int transitionType, boolean shouldApplyIndependently) { @@ -617,25 +565,6 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr } } - /** - * Gets the {@link RemoteAnimationDefinition} set on the given organizer if exists. Returns - * {@code null} if it doesn't. - */ - @Nullable - public RemoteAnimationDefinition getRemoteAnimationDefinition( - @NonNull ITaskFragmentOrganizer organizer) { - synchronized (mGlobalLock) { - final TaskFragmentOrganizerState organizerState = - mTaskFragmentOrganizerState.get(organizer.asBinder()); - if (organizerState == null) { - Slog.e(TAG, "TaskFragmentOrganizer has been unregistered or died when trying" - + " to play animation on its organized windows."); - return null; - } - return organizerState.mRemoteAnimationDefinition; - } - } - int getTaskFragmentOrganizerUid(@NonNull ITaskFragmentOrganizer organizer) { final TaskFragmentOrganizerState state = validateAndGetState(organizer); return state.mOrganizerUid; diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java index 0c1fbf3cb3d7..af4394acce67 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -25,15 +25,11 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_CLOSE; import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_CLOSE; import static android.view.WindowManager.TRANSIT_OLD_DREAM_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CHANGE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN; import static android.view.WindowManager.TRANSIT_OLD_TASK_OPEN; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_FRONT; @@ -41,7 +37,6 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; -import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -51,14 +46,11 @@ import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import android.annotation.Nullable; -import android.graphics.Rect; -import android.gui.DropInputMode; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; @@ -841,353 +833,6 @@ public class AppTransitionControllerTest extends WindowTestsBase { } @Test - public void testOverrideTaskFragmentAdapter_overrideWithEmbeddedActivity() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Create a TaskFragment with embedded activity. - final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer); - final ActivityRecord activity = taskFragment.getTopMostActivity(); - prepareActivityForAppTransition(activity); - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // Animation run by the remote handler. - assertTrue(remoteAnimationRunner.isAnimationStarted()); - } - - @Test - public void testOverrideTaskFragmentAdapter_noOverrideWithOnlyTaskFragmentFillingTask() { - final Task task = createTask(mDisplayContent); - final ActivityRecord closingActivity = createActivityRecord(task); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Create a TaskFragment with embedded activity. - final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer); - - // Make sure the TaskFragment is not embedded. - assertFalse(taskFragment.isEmbeddedWithBoundsOverride()); - final ActivityRecord openingActivity = taskFragment.getTopMostActivity(); - prepareActivityForAppTransition(closingActivity); - prepareActivityForAppTransition(openingActivity); - final int uid = 12345; - closingActivity.info.applicationInfo.uid = uid; - openingActivity.info.applicationInfo.uid = uid; - task.effectiveUid = uid; - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(openingActivity, closingActivity, - null /* changingTaskFragment */); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // Animation is not run by the remote handler because the activity is filling the Task. - assertFalse(remoteAnimationRunner.isAnimationStarted()); - } - - @Test - public void testOverrideTaskFragmentAdapter_overrideWithTaskFragmentNotFillingTask() { - final Task task = createTask(mDisplayContent); - final ActivityRecord closingActivity = createActivityRecord(task); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Create a TaskFragment with embedded activity. - final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer); - - // Make sure the TaskFragment is embedded. - taskFragment.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - final Rect embeddedBounds = new Rect(task.getBounds()); - embeddedBounds.right = embeddedBounds.left + embeddedBounds.width() / 2; - taskFragment.setBounds(embeddedBounds); - assertTrue(taskFragment.isEmbeddedWithBoundsOverride()); - final ActivityRecord openingActivity = taskFragment.getTopMostActivity(); - prepareActivityForAppTransition(closingActivity); - prepareActivityForAppTransition(openingActivity); - final int uid = 12345; - closingActivity.info.applicationInfo.uid = uid; - openingActivity.info.applicationInfo.uid = uid; - task.effectiveUid = uid; - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(openingActivity, closingActivity, - null /* changingTaskFragment */); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // Animation run by the remote handler. - assertTrue(remoteAnimationRunner.isAnimationStarted()); - } - - @Test - public void testOverrideTaskFragmentAdapter_overrideWithNonEmbeddedActivity() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Closing non-embedded activity. - final ActivityRecord closingActivity = createActivityRecord(task); - prepareActivityForAppTransition(closingActivity); - // Opening TaskFragment with embedded activity. - final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer); - final ActivityRecord openingActivity = taskFragment.getTopMostActivity(); - prepareActivityForAppTransition(openingActivity); - task.effectiveUid = openingActivity.getUid(); - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // Animation run by the remote handler. - assertTrue(remoteAnimationRunner.isAnimationStarted()); - } - - @Test - public void testOverrideTaskFragmentAdapter_overrideEmbeddedActivityWithDiffUid() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Closing TaskFragment with embedded activity. - final TaskFragment taskFragment1 = createTaskFragmentWithEmbeddedActivity(task, organizer); - final ActivityRecord closingActivity = taskFragment1.getTopMostActivity(); - prepareActivityForAppTransition(closingActivity); - closingActivity.info.applicationInfo.uid = 12345; - // Opening TaskFragment with embedded activity with different UID. - final TaskFragment taskFragment2 = createTaskFragmentWithEmbeddedActivity(task, organizer); - final ActivityRecord openingActivity = taskFragment2.getTopMostActivity(); - prepareActivityForAppTransition(openingActivity); - openingActivity.info.applicationInfo.uid = 54321; - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment1); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // Animation run by the remote handler. - assertTrue(remoteAnimationRunner.isAnimationStarted()); - } - - @Test - public void testOverrideTaskFragmentAdapter_noOverrideWithTwoApps() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Closing activity in Task1. - final ActivityRecord closingActivity = createActivityRecord(mDisplayContent); - prepareActivityForAppTransition(closingActivity); - // Opening TaskFragment with embedded activity in Task2. - final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer); - final ActivityRecord openingActivity = taskFragment.getTopMostActivity(); - prepareActivityForAppTransition(openingActivity); - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // Animation not run by the remote handler. - assertFalse(remoteAnimationRunner.isAnimationStarted()); - } - - @Test - public void testOverrideTaskFragmentAdapter_noOverrideNonEmbeddedActivityWithDiffUid() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Closing TaskFragment with embedded activity. - final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer); - final ActivityRecord closingActivity = taskFragment.getTopMostActivity(); - prepareActivityForAppTransition(closingActivity); - closingActivity.info.applicationInfo.uid = 12345; - task.effectiveUid = closingActivity.getUid(); - // Opening non-embedded activity with different UID. - final ActivityRecord openingActivity = createActivityRecord(task); - prepareActivityForAppTransition(openingActivity); - openingActivity.info.applicationInfo.uid = 54321; - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(openingActivity, closingActivity, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // Animation should not run by the remote handler when there are non-embedded activities of - // different UID. - assertFalse(remoteAnimationRunner.isAnimationStarted()); - } - - @Test - public void testOverrideTaskFragmentAdapter_noOverrideWithWallpaper() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Create a TaskFragment with embedded activity. - final TaskFragment taskFragment = createTaskFragmentWithEmbeddedActivity(task, organizer); - final ActivityRecord activity = taskFragment.getTopMostActivity(); - prepareActivityForAppTransition(activity); - // Set wallpaper as visible. - final WallpaperWindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, - mock(IBinder.class), true, mDisplayContent, true /* ownerCanManageAppTokens */); - spyOn(mDisplayContent.mWallpaperController); - doReturn(true).when(mDisplayContent.mWallpaperController).isWallpaperVisible(); - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // Animation should not run by the remote handler when there is wallpaper in the transition. - assertFalse(remoteAnimationRunner.isAnimationStarted()); - } - - @Test - public void testOverrideTaskFragmentAdapter_inputProtectedForUntrustedAnimation() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Create a TaskFragment with embedded activities, one is trusted embedded, and the other - // one is untrusted embedded. - final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm) - .setParentTask(task) - .createActivityCount(2) - .setOrganizer(organizer) - .build(); - final ActivityRecord activity0 = taskFragment.getChildAt(0).asActivityRecord(); - final ActivityRecord activity1 = taskFragment.getChildAt(1).asActivityRecord(); - // Also create a non-embedded activity in the Task. - final ActivityRecord activity2 = new ActivityBuilder(mAtm).build(); - task.addChild(activity2, POSITION_BOTTOM); - prepareActivityForAppTransition(activity0); - prepareActivityForAppTransition(activity1); - prepareActivityForAppTransition(activity2); - doReturn(false).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity0); - doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity1); - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(activity1, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // The animation will be animated remotely by client and all activities are input disabled - // for untrusted animation. - assertTrue(remoteAnimationRunner.isAnimationStarted()); - verify(activity0).setDropInputForAnimation(true); - verify(activity1).setDropInputForAnimation(true); - verify(activity2).setDropInputForAnimation(true); - verify(activity0).setDropInputMode(DropInputMode.ALL); - verify(activity1).setDropInputMode(DropInputMode.ALL); - verify(activity2).setDropInputMode(DropInputMode.ALL); - - // Reset input after animation is finished. - clearInvocations(activity0); - clearInvocations(activity1); - clearInvocations(activity2); - remoteAnimationRunner.finishAnimation(); - - verify(activity0).setDropInputForAnimation(false); - verify(activity1).setDropInputForAnimation(false); - verify(activity2).setDropInputForAnimation(false); - verify(activity0).setDropInputMode(DropInputMode.OBSCURED); - verify(activity1).setDropInputMode(DropInputMode.NONE); - verify(activity2).setDropInputMode(DropInputMode.NONE); - } - - /** - * Since we don't have any use case to rely on handling input during animation, disable it even - * if it is trusted embedding so that it could cover some edge-cases when a previously trusted - * host starts doing something bad. - */ - @Test - public void testOverrideTaskFragmentAdapter_inputProtectedForTrustedAnimation() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Create a TaskFragment with only trusted embedded activity - final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm) - .setParentTask(task) - .createActivityCount(1) - .setOrganizer(organizer) - .build(); - final ActivityRecord activity = taskFragment.getChildAt(0).asActivityRecord(); - prepareActivityForAppTransition(activity); - doReturn(true).when(taskFragment).isAllowedToEmbedActivityInTrustedMode(activity); - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // The animation will be animated remotely by client and all activities are input disabled - // for untrusted animation. - assertTrue(remoteAnimationRunner.isAnimationStarted()); - verify(activity).setDropInputForAnimation(true); - verify(activity).setDropInputMode(DropInputMode.ALL); - - // Reset input after animation is finished. - clearInvocations(activity); - remoteAnimationRunner.finishAnimation(); - - verify(activity).setDropInputForAnimation(false); - verify(activity).setDropInputMode(DropInputMode.NONE); - } - - /** - * We don't need to drop input for fully trusted embedding (system app, and embedding in the - * same app). This will allow users to do fast tapping. - */ - @Test - public void testOverrideTaskFragmentAdapter_noInputProtectedForFullyTrustedAnimation() { - final Task task = createTask(mDisplayContent); - final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); - final TestRemoteAnimationRunner remoteAnimationRunner = new TestRemoteAnimationRunner(); - setupTaskFragmentRemoteAnimation(organizer, remoteAnimationRunner); - - // Create a TaskFragment with only trusted embedded activity - final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm) - .setParentTask(task) - .createActivityCount(1) - .setOrganizer(organizer) - .build(); - final ActivityRecord activity = taskFragment.getChildAt(0).asActivityRecord(); - prepareActivityForAppTransition(activity); - final int uid = mAtm.mTaskFragmentOrganizerController.getTaskFragmentOrganizerUid( - getITaskFragmentOrganizer(organizer)); - doReturn(true).when(task).isFullyTrustedEmbedding(uid); - spyOn(mDisplayContent.mAppTransition); - - // Prepare and start transition. - prepareAndTriggerAppTransition(activity, null /* closingActivity */, taskFragment); - mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); - - // The animation will be animated remotely by client, but input should not be dropped for - // fully trusted. - assertTrue(remoteAnimationRunner.isAnimationStarted()); - verify(activity, never()).setDropInputForAnimation(true); - verify(activity, never()).setDropInputMode(DropInputMode.ALL); - } - - @Test public void testTransitionGoodToGoForTaskFragments() { final TaskFragmentOrganizer organizer = new TaskFragmentOrganizer(Runnable::run); final Task task = createTask(mDisplayContent); @@ -1253,22 +898,6 @@ public class AppTransitionControllerTest extends WindowTestsBase { verify(mDisplayContent.mAppTransition).goodToGo(anyInt(), any()); } - /** Registers remote animation for the organizer. */ - private void setupTaskFragmentRemoteAnimation(TaskFragmentOrganizer organizer, - TestRemoteAnimationRunner remoteAnimationRunner) { - final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( - remoteAnimationRunner, 10, 1); - final ITaskFragmentOrganizer iOrganizer = getITaskFragmentOrganizer(organizer); - final RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); - definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CHANGE, adapter); - definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_OPEN, adapter); - definition.addRemoteAnimation(TRANSIT_OLD_TASK_FRAGMENT_CLOSE, adapter); - definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_OPEN, adapter); - definition.addRemoteAnimation(TRANSIT_OLD_ACTIVITY_CLOSE, adapter); - registerTaskFragmentOrganizer(iOrganizer); - mAtm.mTaskFragmentOrganizerController.registerRemoteAnimations(iOrganizer, definition); - } - private static ITaskFragmentOrganizer getITaskFragmentOrganizer( TaskFragmentOrganizer organizer) { return ITaskFragmentOrganizer.Stub.asInterface(organizer.getOrganizerToken().asBinder()); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index a71b81e025d2..d013053a063d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -90,7 +90,6 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.view.RemoteAnimationDefinition; import android.view.SurfaceControl; import android.window.IRemoteTransition; import android.window.ITaskFragmentOrganizer; @@ -140,7 +139,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { private IBinder mFragmentToken; private WindowContainerTransaction mTransaction; private WindowContainerToken mFragmentWindowToken; - private RemoteAnimationDefinition mDefinition; private IBinder mErrorToken; private Rect mTaskFragBounds; @@ -169,7 +167,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mTransaction = new WindowContainerTransaction(); mTransaction.setTaskFragmentOrganizer(mIOrganizer); mFragmentWindowToken = mTaskFragment.mRemoteToken.toWindowContainerToken(); - mDefinition = new RemoteAnimationDefinition(); mErrorToken = new Binder(); final Rect displayBounds = mDisplayContent.getBounds(); mTaskFragBounds = new Rect(displayBounds.left, displayBounds.top, displayBounds.centerX(), @@ -579,17 +576,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { } @Test - public void testRegisterRemoteAnimations() { - mController.registerRemoteAnimations(mIOrganizer, mDefinition); - - assertEquals(mDefinition, mController.getRemoteAnimationDefinition(mIOrganizer)); - - mController.unregisterRemoteAnimations(mIOrganizer); - - assertNull(mController.getRemoteAnimationDefinition(mIOrganizer)); - } - - @Test public void testApplyTransaction_disallowRemoteTransitionForNonSystemOrganizer() { mTransaction.setRelativeBounds(mFragmentWindowToken, new Rect(0, 0, 100, 100)); mTaskFragment.setTaskFragmentOrganizer(mOrganizerToken, 10 /* uid */, |