Loading services/core/java/com/android/server/am/ActivityRecord.java +15 −16 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID; 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.FULLSCREEN_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.HOME_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.AppOpsManager.MODE_ALLOWED; Loading @@ -47,7 +46,6 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.res.Configuration.UI_MODE_TYPE_MASK; import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET; import static android.os.Build.VERSION_CODES.HONEYCOMB; import static android.os.Build.VERSION_CODES.O; Loading Loading @@ -85,7 +83,6 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.IBinder; Loading Loading @@ -290,8 +287,8 @@ final class ActivityRecord implements AppWindowContainerListener { /** * Temp configs used in {@link #ensureActivityConfigurationLocked(int, boolean)} */ private final Configuration mTmpGlobalConfig = new Configuration(); private final Configuration mTmpTaskConfig = new Configuration(); private final Configuration mTmpConfig1 = new Configuration(); private final Configuration mTmpConfig2 = new Configuration(); private static String startingWindowStateToString(int state) { switch (state) { Loading Loading @@ -1975,13 +1972,13 @@ final class ActivityRecord implements AppWindowContainerListener { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Ensuring correct configuration: " + this); // Short circuit: if the two configurations are equal (the common case), then there is // nothing to do. final Configuration newGlobalConfig = service.getGlobalConfiguration(); final Configuration newTaskMergedOverrideConfig = task.getMergedOverrideConfiguration(); if (mLastReportedConfiguration.equals(newGlobalConfig) && mLastReportedOverrideConfiguration.equals(newTaskMergedOverrideConfig) && !forceNewConfig) { // Short circuit: if the two full configurations are equal (the common case), then there is // nothing to do. We test the full configuration instead of the global and merged override // configurations because there are cases (like moving a task to the pinned stack) where // the combine configurations are equal, but would otherwise differ in the override config mTmpConfig1.setTo(mLastReportedConfiguration); mTmpConfig1.updateFrom(mLastReportedOverrideConfiguration); if (task.getConfiguration().equals(mTmpConfig1) && !forceNewConfig) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Configuration unchanged in " + this); return true; Loading @@ -1997,14 +1994,16 @@ final class ActivityRecord implements AppWindowContainerListener { // Okay we now are going to make this activity have the new config. // But then we need to figure out how it needs to deal with that. mTmpGlobalConfig.setTo(mLastReportedConfiguration); mTmpTaskConfig.setTo(mLastReportedOverrideConfiguration); final Configuration newGlobalConfig = service.getGlobalConfiguration(); final Configuration newTaskMergedOverrideConfig = task.getMergedOverrideConfiguration(); mTmpConfig1.setTo(mLastReportedConfiguration); mTmpConfig2.setTo(mLastReportedOverrideConfiguration); mLastReportedConfiguration.setTo(newGlobalConfig); mLastReportedOverrideConfiguration.setTo(newTaskMergedOverrideConfig); int taskChanges = getTaskConfigurationChanges(this, newTaskMergedOverrideConfig, mTmpTaskConfig); final int changes = mTmpGlobalConfig.diff(newGlobalConfig) | taskChanges; mTmpConfig2); final int changes = mTmpConfig1.diff(newGlobalConfig) | taskChanges; if (changes == 0 && !forceNewConfig) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Configuration no differences in " + this); Loading services/core/java/com/android/server/am/TaskRecord.java +16 −47 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.Rect; import android.os.Debug; Loading @@ -52,6 +51,7 @@ import com.android.internal.app.IVoiceInteractor; import com.android.internal.util.XmlUtils; import com.android.server.wm.AppWindowContainerController; import com.android.server.wm.StackWindowController; import com.android.server.wm.TaskWindowContainerController; import com.android.server.wm.TaskWindowContainerListener; Loading Loading @@ -278,7 +278,6 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta private final Rect mTmpStableBounds = new Rect(); private final Rect mTmpNonDecorBounds = new Rect(); private final Rect mTmpRect = new Rect(); private final Rect mTmpRect2 = new Rect(); // Last non-fullscreen bounds the task was launched in or resized to. // The information is persisted and used to determine the appropriate stack to launch the Loading Loading @@ -1838,60 +1837,32 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta return !mTmpConfig.equals(newConfig); } private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds, boolean overrideWidth, boolean overrideHeight) { mTmpRect2.set(inInsetBounds); mService.mWindowManager.subtractNonDecorInsets(mTmpRect2); int leftInset = mTmpRect2.left - inInsetBounds.left; int topInset = mTmpRect2.top - inInsetBounds.top; int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right; int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom; inOutBounds.inset(leftInset, topInset, rightInset, bottomInset); } private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds, boolean overrideWidth, boolean overrideHeight) { mTmpRect2.set(inInsetBounds); mService.mWindowManager.subtractStableInsets(mTmpRect2); int leftInset = mTmpRect2.left - inInsetBounds.left; int topInset = mTmpRect2.top - inInsetBounds.top; int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right; int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom; inOutBounds.inset(leftInset, topInset, rightInset, bottomInset); } /** Clears passed config and fills it with new override values. */ private void calculateOverrideConfig(Configuration config, Rect bounds, Rect insetBounds, boolean overrideWidth, boolean overrideHeight) { mTmpNonDecorBounds.set(bounds); mTmpStableBounds.set(bounds); final Configuration parentConfig = getParent().getConfiguration(); config.unset(); final Configuration parentConfig = getParent().getConfiguration(); final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; final boolean isFloatingTask = mStack != null && StackId.tasksAreFloating(mStack.mStackId); if (isFloatingTask) { // Floating tasks should not be resized to the screen's bounds. config.screenWidthDp = (int) (mTmpStableBounds.width() / density); config.screenHeightDp = (int) (mTmpStableBounds.height() / density); } else { // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen area, // i.e. the screen area without the system bars. // Additionally task dimensions should not be bigger than its parents dimensions. subtractNonDecorInsets(mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds, overrideWidth, overrideHeight); subtractStableInsets(mTmpStableBounds, insetBounds != null ? insetBounds : bounds, overrideWidth, overrideHeight); config.screenWidthDp = Math.min( (int) (mTmpStableBounds.width() / density), parentConfig.screenWidthDp); config.screenHeightDp = Math.min( (int) (mTmpStableBounds.height() / density), parentConfig.screenHeightDp); } // TODO: Orientation? config.orientation = (config.screenWidthDp <= config.screenHeightDp) ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; if (mStack != null) { final StackWindowController stackController = mStack.getWindowContainerController(); stackController.adjustConfigurationForBounds(bounds, insetBounds, mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density, config, parentConfig); } else { // No stack, give some default values config.smallestScreenWidthDp = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask; config.screenWidthDp = config.screenHeightDp = config.smallestScreenWidthDp; Slog.wtf(TAG, "Expected stack when caclulating override config"); } // For calculating screen layout, we need to use the non-decor inset screen area for the // calculation for compatibility reasons, i.e. screen area without system bars that could Loading @@ -1905,8 +1876,6 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp); config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize); config.smallestScreenWidthDp = mService.mWindowManager.getSmallestWidthForTaskBounds( insetBounds != null ? insetBounds : bounds); } /** Loading services/core/java/com/android/server/wm/DockedStackDividerController.java +1 −6 Original line number Diff line number Diff line Loading @@ -152,11 +152,6 @@ public class DockedStackDividerController implements DimLayerUser { int getSmallestWidthDpForBounds(Rect bounds) { final DisplayInfo di = mDisplayContent.getDisplayInfo(); // If the bounds are fullscreen, return the value of the fullscreen configuration if (bounds == null || (bounds.left == 0 && bounds.top == 0 && bounds.right == di.logicalWidth && bounds.bottom == di.logicalHeight)) { return mDisplayContent.getConfiguration().smallestScreenWidthDp; } final int baseDisplayWidth = mDisplayContent.mBaseDisplayWidth; final int baseDisplayHeight = mDisplayContent.mBaseDisplayHeight; int minWidth = Integer.MAX_VALUE; Loading Loading @@ -185,7 +180,7 @@ public class DockedStackDividerController implements DimLayerUser { mTmpRect2.width(), mTmpRect2.height(), getContentWidth()); mService.mPolicy.getStableInsetsLw(rotation, mTmpRect2.width(), mTmpRect2.height(), mTmpRect3); mService.subtractInsets(mTmpRect2, mTmpRect3, mTmpRect); mService.intersectDisplayInsetBounds(mTmpRect2, mTmpRect3, mTmpRect); minWidth = Math.min(mTmpRect.width(), minWidth); } return (int) (minWidth / mDisplayContent.getDisplayMetrics().density); Loading services/core/java/com/android/server/wm/StackWindowController.java +112 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import android.app.ActivityManager.StackId; import android.app.RemoteAction; import android.content.res.Configuration; import android.graphics.Rect; Loading @@ -24,6 +27,8 @@ import android.os.Looper; import android.os.Message; import android.util.Slog; import android.util.SparseArray; import android.view.DisplayInfo; import com.android.server.UiThread; import com.android.internal.annotations.VisibleForTesting; Loading @@ -48,6 +53,12 @@ public class StackWindowController private final H mHandler; // Temp bounds only used in adjustConfigurationForBounds() private final Rect mTmpRect = new Rect(); private final Rect mTmpStableInsets = new Rect(); private final Rect mTmpNonDecorInsets = new Rect(); private final Rect mTmpDisplayBounds = new Rect(); public StackWindowController(int stackId, StackWindowListener listener, int displayId, boolean onTop, Rect outBounds) { this(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance()); Loading Loading @@ -289,6 +300,107 @@ public class StackWindowController } } /** * Adjusts the screen size in dp's for the {@param config} for the given params. */ public void adjustConfigurationForBounds(Rect bounds, Rect insetBounds, Rect nonDecorBounds, Rect stableBounds, boolean overrideWidth, boolean overrideHeight, float density, Configuration config, Configuration parentConfig) { synchronized (mWindowMap) { final TaskStack stack = mContainer; final DisplayContent displayContent = stack.getDisplayContent(); final DisplayInfo di = displayContent.getDisplayInfo(); // Get the insets and display bounds mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, mTmpStableInsets); mService.mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, mTmpNonDecorInsets); mTmpDisplayBounds.set(0, 0, di.logicalWidth, di.logicalHeight); int width; int height; if (StackId.tasksAreFloating(mStackId)) { // Floating tasks should not be resized to the screen's bounds. if (bounds.width() == mTmpDisplayBounds.width() && bounds.height() == mTmpDisplayBounds.height()) { // If the bounds we are animating is the same as the fullscreen stack // dimensions, then apply the same inset calculations that we normally do for // the fullscreen stack, without intersecting it with the display bounds stableBounds.inset(mTmpStableInsets); nonDecorBounds.inset(mTmpNonDecorInsets); } width = (int) (stableBounds.width() / density); height = (int) (stableBounds.height() / density); } else { // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen // area, i.e. the screen area without the system bars. // Additionally task dimensions should not be bigger than its parents dimensions. // The non decor inset are areas that could never be removed in Honeycomb. See // {@link WindowManagerPolicy#getNonDecorInsetsLw}. intersectDisplayBoundsExcludeInsets(nonDecorBounds, insetBounds != null ? insetBounds : bounds, mTmpNonDecorInsets, mTmpDisplayBounds, overrideWidth, overrideHeight); intersectDisplayBoundsExcludeInsets(stableBounds, insetBounds != null ? insetBounds : bounds, mTmpStableInsets, mTmpDisplayBounds, overrideWidth, overrideHeight); width = Math.min((int) (stableBounds.width() / density), parentConfig.screenWidthDp); height = Math.min((int) (stableBounds.height() / density), parentConfig.screenHeightDp); } config.screenWidthDp = width; config.screenHeightDp = height; config.smallestScreenWidthDp = getSmallestWidthForTaskBounds( insetBounds != null ? insetBounds : bounds, density); } } /** * Intersects the specified {@code inOutBounds} with the display frame that excludes the stable * inset areas. * * @param inOutBounds The inOutBounds to subtract the stable inset areas from. */ private void intersectDisplayBoundsExcludeInsets(Rect inOutBounds, Rect inInsetBounds, Rect stableInsets, Rect displayBounds, boolean overrideWidth, boolean overrideHeight) { mTmpRect.set(inInsetBounds); mService.intersectDisplayInsetBounds(displayBounds, stableInsets, mTmpRect); int leftInset = mTmpRect.left - inInsetBounds.left; int topInset = mTmpRect.top - inInsetBounds.top; int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect.right; int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect.bottom; inOutBounds.inset(leftInset, topInset, rightInset, bottomInset); } /** * Calculates the smallest width for a task given the {@param bounds}. * * @return the smallest width to be used in the Configuration, in dips */ private int getSmallestWidthForTaskBounds(Rect bounds, float density) { final DisplayContent displayContent = mContainer.getDisplayContent(); final DisplayInfo displayInfo = displayContent.getDisplayInfo(); if (bounds == null || (bounds.width() == displayInfo.logicalWidth && bounds.height() == displayInfo.logicalHeight)) { // If the bounds are fullscreen, return the value of the fullscreen configuration return displayContent.getConfiguration().smallestScreenWidthDp; } else if (StackId.tasksAreFloating(mStackId)) { // For floating tasks, calculate the smallest width from the bounds of the task return (int) (Math.min(bounds.width(), bounds.height()) / density); } else { // Iterating across all screen orientations, and return the minimum of the task // width taking into account that the bounds might change because the snap algorithm // snaps to a different value return displayContent.getDockedDividerController() .getSmallestWidthDpForBounds(bounds); } } void requestResize(Rect bounds) { mHandler.obtainMessage(H.REQUEST_RESIZE, bounds).sendToTarget(); } Loading services/core/java/com/android/server/wm/TaskStack.java +4 −1 Original line number Diff line number Diff line Loading @@ -1476,7 +1476,10 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye @Override public void getFullScreenBounds(Rect bounds) { getDisplayContent().getContentRect(bounds); // This is currently only used for the pinned stack animation when leaving PiP // (see {@link BoundsAnimationController}), and in that case we need to animate this back // to the full bounds to match the fullscreen stack getDisplayContent().getLogicalDisplayRect(bounds); } public boolean hasMovementAnimations() { Loading Loading
services/core/java/com/android/server/am/ActivityRecord.java +15 −16 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import static android.app.ActivityManager.StackId; import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID; 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.FULLSCREEN_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.HOME_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.AppOpsManager.MODE_ALLOWED; Loading @@ -47,7 +46,6 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.res.Configuration.UI_MODE_TYPE_MASK; import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET; import static android.os.Build.VERSION_CODES.HONEYCOMB; import static android.os.Build.VERSION_CODES.O; Loading Loading @@ -85,7 +83,6 @@ import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.IBinder; Loading Loading @@ -290,8 +287,8 @@ final class ActivityRecord implements AppWindowContainerListener { /** * Temp configs used in {@link #ensureActivityConfigurationLocked(int, boolean)} */ private final Configuration mTmpGlobalConfig = new Configuration(); private final Configuration mTmpTaskConfig = new Configuration(); private final Configuration mTmpConfig1 = new Configuration(); private final Configuration mTmpConfig2 = new Configuration(); private static String startingWindowStateToString(int state) { switch (state) { Loading Loading @@ -1975,13 +1972,13 @@ final class ActivityRecord implements AppWindowContainerListener { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Ensuring correct configuration: " + this); // Short circuit: if the two configurations are equal (the common case), then there is // nothing to do. final Configuration newGlobalConfig = service.getGlobalConfiguration(); final Configuration newTaskMergedOverrideConfig = task.getMergedOverrideConfiguration(); if (mLastReportedConfiguration.equals(newGlobalConfig) && mLastReportedOverrideConfiguration.equals(newTaskMergedOverrideConfig) && !forceNewConfig) { // Short circuit: if the two full configurations are equal (the common case), then there is // nothing to do. We test the full configuration instead of the global and merged override // configurations because there are cases (like moving a task to the pinned stack) where // the combine configurations are equal, but would otherwise differ in the override config mTmpConfig1.setTo(mLastReportedConfiguration); mTmpConfig1.updateFrom(mLastReportedOverrideConfiguration); if (task.getConfiguration().equals(mTmpConfig1) && !forceNewConfig) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Configuration unchanged in " + this); return true; Loading @@ -1997,14 +1994,16 @@ final class ActivityRecord implements AppWindowContainerListener { // Okay we now are going to make this activity have the new config. // But then we need to figure out how it needs to deal with that. mTmpGlobalConfig.setTo(mLastReportedConfiguration); mTmpTaskConfig.setTo(mLastReportedOverrideConfiguration); final Configuration newGlobalConfig = service.getGlobalConfiguration(); final Configuration newTaskMergedOverrideConfig = task.getMergedOverrideConfiguration(); mTmpConfig1.setTo(mLastReportedConfiguration); mTmpConfig2.setTo(mLastReportedOverrideConfiguration); mLastReportedConfiguration.setTo(newGlobalConfig); mLastReportedOverrideConfiguration.setTo(newTaskMergedOverrideConfig); int taskChanges = getTaskConfigurationChanges(this, newTaskMergedOverrideConfig, mTmpTaskConfig); final int changes = mTmpGlobalConfig.diff(newGlobalConfig) | taskChanges; mTmpConfig2); final int changes = mTmpConfig1.diff(newGlobalConfig) | taskChanges; if (changes == 0 && !forceNewConfig) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Configuration no differences in " + this); Loading
services/core/java/com/android/server/am/TaskRecord.java +16 −47 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.Rect; import android.os.Debug; Loading @@ -52,6 +51,7 @@ import com.android.internal.app.IVoiceInteractor; import com.android.internal.util.XmlUtils; import com.android.server.wm.AppWindowContainerController; import com.android.server.wm.StackWindowController; import com.android.server.wm.TaskWindowContainerController; import com.android.server.wm.TaskWindowContainerListener; Loading Loading @@ -278,7 +278,6 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta private final Rect mTmpStableBounds = new Rect(); private final Rect mTmpNonDecorBounds = new Rect(); private final Rect mTmpRect = new Rect(); private final Rect mTmpRect2 = new Rect(); // Last non-fullscreen bounds the task was launched in or resized to. // The information is persisted and used to determine the appropriate stack to launch the Loading Loading @@ -1838,60 +1837,32 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta return !mTmpConfig.equals(newConfig); } private void subtractNonDecorInsets(Rect inOutBounds, Rect inInsetBounds, boolean overrideWidth, boolean overrideHeight) { mTmpRect2.set(inInsetBounds); mService.mWindowManager.subtractNonDecorInsets(mTmpRect2); int leftInset = mTmpRect2.left - inInsetBounds.left; int topInset = mTmpRect2.top - inInsetBounds.top; int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right; int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom; inOutBounds.inset(leftInset, topInset, rightInset, bottomInset); } private void subtractStableInsets(Rect inOutBounds, Rect inInsetBounds, boolean overrideWidth, boolean overrideHeight) { mTmpRect2.set(inInsetBounds); mService.mWindowManager.subtractStableInsets(mTmpRect2); int leftInset = mTmpRect2.left - inInsetBounds.left; int topInset = mTmpRect2.top - inInsetBounds.top; int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect2.right; int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect2.bottom; inOutBounds.inset(leftInset, topInset, rightInset, bottomInset); } /** Clears passed config and fills it with new override values. */ private void calculateOverrideConfig(Configuration config, Rect bounds, Rect insetBounds, boolean overrideWidth, boolean overrideHeight) { mTmpNonDecorBounds.set(bounds); mTmpStableBounds.set(bounds); final Configuration parentConfig = getParent().getConfiguration(); config.unset(); final Configuration parentConfig = getParent().getConfiguration(); final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; final boolean isFloatingTask = mStack != null && StackId.tasksAreFloating(mStack.mStackId); if (isFloatingTask) { // Floating tasks should not be resized to the screen's bounds. config.screenWidthDp = (int) (mTmpStableBounds.width() / density); config.screenHeightDp = (int) (mTmpStableBounds.height() / density); } else { // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen area, // i.e. the screen area without the system bars. // Additionally task dimensions should not be bigger than its parents dimensions. subtractNonDecorInsets(mTmpNonDecorBounds, insetBounds != null ? insetBounds : bounds, overrideWidth, overrideHeight); subtractStableInsets(mTmpStableBounds, insetBounds != null ? insetBounds : bounds, overrideWidth, overrideHeight); config.screenWidthDp = Math.min( (int) (mTmpStableBounds.width() / density), parentConfig.screenWidthDp); config.screenHeightDp = Math.min( (int) (mTmpStableBounds.height() / density), parentConfig.screenHeightDp); } // TODO: Orientation? config.orientation = (config.screenWidthDp <= config.screenHeightDp) ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; if (mStack != null) { final StackWindowController stackController = mStack.getWindowContainerController(); stackController.adjustConfigurationForBounds(bounds, insetBounds, mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density, config, parentConfig); } else { // No stack, give some default values config.smallestScreenWidthDp = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask; config.screenWidthDp = config.screenHeightDp = config.smallestScreenWidthDp; Slog.wtf(TAG, "Expected stack when caclulating override config"); } // For calculating screen layout, we need to use the non-decor inset screen area for the // calculation for compatibility reasons, i.e. screen area without system bars that could Loading @@ -1905,8 +1876,6 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp); config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize); config.smallestScreenWidthDp = mService.mWindowManager.getSmallestWidthForTaskBounds( insetBounds != null ? insetBounds : bounds); } /** Loading
services/core/java/com/android/server/wm/DockedStackDividerController.java +1 −6 Original line number Diff line number Diff line Loading @@ -152,11 +152,6 @@ public class DockedStackDividerController implements DimLayerUser { int getSmallestWidthDpForBounds(Rect bounds) { final DisplayInfo di = mDisplayContent.getDisplayInfo(); // If the bounds are fullscreen, return the value of the fullscreen configuration if (bounds == null || (bounds.left == 0 && bounds.top == 0 && bounds.right == di.logicalWidth && bounds.bottom == di.logicalHeight)) { return mDisplayContent.getConfiguration().smallestScreenWidthDp; } final int baseDisplayWidth = mDisplayContent.mBaseDisplayWidth; final int baseDisplayHeight = mDisplayContent.mBaseDisplayHeight; int minWidth = Integer.MAX_VALUE; Loading Loading @@ -185,7 +180,7 @@ public class DockedStackDividerController implements DimLayerUser { mTmpRect2.width(), mTmpRect2.height(), getContentWidth()); mService.mPolicy.getStableInsetsLw(rotation, mTmpRect2.width(), mTmpRect2.height(), mTmpRect3); mService.subtractInsets(mTmpRect2, mTmpRect3, mTmpRect); mService.intersectDisplayInsetBounds(mTmpRect2, mTmpRect3, mTmpRect); minWidth = Math.min(mTmpRect.width(), minWidth); } return (int) (minWidth / mDisplayContent.getDisplayMetrics().density); Loading
services/core/java/com/android/server/wm/StackWindowController.java +112 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.wm; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import android.app.ActivityManager.StackId; import android.app.RemoteAction; import android.content.res.Configuration; import android.graphics.Rect; Loading @@ -24,6 +27,8 @@ import android.os.Looper; import android.os.Message; import android.util.Slog; import android.util.SparseArray; import android.view.DisplayInfo; import com.android.server.UiThread; import com.android.internal.annotations.VisibleForTesting; Loading @@ -48,6 +53,12 @@ public class StackWindowController private final H mHandler; // Temp bounds only used in adjustConfigurationForBounds() private final Rect mTmpRect = new Rect(); private final Rect mTmpStableInsets = new Rect(); private final Rect mTmpNonDecorInsets = new Rect(); private final Rect mTmpDisplayBounds = new Rect(); public StackWindowController(int stackId, StackWindowListener listener, int displayId, boolean onTop, Rect outBounds) { this(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance()); Loading Loading @@ -289,6 +300,107 @@ public class StackWindowController } } /** * Adjusts the screen size in dp's for the {@param config} for the given params. */ public void adjustConfigurationForBounds(Rect bounds, Rect insetBounds, Rect nonDecorBounds, Rect stableBounds, boolean overrideWidth, boolean overrideHeight, float density, Configuration config, Configuration parentConfig) { synchronized (mWindowMap) { final TaskStack stack = mContainer; final DisplayContent displayContent = stack.getDisplayContent(); final DisplayInfo di = displayContent.getDisplayInfo(); // Get the insets and display bounds mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, mTmpStableInsets); mService.mPolicy.getNonDecorInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight, mTmpNonDecorInsets); mTmpDisplayBounds.set(0, 0, di.logicalWidth, di.logicalHeight); int width; int height; if (StackId.tasksAreFloating(mStackId)) { // Floating tasks should not be resized to the screen's bounds. if (bounds.width() == mTmpDisplayBounds.width() && bounds.height() == mTmpDisplayBounds.height()) { // If the bounds we are animating is the same as the fullscreen stack // dimensions, then apply the same inset calculations that we normally do for // the fullscreen stack, without intersecting it with the display bounds stableBounds.inset(mTmpStableInsets); nonDecorBounds.inset(mTmpNonDecorInsets); } width = (int) (stableBounds.width() / density); height = (int) (stableBounds.height() / density); } else { // For calculating screenWidthDp, screenWidthDp, we use the stable inset screen // area, i.e. the screen area without the system bars. // Additionally task dimensions should not be bigger than its parents dimensions. // The non decor inset are areas that could never be removed in Honeycomb. See // {@link WindowManagerPolicy#getNonDecorInsetsLw}. intersectDisplayBoundsExcludeInsets(nonDecorBounds, insetBounds != null ? insetBounds : bounds, mTmpNonDecorInsets, mTmpDisplayBounds, overrideWidth, overrideHeight); intersectDisplayBoundsExcludeInsets(stableBounds, insetBounds != null ? insetBounds : bounds, mTmpStableInsets, mTmpDisplayBounds, overrideWidth, overrideHeight); width = Math.min((int) (stableBounds.width() / density), parentConfig.screenWidthDp); height = Math.min((int) (stableBounds.height() / density), parentConfig.screenHeightDp); } config.screenWidthDp = width; config.screenHeightDp = height; config.smallestScreenWidthDp = getSmallestWidthForTaskBounds( insetBounds != null ? insetBounds : bounds, density); } } /** * Intersects the specified {@code inOutBounds} with the display frame that excludes the stable * inset areas. * * @param inOutBounds The inOutBounds to subtract the stable inset areas from. */ private void intersectDisplayBoundsExcludeInsets(Rect inOutBounds, Rect inInsetBounds, Rect stableInsets, Rect displayBounds, boolean overrideWidth, boolean overrideHeight) { mTmpRect.set(inInsetBounds); mService.intersectDisplayInsetBounds(displayBounds, stableInsets, mTmpRect); int leftInset = mTmpRect.left - inInsetBounds.left; int topInset = mTmpRect.top - inInsetBounds.top; int rightInset = overrideWidth ? 0 : inInsetBounds.right - mTmpRect.right; int bottomInset = overrideHeight ? 0 : inInsetBounds.bottom - mTmpRect.bottom; inOutBounds.inset(leftInset, topInset, rightInset, bottomInset); } /** * Calculates the smallest width for a task given the {@param bounds}. * * @return the smallest width to be used in the Configuration, in dips */ private int getSmallestWidthForTaskBounds(Rect bounds, float density) { final DisplayContent displayContent = mContainer.getDisplayContent(); final DisplayInfo displayInfo = displayContent.getDisplayInfo(); if (bounds == null || (bounds.width() == displayInfo.logicalWidth && bounds.height() == displayInfo.logicalHeight)) { // If the bounds are fullscreen, return the value of the fullscreen configuration return displayContent.getConfiguration().smallestScreenWidthDp; } else if (StackId.tasksAreFloating(mStackId)) { // For floating tasks, calculate the smallest width from the bounds of the task return (int) (Math.min(bounds.width(), bounds.height()) / density); } else { // Iterating across all screen orientations, and return the minimum of the task // width taking into account that the bounds might change because the snap algorithm // snaps to a different value return displayContent.getDockedDividerController() .getSmallestWidthDpForBounds(bounds); } } void requestResize(Rect bounds) { mHandler.obtainMessage(H.REQUEST_RESIZE, bounds).sendToTarget(); } Loading
services/core/java/com/android/server/wm/TaskStack.java +4 −1 Original line number Diff line number Diff line Loading @@ -1476,7 +1476,10 @@ public class TaskStack extends WindowContainer<Task> implements DimLayer.DimLaye @Override public void getFullScreenBounds(Rect bounds) { getDisplayContent().getContentRect(bounds); // This is currently only used for the pinned stack animation when leaving PiP // (see {@link BoundsAnimationController}), and in that case we need to animate this back // to the full bounds to match the fullscreen stack getDisplayContent().getLogicalDisplayRect(bounds); } public boolean hasMovementAnimations() { Loading