diff options
| author | 2016-01-28 17:57:52 +0000 | |
|---|---|---|
| committer | 2016-01-28 17:57:52 +0000 | |
| commit | 2a25dd5c91aab77393b6cf588b7e8f64d1a346d6 (patch) | |
| tree | cd2ec5e938b63ad90cbc0718dab6e8ad66dfb333 | |
| parent | 0a4b4cdf1c2abfe301742f639015a272ee42f98d (diff) | |
| parent | 84fa3351a21b37d02fafd634a8de65cf6cd04c4d (diff) | |
Merge "Animate pinned stack resizing."
12 files changed, 285 insertions, 36 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 72e8c3b61027..d45bc5dc8789 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -47,7 +47,6 @@ import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.Rect; -import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -79,7 +78,6 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.List; public class Am extends BaseCommand { @@ -159,6 +157,7 @@ public class Am extends BaseCommand { " am stack start <DISPLAY_ID> <INTENT>\n" + " am stack movetask <TASK_ID> <STACK_ID> [true|false]\n" + " am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" + + " am stack resize-animated <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" + " am stack resize-docked-stack <LEFT,TOP,RIGHT,BOTTOM> [<TASK_LEFT,TASK_TOP,TASK_RIGHT,TASK_BOTTOM>]\n" + " am stack size-docked-stack-test: <STEP_SIZE> <l|t|r|b> [DELAY_MS]\n" + " am stack move-top-activity-to-pinned-stack: <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" + @@ -1688,6 +1687,9 @@ public class Am extends BaseCommand { case "resize": runStackResize(); break; + case "resize-animated": + runStackResizeAnimated(); + break; case "resize-docked-stack": runStackResizeDocked(); break; @@ -1756,7 +1758,18 @@ public class Am extends BaseCommand { System.err.println("Error: invalid input bounds"); return; } - resizeStack(stackId, bounds, 0); + resizeStack(stackId, bounds, 0, false); + } + + private void runStackResizeAnimated() throws Exception { + String stackIdStr = nextArgRequired(); + int stackId = Integer.valueOf(stackIdStr); + final Rect bounds = getBounds(); + if (bounds == null) { + System.err.println("Error: invalid input bounds"); + return; + } + resizeStack(stackId, bounds, 0, true); } private void runStackResizeDocked() throws Exception { @@ -1773,14 +1786,15 @@ public class Am extends BaseCommand { } } - private void resizeStack(int stackId, Rect bounds, int delayMs) throws Exception { + private void resizeStack(int stackId, Rect bounds, int delayMs, boolean animate) + throws Exception { if (bounds == null) { showError("Error: invalid input bounds"); return; } try { - mAm.resizeStack(stackId, bounds, false); + mAm.resizeStack(stackId, bounds, false, false, animate); Thread.sleep(delayMs); } catch (RemoteException e) { showError("Error: resizing stack " + e); @@ -1894,7 +1908,7 @@ public class Am extends BaseCommand { maxChange = Math.min(stepSize, currentPoint - minPoint); currentPoint -= maxChange; setBoundsSide(bounds, side, currentPoint); - resizeStack(DOCKED_STACK_ID, bounds, delayMs); + resizeStack(DOCKED_STACK_ID, bounds, delayMs, false); } System.out.println("Growing docked stack side=" + side); @@ -1902,7 +1916,7 @@ public class Am extends BaseCommand { maxChange = Math.min(stepSize, maxPoint - currentPoint); currentPoint += maxChange; setBoundsSide(bounds, side, currentPoint); - resizeStack(DOCKED_STACK_ID, bounds, delayMs); + resizeStack(DOCKED_STACK_ID, bounds, delayMs, false); } System.out.println("Back to Original size side=" + side); @@ -1910,7 +1924,7 @@ public class Am extends BaseCommand { maxChange = Math.min(stepSize, currentPoint - startPoint); currentPoint -= maxChange; setBoundsSide(bounds, side, currentPoint); - resizeStack(DOCKED_STACK_ID, bounds, delayMs); + resizeStack(DOCKED_STACK_ID, bounds, delayMs, false); } } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 420bf31a189d..90feab4327b7 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -564,8 +564,7 @@ public class ActivityManager { * there isn't a display gap. */ public static boolean preserveWindowOnTaskMove(int stackId) { - return stackId == FULLSCREEN_WORKSPACE_STACK_ID - || stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID; + return stackId == FULLSCREEN_WORKSPACE_STACK_ID || stackId == DOCKED_STACK_ID; } /** @@ -616,6 +615,14 @@ public class ActivityManager { public static boolean keepVisibleDeadAppWindowOnScreen(int stackId) { return stackId != PINNED_STACK_ID; } + + /** + * Returns true if the backdrop on the client side should match the frame of the window. + * Returns false, if the backdrop should be fullscreen. + */ + public static boolean useWindowFrameForBackdrop(int stackId) { + return stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == PINNED_STACK_ID; + } } /** diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 42ff8e83862d..cd5797ecb286 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -816,7 +816,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM r = Rect.CREATOR.createFromParcel(data); } final boolean allowResizeInDockedMode = data.readInt() == 1; - resizeStack(stackId, r, allowResizeInDockedMode); + final boolean preserveWindows = data.readInt() == 1; + final boolean animate = data.readInt() == 1; + resizeStack(stackId, r, allowResizeInDockedMode, preserveWindows, animate); reply.writeNoException(); return true; } @@ -3815,9 +3817,8 @@ class ActivityManagerProxy implements IActivityManager return res; } @Override - public void resizeStack(int stackId, Rect r, boolean allowResizeInDockedMode) - throws RemoteException - { + public void resizeStack(int stackId, Rect r, boolean allowResizeInDockedMode, + boolean preserveWindows, boolean animate) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -3829,6 +3830,8 @@ class ActivityManagerProxy implements IActivityManager data.writeInt(0); } data.writeInt(allowResizeInDockedMode ? 1 : 0); + data.writeInt(preserveWindows ? 1 : 0); + data.writeInt(animate ? 1 : 0); mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 22de2ff7bc6e..5b3ffe05451a 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -146,8 +146,8 @@ public interface IActivityManager extends IInterface { public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds) throws RemoteException; public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) throws RemoteException; - public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) - throws RemoteException; + public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode, + boolean preserveWindows, boolean animate) throws RemoteException; /** * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change. diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java index 67bb58ae8fc9..24ab5063d94e 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java @@ -97,7 +97,8 @@ public class WindowManagerProxy { @Override public void run() { try { - ActivityManagerNative.getDefault().resizeStack(DOCKED_STACK_ID, null, true); + ActivityManagerNative.getDefault().resizeStack(DOCKED_STACK_ID, null, true, false, + false); } catch (RemoteException e) { Log.w(TAG, "Failed to resize stack: " + e); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 2c55ee26cf8f..76fbebfd14b5 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9411,14 +9411,24 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) { + public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode, + boolean preserveWindows, boolean animate) { enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); long ident = Binder.clearCallingIdentity(); try { synchronized (this) { - mStackSupervisor.resizeStackLocked( - stackId, bounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */, - !PRESERVE_WINDOWS, allowResizeInDockedMode); + if (animate) { + if (stackId == PINNED_STACK_ID) { + mWindowManager.animateResizePinnedStack(bounds); + } else { + throw new IllegalArgumentException("Stack: " + stackId + + " doesn't support animated resize."); + } + } else { + mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */, + null /* tempTaskInsetBounds */, preserveWindows, + allowResizeInDockedMode); + } } } finally { Binder.restoreCallingIdentity(ident); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 8db2f8ff50f3..11dd8a38cdbf 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -98,6 +98,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Set; import static android.Manifest.permission.START_ANY_ACTIVITY; @@ -2019,7 +2020,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // If this is a forced resize, let it go through even if the bounds is not changing, // as we might need a relayout due to surface size change (to/from fullscreen). final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0; - if (task.mBounds != null && task.mBounds.equals(bounds) && !forced) { + if (Objects.equals(task.mBounds, bounds) && !forced) { // Nothing to do here... return true; } @@ -2257,10 +2258,7 @@ public final class ActivityStackSupervisor implements DisplayListener { // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old // window), we need to clear the replace window settings. Otherwise, we schedule a // timeout to remove the old window if the replacing window is not coming in time. - // In case of the pinned stack we don't resize the task during the move, but we will - // resize the stack soon after so we want to retain the replacing window. - mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, - !kept || stackId == PINNED_STACK_ID); + mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept); } // The task might have already been running and its visibility needs to be synchronized with @@ -2294,7 +2292,8 @@ public final class ActivityStackSupervisor implements DisplayListener { return false; } - moveActivityToStackLocked(r, PINNED_STACK_ID, "moveTopActivityToPinnedStack", bounds); + moveActivityToStackLocked(r, PINNED_STACK_ID, "moveTopActivityToPinnedStack", null); + mWindowManager.animateResizePinnedStack(bounds); return true; } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 552af03173a7..43a17c98fcc4 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -134,7 +134,7 @@ public class AppTransition implements Dump { /** Fraction of animation at which the recents thumbnail becomes completely transparent */ private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.5f; - private static final int DEFAULT_APP_TRANSITION_DURATION = 336; + static final int DEFAULT_APP_TRANSITION_DURATION = 336; private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336; private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 336; private static final long APP_TRANSITION_TIMEOUT_MS = 5000; diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java new file mode 100644 index 000000000000..5f974785b667 --- /dev/null +++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2016 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 com.android.server.wm; + +import static com.android.server.wm.AppTransition.DEFAULT_APP_TRANSITION_DURATION; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.graphics.Rect; +import android.util.ArrayMap; +import android.util.Slog; +import android.view.animation.LinearInterpolator; + +/** + * Enables animating bounds of objects. + * + * In multi-window world bounds of both stack and tasks can change. When we need these bounds to + * change smoothly and not require the app to relaunch (e.g. because it handles resizes and + * relaunching it would cause poorer experience), these class provides a way to directly animate + * the bounds of the resized object. + * + * The object that is resized needs to implement {@link AnimateBoundsUser} interface. + */ +public class BoundsAnimationController { + private static final String TAG = TAG_WITH_CLASS_NAME ? "BoundsAnimationController" : TAG_WM; + + // Only acccessed on UI thread. + private ArrayMap<AnimateBoundsUser, BoundsAnimator> mRunningAnimations = new ArrayMap<>(); + + private final class BoundsAnimator extends ValueAnimator + implements ValueAnimator.AnimatorUpdateListener, ValueAnimator.AnimatorListener { + private final AnimateBoundsUser mTarget; + private final Rect mFrom; + private final Rect mTo; + private final Rect mTmpRect; + + BoundsAnimator(AnimateBoundsUser target, Rect from, Rect to) { + super(); + mTarget = target; + mFrom = from; + mTo = to; + mTmpRect = new Rect(); + addUpdateListener(this); + addListener(this); + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + final float value = (Float) animation.getAnimatedValue(); + final float remains = 1 - value; + mTmpRect.left = (int) (mFrom.left * remains + mTo.left * value); + mTmpRect.top = (int) (mFrom.top * remains + mTo.top * value); + mTmpRect.right = (int) (mFrom.right * remains + mTo.right * value); + mTmpRect.bottom = (int) (mFrom.bottom * remains + mTo.bottom * value); + if (DEBUG_ANIM) Slog.d(TAG, "animateUpdate: mTarget=" + mTarget + ", mBounds=" + + mTmpRect + ", from=" + mFrom + ", mTo=" + mTo + ", value=" + value + + ", remains=" + remains); + if (!mTarget.setSize(mTmpRect)) { + // Whoops, the target doesn't feel like animating anymore. Let's immediately finish + // any further animation. + animation.cancel(); + } + } + + + @Override + public void onAnimationStart(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + finishAnimation(); + } + + @Override + public void onAnimationCancel(Animator animation) { + finishAnimation(); + } + + private void finishAnimation() { + mTarget.finishBoundsAnimation(); + removeListener(this); + removeUpdateListener(this); + mRunningAnimations.remove(mTarget); + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + } + + public interface AnimateBoundsUser { + /** + * Asks the target to directly (without any intermediate steps, like scheduling animation) + * resize its bounds. + * + * @return Whether the target still wants to be animated and successfully finished the + * operation. If it returns false, the animation will immediately be cancelled. The target + * should return false when something abnormal happened, e.g. it was completely removed + * from the hierarchy and is not valid anymore. + */ + boolean setSize(Rect bounds); + + /** + * Callback for the target to inform it that the animation is finished, so it can do some + * necessary cleanup. + */ + void finishBoundsAnimation(); + } + + void animateBounds(AnimateBoundsUser target, Rect from, Rect to) { + final BoundsAnimator existing = mRunningAnimations.get(target); + if (existing != null) { + existing.cancel(); + } + BoundsAnimator animator = new BoundsAnimator(target, from, to); + mRunningAnimations.put(target, animator); + animator.setFloatValues(0f, 1f); + animator.setDuration(DEFAULT_APP_TRANSITION_DURATION); + animator.setInterpolator(new LinearInterpolator()); + animator.start(); + } +} diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index f02e49e21977..e0880ad3ae92 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -20,6 +20,7 @@ import android.app.ActivityManager.StackId; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Debug; +import android.os.RemoteException; import android.util.EventLog; import android.util.Slog; import android.util.SparseArray; @@ -47,7 +48,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT import static com.android.server.wm.WindowManagerService.H.RESIZE_STACK; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -public class TaskStack implements DimLayer.DimLayerUser { +public class TaskStack implements DimLayer.DimLayerUser, + BoundsAnimationController.AnimateBoundsUser { // If the stack should be resized to fullscreen. private static final boolean FULLSCREEN = true; @@ -804,4 +806,32 @@ public class TaskStack implements DimLayer.DimLayerUser { } return false; } + + @Override // AnimatesBounds + public boolean setSize(Rect bounds) { + synchronized (mService.mWindowMap) { + if (mDisplayContent == null) { + return false; + } + } + try { + mService.mActivityManager.resizeStack(mStackId, bounds, false, true, false); + } catch (RemoteException e) { + } + return true; + } + + @Override // AnimatesBounds + public void finishBoundsAnimation() { + synchronized (mService.mWindowMap) { + if (mTasks.isEmpty()) { + return; + } + final Task task = mTasks.get(mTasks.size() - 1); + if (task != null) { + task.setDragResizing(false); + mService.requestTraversal(); + } + } + } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 93a10156414a..2b88af414b4a 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -157,6 +157,7 @@ import java.util.List; import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; +import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.StatusBarManager.DISABLE_MASK; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -643,6 +644,9 @@ public class WindowManagerService extends IWindowManager.Stub final WindowAnimator mAnimator; + private final BoundsAnimationController mBoundsAnimationController = + new BoundsAnimationController(); + SparseArray<Task> mTaskIdToTask = new SparseArray<>(); /** All of the TaskStacks in the window manager, unordered. For an ordered list call @@ -2848,11 +2852,12 @@ public class WindowManagerService extends IWindowManager.Stub if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) { win.prepareWindowToDisplayDuringRelayout(outConfig); } - if ((attrChanges& LayoutParams.FORMAT_CHANGED) != 0) { - // If the format can be changed in place yaay! - // If not, fall back to a surface re-build + if ((attrChanges & LayoutParams.FORMAT_CHANGED) != 0) { + // If the format can't be changed in place, preserve the old surface until the app draws + // on the new one. This prevents blinking when we change elevation of freeform and + // pinned windows. if (!winAnimator.tryChangeFormatInPlaceLocked()) { - winAnimator.destroySurfaceLocked(); + winAnimator.preserveSurfaceLocked(); result |= RELAYOUT_RES_SURFACE_CHANGED | WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME; } @@ -8085,7 +8090,8 @@ public class WindowManagerService extends IWindowManager.Stub break; case RESIZE_STACK: { try { - mActivityManager.resizeStack(msg.arg1, (Rect) msg.obj, msg.arg2 == 1); + mActivityManager.resizeStack(msg.arg1, (Rect) msg.obj, msg.arg2 == 1, false, + false); } catch (RemoteException e) { // This will not happen since we are in the same process. } @@ -10273,6 +10279,31 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void animateResizePinnedStack(final Rect bounds) { + synchronized (mWindowMap) { + final TaskStack stack = mStackIdToStack.get(PINNED_STACK_ID); + if (stack == null) { + Slog.w(TAG, "animateResizePinnedStack: stackId " + PINNED_STACK_ID + " not found."); + return; + } + final ArrayList<Task> tasks = stack.getTasks(); + if (tasks.isEmpty()) { + Slog.w(TAG, "animateResizePinnedStack: pinned stack doesn't have any tasks."); + return; + } + final Task task = tasks.get(tasks.size() - 1); + task.setDragResizing(true); + final Rect originalBounds = new Rect(); + stack.getBounds(originalBounds); + UiThread.getHandler().post(new Runnable() { + @Override + public void run() { + mBoundsAnimationController.animateBounds(stack, originalBounds, bounds); + } + }); + } + } + public void setTaskResizeable(int taskId, boolean resizeable) { synchronized (mWindowMap) { Task task = mTaskIdToTask.get(taskId); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index c541b3f6f56b..1214948911e1 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -57,6 +57,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import static android.app.ActivityManager.StackId; +import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT; import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME; @@ -2051,10 +2052,21 @@ final class WindowState implements WindowManagerPolicy.WindowState { // until the window to small size, otherwise the multithread renderer will shift last // one or more frame to wrong offset. So here we send fullscreen backdrop if either // isDragResizing() or isDragResizeChanged() is true. + boolean resizing = isDragResizing() || isDragResizeChanged(); + if (StackId.useWindowFrameForBackdrop(getStackId()) || !resizing) { + return frame; + } DisplayInfo displayInfo = getDisplayInfo(); mTmpRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); - boolean resizing = isDragResizing() || isDragResizeChanged(); - return (inFreeformWorkspace() || !resizing) ? frame : mTmpRect; + return mTmpRect; + } + + private int getStackId() { + final TaskStack stack = getStack(); + if (stack == null) { + return INVALID_STACK_ID; + } + return stack.mStackId; } private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, |