Merge "Fix smallest width configuration calculation" into nyc-dev
This commit is contained in:
@@ -246,7 +246,8 @@ public class DividerSnapAlgorithm {
|
||||
int dividerMax = isHorizontalDivision
|
||||
? mDisplayHeight
|
||||
: mDisplayWidth;
|
||||
mTargets.add(new SnapTarget(-mDividerSize, SnapTarget.FLAG_DISMISS_START, 0.35f));
|
||||
mTargets.add(new SnapTarget(-mDividerSize, -mDividerSize, SnapTarget.FLAG_DISMISS_START,
|
||||
0.35f));
|
||||
switch (mSnapMode) {
|
||||
case SNAP_MODE_16_9:
|
||||
addRatio16_9Targets(isHorizontalDivision, dividerMax);
|
||||
@@ -259,7 +260,8 @@ public class DividerSnapAlgorithm {
|
||||
break;
|
||||
}
|
||||
int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
|
||||
mTargets.add(new SnapTarget(dividerMax - navBarSize, SnapTarget.FLAG_DISMISS_END, 0.35f));
|
||||
mTargets.add(new SnapTarget(dividerMax - navBarSize, dividerMax,
|
||||
SnapTarget.FLAG_DISMISS_END, 0.35f));
|
||||
}
|
||||
|
||||
private void addNonDismissingTargets(boolean isHorizontalDivision, int topPosition,
|
||||
@@ -269,13 +271,15 @@ public class DividerSnapAlgorithm {
|
||||
maybeAddTarget(bottomPosition, dividerMax - mInsets.bottom
|
||||
- (bottomPosition + mDividerSize));
|
||||
}
|
||||
|
||||
private void addFixedDivisionTargets(boolean isHorizontalDivision, int dividerMax) {
|
||||
int start = isHorizontalDivision ? mInsets.top : mInsets.left;
|
||||
int end = isHorizontalDivision
|
||||
? mDisplayHeight - mInsets.bottom
|
||||
: mDisplayWidth - mInsets.right;
|
||||
int topPosition = (int) (start + mFixedRatio * (end - start)) - mDividerSize / 2;
|
||||
int bottomPosition = (int) (start + (1 - mFixedRatio) * (end - start)) - mDividerSize / 2;
|
||||
int size = (int) (mFixedRatio * (end - start)) - mDividerSize / 2;
|
||||
int topPosition = start + size;
|
||||
int bottomPosition = end - size - mDividerSize;
|
||||
addNonDismissingTargets(isHorizontalDivision, topPosition, bottomPosition, dividerMax);
|
||||
}
|
||||
|
||||
@@ -301,13 +305,14 @@ public class DividerSnapAlgorithm {
|
||||
*/
|
||||
private void maybeAddTarget(int position, int smallerSize) {
|
||||
if (smallerSize >= mMinimalSizeResizableTask) {
|
||||
mTargets.add(new SnapTarget(position, SnapTarget.FLAG_NONE));
|
||||
mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
|
||||
}
|
||||
}
|
||||
|
||||
private void addMiddleTarget(boolean isHorizontalDivision) {
|
||||
mTargets.add(new SnapTarget(DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision,
|
||||
mInsets, mDisplayWidth, mDisplayHeight, mDividerSize), SnapTarget.FLAG_NONE));
|
||||
int position = DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision,
|
||||
mInsets, mDisplayWidth, mDisplayHeight, mDividerSize);
|
||||
mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
|
||||
}
|
||||
|
||||
public SnapTarget getMiddleTarget() {
|
||||
@@ -370,7 +375,15 @@ public class DividerSnapAlgorithm {
|
||||
/** If the divider reaches this value, the right/bottom task should be dismissed */
|
||||
public static final int FLAG_DISMISS_END = 2;
|
||||
|
||||
/** Position of this snap target. The right/bottom edge of the top/left task snaps here. */
|
||||
public final int position;
|
||||
|
||||
/**
|
||||
* Like {@link #position}, but used to calculate the task bounds which might be different
|
||||
* from the stack bounds.
|
||||
*/
|
||||
public final int taskPosition;
|
||||
|
||||
public final int flag;
|
||||
|
||||
/**
|
||||
@@ -379,12 +392,13 @@ public class DividerSnapAlgorithm {
|
||||
*/
|
||||
private final float distanceMultiplier;
|
||||
|
||||
public SnapTarget(int position, int flag) {
|
||||
this(position, flag, 1f);
|
||||
public SnapTarget(int position, int taskPosition, int flag) {
|
||||
this(position, taskPosition, flag, 1f);
|
||||
}
|
||||
|
||||
public SnapTarget(int position, int flag, float distanceMultiplier) {
|
||||
public SnapTarget(int position, int taskPosition, int flag, float distanceMultiplier) {
|
||||
this.position = position;
|
||||
this.taskPosition = taskPosition;
|
||||
this.flag = flag;
|
||||
this.distanceMultiplier = distanceMultiplier;
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ public class DividerView extends FrameLayout implements OnTouchListener,
|
||||
anim.addUpdateListener(animation -> resizeStack((Integer) animation.getAnimatedValue(),
|
||||
taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f
|
||||
? TASK_POSITION_SAME
|
||||
: snapTarget.position, snapTarget));
|
||||
: snapTarget.taskPosition, snapTarget));
|
||||
Runnable endAction = () -> {
|
||||
commitSnapFlags(snapTarget);
|
||||
mWindowManagerProxy.setResizing(false);
|
||||
|
||||
@@ -1508,16 +1508,18 @@ final class TaskRecord {
|
||||
? Configuration.ORIENTATION_PORTRAIT
|
||||
: Configuration.ORIENTATION_LANDSCAPE;
|
||||
|
||||
// For calculating screen layout and smallest screen width, 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 never go away in Honeycomb.
|
||||
// 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
|
||||
// never go away in Honeycomb.
|
||||
final int compatScreenWidthDp = (int)(mTmpNonDecorBounds.width() / density);
|
||||
final int compatScreenHeightDp = (int)(mTmpNonDecorBounds.height() / density);
|
||||
final int sl = Configuration.resetScreenLayout(serviceConfig.screenLayout);
|
||||
final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp);
|
||||
config.smallestScreenWidthDp = Math.min(compatScreenHeightDp, compatScreenWidthDp);
|
||||
config.screenLayout = Configuration.reduceScreenLayout(sl, longSize,
|
||||
config.smallestScreenWidthDp);
|
||||
final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp);;
|
||||
config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize);
|
||||
|
||||
config.smallestScreenWidthDp = mService.mWindowManager.getSmallestWidthForTaskBounds(
|
||||
insetBounds != null ? insetBounds : bounds);
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ package com.android.server.wm;
|
||||
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
|
||||
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
import static android.view.Surface.ROTATION_270;
|
||||
import static android.view.Surface.ROTATION_90;
|
||||
import static android.view.WindowManager.DOCKED_BOTTOM;
|
||||
import static android.view.WindowManager.DOCKED_LEFT;
|
||||
import static android.view.WindowManager.DOCKED_RIGHT;
|
||||
@@ -30,6 +34,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
import static com.android.server.wm.WindowManagerService.H.NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
@@ -41,6 +46,8 @@ import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
import com.android.internal.policy.DividerSnapAlgorithm;
|
||||
import com.android.internal.policy.DockedDividerUtils;
|
||||
import com.android.server.wm.DimLayer.DimLayerUser;
|
||||
import com.android.server.wm.WindowManagerService.H;
|
||||
|
||||
@@ -96,6 +103,7 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
private WindowState mWindow;
|
||||
private final Rect mTmpRect = new Rect();
|
||||
private final Rect mTmpRect2 = new Rect();
|
||||
private final Rect mTmpRect3 = new Rect();
|
||||
private final Rect mLastRect = new Rect();
|
||||
private boolean mLastVisibility = false;
|
||||
private final RemoteCallbackList<IDockedStackListener> mDockedStackListeners
|
||||
@@ -121,6 +129,7 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
private float mDividerAnimationTarget;
|
||||
private float mLastAnimationProgress;
|
||||
private float mLastDividerProgress;
|
||||
private final DividerSnapAlgorithm[] mSnapAlgorithmForRotation = new DividerSnapAlgorithm[4];
|
||||
|
||||
DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) {
|
||||
mService = service;
|
||||
@@ -133,6 +142,77 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
loadDimens();
|
||||
}
|
||||
|
||||
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 mService.mCurConfiguration.smallestScreenWidthDp;
|
||||
}
|
||||
final int baseDisplayWidth = mDisplayContent.mBaseDisplayWidth;
|
||||
final int baseDisplayHeight = mDisplayContent.mBaseDisplayHeight;
|
||||
int minWidth = Integer.MAX_VALUE;
|
||||
|
||||
// Go through all screen orientations and find the orientation in which the task has the
|
||||
// smallest width.
|
||||
for (int rotation = 0; rotation < 4; rotation++) {
|
||||
mTmpRect.set(bounds);
|
||||
mDisplayContent.rotateBounds(di.rotation, rotation, mTmpRect);
|
||||
final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
|
||||
mTmpRect2.set(0, 0,
|
||||
rotated ? baseDisplayHeight : baseDisplayWidth,
|
||||
rotated ? baseDisplayWidth : baseDisplayHeight);
|
||||
final int orientation = mTmpRect2.width() <= mTmpRect2.height()
|
||||
? ORIENTATION_PORTRAIT
|
||||
: ORIENTATION_LANDSCAPE;
|
||||
final int dockSide = TaskStack.getDockSideUnchecked(mTmpRect, mTmpRect2, orientation);
|
||||
final int position = DockedDividerUtils.calculatePositionForBounds(mTmpRect, dockSide,
|
||||
getContentWidth());
|
||||
|
||||
// Since we only care about feasible states, snap to the closest snap target, like it
|
||||
// would happen when actually rotating the screen.
|
||||
final int snappedPosition = mSnapAlgorithmForRotation[rotation]
|
||||
.calculateNonDismissingSnapTarget(position).position;
|
||||
DockedDividerUtils.calculateBoundsForPosition(snappedPosition, dockSide, mTmpRect,
|
||||
mTmpRect2.width(), mTmpRect2.height(), getContentWidth());
|
||||
mService.mPolicy.getStableInsetsLw(rotation, mTmpRect2.width(), mTmpRect2.height(),
|
||||
mTmpRect3);
|
||||
mService.subtractInsets(mTmpRect2, mTmpRect3, mTmpRect);
|
||||
minWidth = Math.min(mTmpRect.width(), minWidth);
|
||||
}
|
||||
return (int) (minWidth / mDisplayContent.getDisplayMetrics().density);
|
||||
}
|
||||
|
||||
private void initSnapAlgorithmForRotations() {
|
||||
final Configuration baseConfig = mService.mCurConfiguration;
|
||||
|
||||
// Initialize the snap algorithms for all 4 screen orientations.
|
||||
final Configuration config = new Configuration();
|
||||
for (int rotation = 0; rotation < 4; rotation++) {
|
||||
final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
|
||||
final int dw = rotated
|
||||
? mDisplayContent.mBaseDisplayHeight
|
||||
: mDisplayContent.mBaseDisplayWidth;
|
||||
final int dh = rotated
|
||||
? mDisplayContent.mBaseDisplayWidth
|
||||
: mDisplayContent.mBaseDisplayHeight;
|
||||
mService.mPolicy.getStableInsetsLw(rotation, dw, dh, mTmpRect);
|
||||
config.setToDefaults();
|
||||
config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
|
||||
config.screenWidthDp = (int)
|
||||
(mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode) /
|
||||
mDisplayContent.getDisplayMetrics().density);
|
||||
config.screenHeightDp = (int)
|
||||
(mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, baseConfig.uiMode) /
|
||||
mDisplayContent.getDisplayMetrics().density);
|
||||
final Context rotationContext = mService.mContext.createConfigurationContext(config);
|
||||
mSnapAlgorithmForRotation[rotation] = new DividerSnapAlgorithm(
|
||||
rotationContext.getResources(), dw, dh, getContentWidth(),
|
||||
config.orientation == ORIENTATION_PORTRAIT, mTmpRect);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadDimens() {
|
||||
final Context context = mService.mContext;
|
||||
mDividerWindowWidth = context.getResources().getDimensionPixelSize(
|
||||
@@ -141,6 +221,7 @@ public class DockedStackDividerController implements DimLayerUser {
|
||||
com.android.internal.R.dimen.docked_stack_divider_insets);
|
||||
mDividerWindowWidthInactive = WindowManagerService.dipToPixel(
|
||||
DIVIDER_WIDTH_INACTIVE_DP, mDisplayContent.getDisplayMetrics());
|
||||
initSnapAlgorithmForRotations();
|
||||
}
|
||||
|
||||
void onConfigurationChanged() {
|
||||
|
||||
@@ -1197,16 +1197,20 @@ public class TaskStack implements DimLayer.DimLayerUser,
|
||||
}
|
||||
mDisplayContent.getLogicalDisplayRect(mTmpRect);
|
||||
final int orientation = mService.mCurConfiguration.orientation;
|
||||
return getDockSideUnchecked(bounds, mTmpRect, orientation);
|
||||
}
|
||||
|
||||
static int getDockSideUnchecked(Rect bounds, Rect displayRect, int orientation) {
|
||||
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
// Portrait mode, docked either at the top or the bottom.
|
||||
if (bounds.top - mTmpRect.top <= mTmpRect.bottom - bounds.bottom) {
|
||||
if (bounds.top - displayRect.top <= displayRect.bottom - bounds.bottom) {
|
||||
return DOCKED_TOP;
|
||||
} else {
|
||||
return DOCKED_BOTTOM;
|
||||
}
|
||||
} else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
// Landscape mode, docked either on the left or on the right.
|
||||
if (bounds.left - mTmpRect.left <= mTmpRect.right - bounds.right) {
|
||||
if (bounds.left - displayRect.left <= displayRect.right - bounds.right) {
|
||||
return DOCKED_LEFT;
|
||||
} else {
|
||||
return DOCKED_RIGHT;
|
||||
|
||||
@@ -501,7 +501,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
final float[] mTmpFloats = new float[9];
|
||||
final Rect mTmpRect = new Rect();
|
||||
final Rect mTmpRect2 = new Rect();
|
||||
final Region mTmpRegion = new Region();
|
||||
final Rect mTmpRect3 = new Rect();
|
||||
|
||||
boolean mDisplayReady;
|
||||
boolean mSafeMode;
|
||||
@@ -10889,8 +10889,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
getStableInsetsLocked(mTmpRect2);
|
||||
final DisplayInfo di = getDefaultDisplayInfoLocked();
|
||||
mTmpRect.set(0, 0, di.logicalWidth, di.logicalHeight);
|
||||
mTmpRect.inset(mTmpRect2);
|
||||
inOutBounds.intersect(mTmpRect);
|
||||
subtractInsets(mTmpRect, mTmpRect2, inOutBounds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10906,8 +10905,27 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
getNonDecorInsetsLocked(mTmpRect2);
|
||||
final DisplayInfo di = getDefaultDisplayInfoLocked();
|
||||
mTmpRect.set(0, 0, di.logicalWidth, di.logicalHeight);
|
||||
mTmpRect.inset(mTmpRect2);
|
||||
inOutBounds.intersect(mTmpRect);
|
||||
subtractInsets(mTmpRect, mTmpRect2, inOutBounds);
|
||||
}
|
||||
}
|
||||
|
||||
void subtractInsets(Rect display, Rect insets, Rect inOutBounds) {
|
||||
mTmpRect3.set(display);
|
||||
mTmpRect3.inset(insets);
|
||||
inOutBounds.intersect(mTmpRect3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the smallest width for a task given the {@param bounds}. It does that by iterating
|
||||
* across all screen orientations, and returns the minimum of the task width taking into account
|
||||
* that the bounds might change because the snap algorithm snaps to a different value.
|
||||
*
|
||||
* @return the smallest width to be used in the Configuration, in dips
|
||||
*/
|
||||
public int getSmallestWidthForTaskBounds(Rect bounds) {
|
||||
synchronized (mWindowMap) {
|
||||
return getDefaultDisplayContentLocked().getDockedDividerController()
|
||||
.getSmallestWidthDpForBounds(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user