Merge changes Ib5ad3250,Iff58afdb into sc-v2-dev am: 83d5a591f2 am: 055d1d5a4e
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15838390 Change-Id: I437593233fa28a2915ebb4323f2e8172542777ff
This commit is contained in:
@@ -208,6 +208,15 @@ public class RemoteAnimationTarget implements Parcelable {
|
||||
*/
|
||||
public final @WindowManager.LayoutParams.WindowType int windowType;
|
||||
|
||||
/**
|
||||
* {@code true} if its parent is also a {@link RemoteAnimationTarget} in the same transition.
|
||||
*
|
||||
* For example, when a TaskFragment is resizing while one of its children is open/close, both
|
||||
* windows will be animation targets. This value will be {@code true} for the child, so that
|
||||
* the handler can choose to handle it differently.
|
||||
*/
|
||||
public boolean hasAnimatingParent;
|
||||
|
||||
public RemoteAnimationTarget(int taskId, int mode, SurfaceControl leash, boolean isTranslucent,
|
||||
Rect clipRect, Rect contentInsets, int prefixOrderIndex, Point position,
|
||||
Rect localBounds, Rect screenSpaceBounds,
|
||||
@@ -265,6 +274,7 @@ public class RemoteAnimationTarget implements Parcelable {
|
||||
taskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
|
||||
allowEnterPip = in.readBoolean();
|
||||
windowType = in.readInt();
|
||||
hasAnimatingParent = in.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -292,6 +302,7 @@ public class RemoteAnimationTarget implements Parcelable {
|
||||
dest.writeTypedObject(taskInfo, 0 /* flags */);
|
||||
dest.writeBoolean(allowEnterPip);
|
||||
dest.writeInt(windowType);
|
||||
dest.writeBoolean(hasAnimatingParent);
|
||||
}
|
||||
|
||||
public void dump(PrintWriter pw, String prefix) {
|
||||
@@ -311,6 +322,7 @@ public class RemoteAnimationTarget implements Parcelable {
|
||||
pw.print(prefix); pw.print("taskInfo="); pw.println(taskInfo);
|
||||
pw.print(prefix); pw.print("allowEnterPip="); pw.println(allowEnterPip);
|
||||
pw.print(prefix); pw.print("windowType="); pw.print(windowType);
|
||||
pw.print(prefix); pw.print("hasAnimatingParent="); pw.print(hasAnimatingParent);
|
||||
}
|
||||
|
||||
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
|
||||
@@ -223,7 +223,6 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
|
||||
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
|
||||
import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
|
||||
import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM;
|
||||
|
||||
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
|
||||
import static org.xmlpull.v1.XmlPullParser.END_TAG;
|
||||
@@ -8041,13 +8040,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
@VisibleForTesting
|
||||
@Override
|
||||
Rect getAnimationBounds(int appRootTaskClipMode) {
|
||||
if (appRootTaskClipMode == ROOT_TASK_CLIP_BEFORE_ANIM && getRootTask() != null) {
|
||||
// Using the root task bounds here effectively applies the clipping before animation.
|
||||
return getRootTask().getBounds();
|
||||
}
|
||||
// Use task-bounds if available so that activity-level letterbox (maxAspectRatio) is
|
||||
// Use TaskFragment-bounds if available so that activity-level letterbox (maxAspectRatio) is
|
||||
// included in the animation.
|
||||
return task != null ? task.getBounds() : getBounds();
|
||||
final TaskFragment taskFragment = getTaskFragment();
|
||||
return taskFragment != null ? taskFragment.getBounds() : getBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -9269,14 +9265,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
task.getBounds(), Type.systemBars(), false /* ignoreVisibility */).toRect();
|
||||
InsetUtils.addInsets(insets, getLetterboxInsets());
|
||||
|
||||
return new RemoteAnimationTarget(task.mTaskId, record.getMode(),
|
||||
record.mAdapter.mCapturedLeash, !fillsParent(),
|
||||
final RemoteAnimationTarget target = new RemoteAnimationTarget(task.mTaskId,
|
||||
record.getMode(), record.mAdapter.mCapturedLeash, !fillsParent(),
|
||||
new Rect(), insets,
|
||||
getPrefixOrderIndex(), record.mAdapter.mPosition, record.mAdapter.mLocalBounds,
|
||||
record.mAdapter.mRootTaskBounds, task.getWindowConfiguration(),
|
||||
false /*isNotInRecents*/,
|
||||
record.mThumbnailAdapter != null ? record.mThumbnailAdapter.mCapturedLeash : null,
|
||||
record.mStartBounds, task.getTaskInfo(), checkEnterPictureInPictureAppOpsState());
|
||||
target.hasAnimatingParent = record.hasAnimatingParent();
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -436,6 +436,19 @@ class RemoteAnimationController implements DeathRecipient {
|
||||
int getMode() {
|
||||
return mMode;
|
||||
}
|
||||
|
||||
/** Whether its parent is also an animation target in the same transition. */
|
||||
boolean hasAnimatingParent() {
|
||||
// mOpeningApps and mClosingApps are only activities, so only need to check
|
||||
// mChangingContainers.
|
||||
for (int i = mDisplayContent.mChangingContainers.size() - 1; i >= 0; i--) {
|
||||
if (mWindowContainer.isDescendantOf(
|
||||
mDisplayContent.mChangingContainers.valueAt(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class RemoteAnimationAdapterWrapper implements AnimationAdapter {
|
||||
|
||||
@@ -130,7 +130,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
import static com.android.server.wm.WindowManagerService.dipToPixel;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM;
|
||||
|
||||
import static java.lang.Integer.MAX_VALUE;
|
||||
|
||||
@@ -2984,16 +2983,6 @@ class Task extends TaskFragment {
|
||||
super.resetSurfacePositionForAnimationLeash(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
Rect getAnimationBounds(int appRootTaskClipMode) {
|
||||
// TODO(b/131661052): we should remove appRootTaskClipMode with hierarchical animations.
|
||||
if (appRootTaskClipMode == ROOT_TASK_CLIP_BEFORE_ANIM && getRootTask() != null) {
|
||||
// Using the root task bounds here effectively applies the clipping before animation.
|
||||
return getRootTask().getBounds();
|
||||
}
|
||||
return super.getAnimationBounds(appRootTaskClipMode);
|
||||
}
|
||||
|
||||
boolean shouldAnimate() {
|
||||
/**
|
||||
* Animations are handled by the TaskOrganizer implementation.
|
||||
|
||||
@@ -79,17 +79,11 @@ class WindowStateAnimator {
|
||||
*/
|
||||
static final int ROOT_TASK_CLIP_AFTER_ANIM = 0;
|
||||
|
||||
/**
|
||||
* Mode how the window gets clipped by the root task bounds: The clipping should be applied
|
||||
* before applying the animation transformation, i.e. the root task bounds move with the window.
|
||||
*/
|
||||
static final int ROOT_TASK_CLIP_BEFORE_ANIM = 1;
|
||||
|
||||
/**
|
||||
* Mode how window gets clipped by the root task bounds during an animation: Don't clip the
|
||||
* window by the root task bounds.
|
||||
*/
|
||||
static final int ROOT_TASK_CLIP_NONE = 2;
|
||||
static final int ROOT_TASK_CLIP_NONE = 1;
|
||||
|
||||
// Unchanging local convenience fields.
|
||||
final WindowManagerService mService;
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.server.wm;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
|
||||
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
|
||||
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
|
||||
import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
|
||||
@@ -83,7 +82,6 @@ import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_VISIBL
|
||||
import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
|
||||
import static com.android.server.wm.WindowContainer.POSITION_TOP;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_AFTER_ANIM;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
@@ -2779,10 +2777,36 @@ public class ActivityRecordTests extends WindowTestsBase {
|
||||
|
||||
assertEquals(taskBounds, activity.getAnimationBounds(ROOT_TASK_CLIP_AFTER_ANIM));
|
||||
assertEquals(new Point(0, 0), animationPosition);
|
||||
}
|
||||
|
||||
// ROOT_TASK_CLIP_BEFORE_ANIM should use stack bounds since it won't be clipped later.
|
||||
task.getWindowConfiguration().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
|
||||
assertEquals(rootTask.getBounds(), activity.getAnimationBounds(ROOT_TASK_CLIP_BEFORE_ANIM));
|
||||
@Test
|
||||
public void testTransitionAnimationBounds_returnTaskFragment() {
|
||||
removeGlobalMinSizeRestriction();
|
||||
final Task task = new TaskBuilder(mSupervisor).setCreateParentTask(true).build();
|
||||
final Task rootTask = task.getRootTask();
|
||||
final TaskFragment taskFragment = createTaskFragmentWithParentTask(task,
|
||||
false /* createEmbeddedTask */);
|
||||
final ActivityRecord activity = taskFragment.getTopNonFinishingActivity();
|
||||
final Rect stackBounds = new Rect(0, 0, 1000, 600);
|
||||
final Rect taskBounds = new Rect(100, 400, 600, 800);
|
||||
final Rect taskFragmentBounds = new Rect(100, 400, 300, 800);
|
||||
final Rect activityBounds = new Rect(100, 400, 300, 600);
|
||||
// Set the bounds and windowing mode to window configuration directly, otherwise the
|
||||
// testing setups may be discarded by configuration resolving.
|
||||
rootTask.getWindowConfiguration().setBounds(stackBounds);
|
||||
task.getWindowConfiguration().setBounds(taskBounds);
|
||||
taskFragment.getWindowConfiguration().setBounds(taskFragmentBounds);
|
||||
activity.getWindowConfiguration().setBounds(activityBounds);
|
||||
|
||||
// Check that anim bounds for freeform window match task fragment bounds
|
||||
task.getWindowConfiguration().setWindowingMode(WINDOWING_MODE_FREEFORM);
|
||||
assertEquals(taskFragment.getBounds(), activity.getAnimationBounds(ROOT_TASK_CLIP_NONE));
|
||||
|
||||
// ROOT_TASK_CLIP_AFTER_ANIM should use task fragment bounds since they will be clipped by
|
||||
// bounds animation layer.
|
||||
task.getWindowConfiguration().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
|
||||
assertEquals(taskFragment.getBounds(),
|
||||
activity.getAnimationBounds(ROOT_TASK_CLIP_AFTER_ANIM));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.server.wm;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_AFTER_ANIM;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_BEFORE_ANIM;
|
||||
import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -88,43 +87,6 @@ public class WindowAnimationSpecTest {
|
||||
argThat(rect -> rect.equals(mStackBounds)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_clipBeforeNoAnimationBounds() {
|
||||
// Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 0, 0)
|
||||
WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(mAnimation, null,
|
||||
mStackBounds, false /* canSkipFirstFrame */, ROOT_TASK_CLIP_BEFORE_ANIM,
|
||||
true /* isAppAnimation */, 0 /* windowCornerRadius */);
|
||||
windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
|
||||
verify(mTransaction).setWindowCrop(eq(mSurfaceControl),
|
||||
argThat(rect -> rect.equals(mStackBounds)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_clipBeforeNoStackBounds() {
|
||||
// Stack bounds is (0, 0, 0, 0) animation clip is (0, 0, 20, 20)
|
||||
Rect windowCrop = new Rect(0, 0, 20, 20);
|
||||
Animation a = createClipRectAnimation(windowCrop, windowCrop);
|
||||
a.initialize(0, 0, 0, 0);
|
||||
WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null,
|
||||
null, false /* canSkipFirstFrame */, ROOT_TASK_CLIP_BEFORE_ANIM,
|
||||
true /* isAppAnimation */, 0 /* windowCornerRadius */);
|
||||
windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
|
||||
verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_setCornerRadius() {
|
||||
final float windowCornerRadius = 30f;
|
||||
WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(mAnimation, null,
|
||||
mStackBounds, false /* canSkipFirstFrame */, ROOT_TASK_CLIP_BEFORE_ANIM,
|
||||
true /* isAppAnimation */, windowCornerRadius);
|
||||
windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
|
||||
verify(mTransaction, never()).setCornerRadius(eq(mSurfaceControl), eq(windowCornerRadius));
|
||||
when(mAnimation.hasRoundedCorners()).thenReturn(true);
|
||||
windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
|
||||
verify(mTransaction).setCornerRadius(eq(mSurfaceControl), eq(windowCornerRadius));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_setCornerRadius_noClip() {
|
||||
final float windowCornerRadius = 30f;
|
||||
@@ -136,32 +98,6 @@ public class WindowAnimationSpecTest {
|
||||
verify(mTransaction, never()).setCornerRadius(any(), anyFloat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_clipBeforeSmallerAnimationClip() {
|
||||
// Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 5, 5)
|
||||
Rect windowCrop = new Rect(0, 0, 5, 5);
|
||||
Animation a = createClipRectAnimation(windowCrop, windowCrop);
|
||||
WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null,
|
||||
mStackBounds, false /* canSkipFirstFrame */, ROOT_TASK_CLIP_BEFORE_ANIM,
|
||||
true /* isAppAnimation */, 0 /* windowCornerRadius */);
|
||||
windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
|
||||
verify(mTransaction).setWindowCrop(eq(mSurfaceControl),
|
||||
argThat(rect -> rect.equals(windowCrop)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApply_clipBeforeSmallerStackClip() {
|
||||
// Stack bounds is (0, 0, 10, 10) animation clip is (0, 0, 20, 20)
|
||||
Rect windowCrop = new Rect(0, 0, 20, 20);
|
||||
Animation a = createClipRectAnimation(windowCrop, windowCrop);
|
||||
WindowAnimationSpec windowAnimationSpec = new WindowAnimationSpec(a, null,
|
||||
mStackBounds, false /* canSkipFirstFrame */, ROOT_TASK_CLIP_BEFORE_ANIM,
|
||||
true /* isAppAnimation */, 0 /* windowCornerRadius */);
|
||||
windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
|
||||
verify(mTransaction).setWindowCrop(eq(mSurfaceControl),
|
||||
argThat(rect -> rect.equals(mStackBounds)));
|
||||
}
|
||||
|
||||
private Animation createClipRectAnimation(Rect fromClip, Rect toClip) {
|
||||
Animation a = new ClipRectAnimation(fromClip, toClip);
|
||||
a.initialize(0, 0, 0, 0);
|
||||
|
||||
Reference in New Issue
Block a user