Merge "DisplayContent rotateBounds not keeping same physical position for 180" into sc-dev
This commit is contained in:
@@ -24,6 +24,7 @@ import static android.view.Surface.ROTATION_90;
|
|||||||
import android.annotation.Dimension;
|
import android.annotation.Dimension;
|
||||||
import android.graphics.Insets;
|
import android.graphics.Insets;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.view.Surface.Rotation;
|
import android.view.Surface.Rotation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,6 +73,60 @@ public class RotationUtils {
|
|||||||
return rotated;
|
return rotated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates bounds as if parentBounds and bounds are a group. The group is rotated from
|
||||||
|
* oldRotation to newRotation. This assumes that parentBounds is at 0,0 and remains at 0,0 after
|
||||||
|
* rotation. The bounds will be at the same physical position in parentBounds.
|
||||||
|
*
|
||||||
|
* Only 'inOutBounds' is mutated.
|
||||||
|
*/
|
||||||
|
public static void rotateBounds(Rect inOutBounds, Rect parentBounds, @Rotation int oldRotation,
|
||||||
|
@Rotation int newRotation) {
|
||||||
|
rotateBounds(inOutBounds, parentBounds, deltaRotation(oldRotation, newRotation));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates bounds as if parentBounds and bounds are a group. The group is rotated by `delta`
|
||||||
|
* 90-degree counter-clockwise increments. This assumes that parentBounds is at 0,0 and
|
||||||
|
* remains at 0,0 after rotation. The bounds will be at the same physical position in
|
||||||
|
* parentBounds.
|
||||||
|
*
|
||||||
|
* Only 'inOutBounds' is mutated.
|
||||||
|
*/
|
||||||
|
public static void rotateBounds(Rect inOutBounds, Rect parentBounds, @Rotation int rotation) {
|
||||||
|
final int origLeft = inOutBounds.left;
|
||||||
|
final int origTop = inOutBounds.top;
|
||||||
|
switch (rotation) {
|
||||||
|
case ROTATION_0:
|
||||||
|
return;
|
||||||
|
case ROTATION_90:
|
||||||
|
inOutBounds.left = inOutBounds.top;
|
||||||
|
inOutBounds.top = parentBounds.right - inOutBounds.right;
|
||||||
|
inOutBounds.right = inOutBounds.bottom;
|
||||||
|
inOutBounds.bottom = parentBounds.right - origLeft;
|
||||||
|
return;
|
||||||
|
case ROTATION_180:
|
||||||
|
inOutBounds.left = parentBounds.right - inOutBounds.right;
|
||||||
|
inOutBounds.right = parentBounds.right - origLeft;
|
||||||
|
inOutBounds.top = parentBounds.bottom - inOutBounds.bottom;
|
||||||
|
inOutBounds.bottom = parentBounds.bottom - origTop;
|
||||||
|
return;
|
||||||
|
case ROTATION_270:
|
||||||
|
inOutBounds.left = parentBounds.bottom - inOutBounds.bottom;
|
||||||
|
inOutBounds.bottom = inOutBounds.right;
|
||||||
|
inOutBounds.right = parentBounds.bottom - inOutBounds.top;
|
||||||
|
inOutBounds.top = origLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return the rotation needed to rotate from oldRotation to newRotation. */
|
||||||
|
@Rotation
|
||||||
|
public static int deltaRotation(int oldRotation, int newRotation) {
|
||||||
|
int delta = newRotation - oldRotation;
|
||||||
|
if (delta < 0) delta += 4;
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a matrix such that given a rotation, it transforms physical display
|
* Sets a matrix such that given a rotation, it transforms physical display
|
||||||
* coordinates to that rotation's logical coordinates.
|
* coordinates to that rotation's logical coordinates.
|
||||||
|
|||||||
61
core/tests/coretests/src/android/util/RotationUtilsTest.java
Normal file
61
core/tests/coretests/src/android/util/RotationUtilsTest.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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 android.util;
|
||||||
|
|
||||||
|
import static android.util.RotationUtils.rotateBounds;
|
||||||
|
import static android.view.Surface.ROTATION_180;
|
||||||
|
import static android.view.Surface.ROTATION_270;
|
||||||
|
import static android.view.Surface.ROTATION_90;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link RotationUtils}.
|
||||||
|
*
|
||||||
|
* Build/Install/Run:
|
||||||
|
* atest FrameworksCoreTests:RotationUtilsTest
|
||||||
|
*/
|
||||||
|
@SmallTest
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class RotationUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRotateBounds() {
|
||||||
|
Rect testParent = new Rect(0, 0, 1000, 600);
|
||||||
|
Rect testInner = new Rect(40, 20, 120, 80);
|
||||||
|
|
||||||
|
Rect testResult = new Rect(testInner);
|
||||||
|
rotateBounds(testResult, testParent, ROTATION_90);
|
||||||
|
assertEquals(new Rect(20, 880, 80, 960), testResult);
|
||||||
|
|
||||||
|
testResult.set(testInner);
|
||||||
|
rotateBounds(testResult, testParent, ROTATION_180);
|
||||||
|
assertEquals(new Rect(880, 520, 960, 580), testResult);
|
||||||
|
|
||||||
|
testResult.set(testInner);
|
||||||
|
rotateBounds(testResult, testParent, ROTATION_270);
|
||||||
|
assertEquals(new Rect(520, 40, 580, 120), testResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,8 @@ import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
|
|||||||
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
|
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
|
||||||
import static android.os.Process.SYSTEM_UID;
|
import static android.os.Process.SYSTEM_UID;
|
||||||
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
|
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
|
||||||
|
import static android.util.RotationUtils.rotateBounds;
|
||||||
|
import static android.util.RotationUtils.rotateInsets;
|
||||||
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
|
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
|
||||||
import static android.view.Surface.ROTATION_0;
|
import static android.view.Surface.ROTATION_0;
|
||||||
import static android.view.Surface.ROTATION_270;
|
import static android.view.Surface.ROTATION_270;
|
||||||
@@ -37,7 +39,6 @@ import android.graphics.Rect;
|
|||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.RotationUtils;
|
|
||||||
import android.util.Size;
|
import android.util.Size;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.DisplayCutout;
|
import android.view.DisplayCutout;
|
||||||
@@ -240,38 +241,6 @@ public class DisplayLayout {
|
|||||||
return navigationBarPosition(res, mWidth, mHeight, mRotation);
|
return navigationBarPosition(res, mWidth, mHeight, mRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotates bounds as if parentBounds and bounds are a group. The group is rotated by `delta`
|
|
||||||
* 90-degree counter-clockwise increments. This assumes that parentBounds is at 0,0 and
|
|
||||||
* remains at 0,0 after rotation.
|
|
||||||
*
|
|
||||||
* Only 'bounds' is mutated.
|
|
||||||
*/
|
|
||||||
public static void rotateBounds(Rect inOutBounds, Rect parentBounds, int delta) {
|
|
||||||
int rdelta = ((delta % 4) + 4) % 4;
|
|
||||||
int origLeft = inOutBounds.left;
|
|
||||||
switch (rdelta) {
|
|
||||||
case 0:
|
|
||||||
return;
|
|
||||||
case 1:
|
|
||||||
inOutBounds.left = inOutBounds.top;
|
|
||||||
inOutBounds.top = parentBounds.right - inOutBounds.right;
|
|
||||||
inOutBounds.right = inOutBounds.bottom;
|
|
||||||
inOutBounds.bottom = parentBounds.right - origLeft;
|
|
||||||
return;
|
|
||||||
case 2:
|
|
||||||
inOutBounds.left = parentBounds.right - inOutBounds.right;
|
|
||||||
inOutBounds.right = parentBounds.right - origLeft;
|
|
||||||
return;
|
|
||||||
case 3:
|
|
||||||
inOutBounds.left = parentBounds.bottom - inOutBounds.bottom;
|
|
||||||
inOutBounds.bottom = inOutBounds.right;
|
|
||||||
inOutBounds.right = parentBounds.bottom - inOutBounds.top;
|
|
||||||
inOutBounds.top = origLeft;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the stable insets if we already have the non-decor insets.
|
* Calculates the stable insets if we already have the non-decor insets.
|
||||||
*/
|
*/
|
||||||
@@ -359,8 +328,7 @@ public class DisplayLayout {
|
|||||||
if (rotation == ROTATION_0) {
|
if (rotation == ROTATION_0) {
|
||||||
return computeSafeInsets(cutout, displayWidth, displayHeight);
|
return computeSafeInsets(cutout, displayWidth, displayHeight);
|
||||||
}
|
}
|
||||||
final Insets waterfallInsets =
|
final Insets waterfallInsets = rotateInsets(cutout.getWaterfallInsets(), rotation);
|
||||||
RotationUtils.rotateInsets(cutout.getWaterfallInsets(), rotation);
|
|
||||||
final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
|
final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
|
||||||
Rect[] cutoutRects = cutout.getBoundingRectsAll();
|
Rect[] cutoutRects = cutout.getBoundingRectsAll();
|
||||||
final Rect[] newBounds = new Rect[cutoutRects.length];
|
final Rect[] newBounds = new Rect[cutoutRects.length];
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.wm.shell.legacysplitscreen;
|
|||||||
|
|
||||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||||
|
import static android.util.RotationUtils.rotateBounds;
|
||||||
import static android.view.WindowManager.DOCKED_BOTTOM;
|
import static android.view.WindowManager.DOCKED_BOTTOM;
|
||||||
import static android.view.WindowManager.DOCKED_INVALID;
|
import static android.view.WindowManager.DOCKED_INVALID;
|
||||||
import static android.view.WindowManager.DOCKED_LEFT;
|
import static android.view.WindowManager.DOCKED_LEFT;
|
||||||
@@ -244,7 +245,7 @@ public class LegacySplitDisplayLayout {
|
|||||||
DividerSnapAlgorithm snap = initSnapAlgorithmForRotation(context, tmpDL, dividerSize);
|
DividerSnapAlgorithm snap = initSnapAlgorithmForRotation(context, tmpDL, dividerSize);
|
||||||
|
|
||||||
tmpRect.set(bounds);
|
tmpRect.set(bounds);
|
||||||
DisplayLayout.rotateBounds(tmpRect, displayRect, rotation - dl.rotation());
|
rotateBounds(tmpRect, displayRect, dl.rotation(), rotation);
|
||||||
rotatedDisplayRect.set(0, 0, tmpDL.width(), tmpDL.height());
|
rotatedDisplayRect.set(0, 0, tmpDL.width(), tmpDL.height());
|
||||||
final int dockSide = getPrimarySplitSide(tmpRect, rotatedDisplayRect,
|
final int dockSide = getPrimarySplitSide(tmpRect, rotatedDisplayRect,
|
||||||
tmpDL.getOrientation());
|
tmpDL.getOrientation());
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.wm.shell.pip;
|
package com.android.wm.shell.pip;
|
||||||
|
|
||||||
|
import static android.util.RotationUtils.rotateBounds;
|
||||||
import static android.view.Surface.ROTATION_270;
|
import static android.view.Surface.ROTATION_270;
|
||||||
import static android.view.Surface.ROTATION_90;
|
import static android.view.Surface.ROTATION_90;
|
||||||
|
|
||||||
@@ -33,7 +34,6 @@ import android.view.SurfaceControl;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
|
import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
|
||||||
import com.android.wm.shell.animation.Interpolators;
|
import com.android.wm.shell.animation.Interpolators;
|
||||||
import com.android.wm.shell.common.DisplayLayout;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -448,7 +448,7 @@ public class PipAnimationController {
|
|||||||
// Rotate the end bounds according to the rotation delta because the display will
|
// Rotate the end bounds according to the rotation delta because the display will
|
||||||
// be rotated to the same orientation.
|
// be rotated to the same orientation.
|
||||||
rotatedEndRect = new Rect(endValue);
|
rotatedEndRect = new Rect(endValue);
|
||||||
DisplayLayout.rotateBounds(rotatedEndRect, endValue, rotationDelta);
|
rotateBounds(rotatedEndRect, endValue, rotationDelta);
|
||||||
} else {
|
} else {
|
||||||
rotatedEndRect = null;
|
rotatedEndRect = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ import com.android.internal.R;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link DisplayLayout}.
|
||||||
|
*
|
||||||
|
* Build/Install/Run:
|
||||||
|
* atest WMShellUnitTests:DisplayLayoutTest
|
||||||
|
*/
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class DisplayLayoutTest {
|
public class DisplayLayoutTest {
|
||||||
|
|
||||||
@@ -70,18 +76,6 @@ public class DisplayLayoutTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRotate() {
|
public void testRotate() {
|
||||||
// Basic rotate utility
|
// Basic rotate utility
|
||||||
Rect testParent = new Rect(0, 0, 1000, 600);
|
|
||||||
Rect testInner = new Rect(40, 20, 120, 80);
|
|
||||||
Rect testResult = new Rect(testInner);
|
|
||||||
DisplayLayout.rotateBounds(testResult, testParent, 1);
|
|
||||||
assertEquals(new Rect(20, 880, 80, 960), testResult);
|
|
||||||
testResult.set(testInner);
|
|
||||||
DisplayLayout.rotateBounds(testResult, testParent, 2);
|
|
||||||
assertEquals(new Rect(880, 20, 960, 80), testResult);
|
|
||||||
testResult.set(testInner);
|
|
||||||
DisplayLayout.rotateBounds(testResult, testParent, 3);
|
|
||||||
assertEquals(new Rect(520, 40, 580, 120), testResult);
|
|
||||||
|
|
||||||
Resources res = createResources(40, 50, false, 30, 40);
|
Resources res = createResources(40, 50, false, 30, 40);
|
||||||
DisplayInfo info = createDisplayInfo(1000, 1500, 60, ROTATION_0);
|
DisplayInfo info = createDisplayInfo(1000, 1500, 60, ROTATION_0);
|
||||||
DisplayLayout dl = new DisplayLayout(info, res, true, true);
|
DisplayLayout dl = new DisplayLayout(info, res, true, true);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.wm.shell.pip;
|
package com.android.wm.shell.pip;
|
||||||
|
|
||||||
|
import static android.util.RotationUtils.rotateBounds;
|
||||||
import static android.view.Surface.ROTATION_0;
|
import static android.view.Surface.ROTATION_0;
|
||||||
import static android.view.Surface.ROTATION_90;
|
import static android.view.Surface.ROTATION_90;
|
||||||
|
|
||||||
@@ -37,7 +38,6 @@ import android.view.SurfaceControl;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.wm.shell.ShellTestCase;
|
import com.android.wm.shell.ShellTestCase;
|
||||||
import com.android.wm.shell.common.DisplayLayout;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -141,7 +141,7 @@ public class PipAnimationControllerTest extends ShellTestCase {
|
|||||||
// Apply fraction 1 to compute the end value.
|
// Apply fraction 1 to compute the end value.
|
||||||
animator.applySurfaceControlTransaction(mLeash, new DummySurfaceControlTx(), 1);
|
animator.applySurfaceControlTransaction(mLeash, new DummySurfaceControlTx(), 1);
|
||||||
final Rect rotatedEndBounds = new Rect(endBounds);
|
final Rect rotatedEndBounds = new Rect(endBounds);
|
||||||
DisplayLayout.rotateBounds(rotatedEndBounds, endBounds, ROTATION_90);
|
rotateBounds(rotatedEndBounds, endBounds, ROTATION_90);
|
||||||
|
|
||||||
assertEquals("Expect 90 degree rotated bounds", rotatedEndBounds, animator.mCurrentValue);
|
assertEquals("Expect 90 degree rotated bounds", rotatedEndBounds, animator.mCurrentValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
|
|||||||
import static android.os.Build.VERSION_CODES.N;
|
import static android.os.Build.VERSION_CODES.N;
|
||||||
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
||||||
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
|
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
|
||||||
|
import static android.util.RotationUtils.deltaRotation;
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
|
import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
|
||||||
import static android.view.Display.FLAG_PRIVATE;
|
import static android.view.Display.FLAG_PRIVATE;
|
||||||
@@ -47,7 +48,6 @@ import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
|
|||||||
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||||
import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
|
import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
|
||||||
import static android.view.Surface.ROTATION_0;
|
import static android.view.Surface.ROTATION_0;
|
||||||
import static android.view.Surface.ROTATION_180;
|
|
||||||
import static android.view.Surface.ROTATION_270;
|
import static android.view.Surface.ROTATION_270;
|
||||||
import static android.view.Surface.ROTATION_90;
|
import static android.view.Surface.ROTATION_90;
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
@@ -157,10 +157,8 @@ import android.content.res.CompatibilityInfo;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Insets;
|
import android.graphics.Insets;
|
||||||
import android.graphics.Matrix;
|
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.graphics.Region.Op;
|
import android.graphics.Region.Op;
|
||||||
import android.hardware.HardwareBuffer;
|
import android.hardware.HardwareBuffer;
|
||||||
@@ -205,6 +203,7 @@ import android.view.MagnificationSpec;
|
|||||||
import android.view.RemoteAnimationDefinition;
|
import android.view.RemoteAnimationDefinition;
|
||||||
import android.view.RoundedCorners;
|
import android.view.RoundedCorners;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
import android.view.Surface.Rotation;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.view.SurfaceControl.Transaction;
|
import android.view.SurfaceControl.Transaction;
|
||||||
import android.view.SurfaceSession;
|
import android.view.SurfaceSession;
|
||||||
@@ -448,8 +447,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
/** Save allocating when calculating rects */
|
/** Save allocating when calculating rects */
|
||||||
private final Rect mTmpRect = new Rect();
|
private final Rect mTmpRect = new Rect();
|
||||||
private final Rect mTmpRect2 = new Rect();
|
private final Rect mTmpRect2 = new Rect();
|
||||||
private final RectF mTmpRectF = new RectF();
|
|
||||||
private final Matrix mTmpMatrix = new Matrix();
|
|
||||||
private final Region mTmpRegion = new Region();
|
private final Region mTmpRegion = new Region();
|
||||||
|
|
||||||
/** Used for handing back size of display */
|
/** Used for handing back size of display */
|
||||||
@@ -1288,7 +1285,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
return mInsetsPolicy;
|
return mInsetsPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Surface.Rotation
|
@Rotation
|
||||||
int getRotation() {
|
int getRotation() {
|
||||||
return mDisplayRotation.getRotation();
|
return mDisplayRotation.getRotation();
|
||||||
}
|
}
|
||||||
@@ -1478,7 +1475,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
* Returns a valid rotation if the activity can use different orientation than the display.
|
* Returns a valid rotation if the activity can use different orientation than the display.
|
||||||
* Otherwise {@link #ROTATION_UNDEFINED}.
|
* Otherwise {@link #ROTATION_UNDEFINED}.
|
||||||
*/
|
*/
|
||||||
@Surface.Rotation
|
@Rotation
|
||||||
int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
|
int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
|
||||||
if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
|
if (!WindowManagerService.ENABLE_FIXED_ROTATION_TRANSFORM) {
|
||||||
return ROTATION_UNDEFINED;
|
return ROTATION_UNDEFINED;
|
||||||
@@ -1613,7 +1610,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
* Sets the provided record to {@link #mFixedRotationLaunchingApp} if possible to apply fixed
|
* Sets the provided record to {@link #mFixedRotationLaunchingApp} if possible to apply fixed
|
||||||
* rotation transform to it and indicate that the display may be rotated after it is launched.
|
* rotation transform to it and indicate that the display may be rotated after it is launched.
|
||||||
*/
|
*/
|
||||||
void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Surface.Rotation int rotation) {
|
void setFixedRotationLaunchingApp(@NonNull ActivityRecord r, @Rotation int rotation) {
|
||||||
final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
|
final WindowToken prevRotatedLaunchingApp = mFixedRotationLaunchingApp;
|
||||||
if (prevRotatedLaunchingApp == r
|
if (prevRotatedLaunchingApp == r
|
||||||
&& r.getWindowConfiguration().getRotation() == rotation) {
|
&& r.getWindowConfiguration().getRotation() == rotation) {
|
||||||
@@ -2950,27 +2947,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
forAllRootTasks(Task::prepareFreezingTaskBounds);
|
forAllRootTasks(Task::prepareFreezingTaskBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rotateBounds(int oldRotation, int newRotation, Rect bounds) {
|
void rotateBounds(@Rotation int oldRotation, @Rotation int newRotation, Rect inOutBounds) {
|
||||||
getBounds(mTmpRect, newRotation);
|
// Get display bounds on oldRotation as parent bounds for the rotation.
|
||||||
rotateBounds(mTmpRect, oldRotation, newRotation, bounds);
|
getBounds(mTmpRect, oldRotation);
|
||||||
}
|
RotationUtils.rotateBounds(inOutBounds, mTmpRect, oldRotation, newRotation);
|
||||||
|
|
||||||
void rotateBounds(Rect parentBounds, int oldRotation, int newRotation, Rect bounds) {
|
|
||||||
// Compute a transform matrix to undo the coordinate space transformation,
|
|
||||||
// and present the window at the same physical position it previously occupied.
|
|
||||||
final int deltaRotation = deltaRotation(newRotation, oldRotation);
|
|
||||||
createRotationMatrix(
|
|
||||||
deltaRotation, parentBounds.width(), parentBounds.height(), mTmpMatrix);
|
|
||||||
|
|
||||||
mTmpRectF.set(bounds);
|
|
||||||
mTmpMatrix.mapRect(mTmpRectF);
|
|
||||||
mTmpRectF.round(bounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int deltaRotation(int oldRotation, int newRotation) {
|
|
||||||
int delta = newRotation - oldRotation;
|
|
||||||
if (delta < 0) delta += 4;
|
|
||||||
return delta;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) {
|
public void setRotationAnimation(ScreenRotationAnimation screenRotationAnimation) {
|
||||||
@@ -2984,35 +2964,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
return mScreenRotationAnimation;
|
return mScreenRotationAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createRotationMatrix(int rotation, float displayWidth, float displayHeight,
|
|
||||||
Matrix outMatrix) {
|
|
||||||
// For rotations without Z-ordering we don't need the target rectangle's position.
|
|
||||||
createRotationMatrix(rotation, 0 /* rectLeft */, 0 /* rectTop */, displayWidth,
|
|
||||||
displayHeight, outMatrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void createRotationMatrix(int rotation, float rectLeft, float rectTop,
|
|
||||||
float displayWidth, float displayHeight, Matrix outMatrix) {
|
|
||||||
switch (rotation) {
|
|
||||||
case ROTATION_0:
|
|
||||||
outMatrix.reset();
|
|
||||||
break;
|
|
||||||
case ROTATION_270:
|
|
||||||
outMatrix.setRotate(270, 0, 0);
|
|
||||||
outMatrix.postTranslate(0, displayHeight);
|
|
||||||
outMatrix.postTranslate(rectTop, 0);
|
|
||||||
break;
|
|
||||||
case ROTATION_180:
|
|
||||||
outMatrix.reset();
|
|
||||||
break;
|
|
||||||
case ROTATION_90:
|
|
||||||
outMatrix.setRotate(90, 0, 0);
|
|
||||||
outMatrix.postTranslate(displayWidth, 0);
|
|
||||||
outMatrix.postTranslate(-rectTop, rectLeft);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dumpDebug(ProtoOutputStream proto, long fieldId,
|
public void dumpDebug(ProtoOutputStream proto, long fieldId,
|
||||||
@WindowTraceLogLevel int logLevel) {
|
@WindowTraceLogLevel int logLevel) {
|
||||||
@@ -4287,17 +4238,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
out.set(left, top, left + width, top + height);
|
out.set(left, top, left + width, top + height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getBounds(Rect out, int orientation) {
|
private void getBounds(Rect out, @Rotation int rotation) {
|
||||||
getBounds(out);
|
getBounds(out);
|
||||||
|
|
||||||
// Rotate the Rect if needed.
|
// Rotate the Rect if needed.
|
||||||
final int currentRotation = mDisplayInfo.rotation;
|
final int currentRotation = mDisplayInfo.rotation;
|
||||||
final int rotationDelta = deltaRotation(currentRotation, orientation);
|
final int rotationDelta = deltaRotation(currentRotation, rotation);
|
||||||
if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
|
if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) {
|
||||||
createRotationMatrix(rotationDelta, mBaseDisplayWidth, mBaseDisplayHeight, mTmpMatrix);
|
out.set(0, 0, out.height(), out.width());
|
||||||
mTmpRectF.set(out);
|
|
||||||
mTmpMatrix.mapRect(mTmpRectF);
|
|
||||||
mTmpRectF.round(out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
|
|||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
|
||||||
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
|
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
|
||||||
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
|
import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
|
||||||
|
import static android.util.RotationUtils.deltaRotation;
|
||||||
|
import static android.util.RotationUtils.rotateBounds;
|
||||||
import static android.view.Display.TYPE_INTERNAL;
|
import static android.view.Display.TYPE_INTERNAL;
|
||||||
import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES;
|
import static android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES;
|
||||||
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
|
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
|
||||||
@@ -1046,11 +1048,17 @@ public class DisplayPolicy {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get displayFrames bounds
|
// Get displayFrames bounds as it is on WindowState's rotation.
|
||||||
sTmpDisplayFrameBounds.set(0, 0, displayFrames.mDisplayWidth, displayFrames.mDisplayHeight);
|
final int deltaRotation = deltaRotation(windowRotation, displayFrames.mRotation);
|
||||||
|
if (deltaRotation == Surface.ROTATION_90 || deltaRotation == Surface.ROTATION_270) {
|
||||||
|
sTmpDisplayFrameBounds.set(
|
||||||
|
0, 0, displayFrames.mDisplayHeight, displayFrames.mDisplayWidth);
|
||||||
|
} else {
|
||||||
|
sTmpDisplayFrameBounds.set(
|
||||||
|
0, 0, displayFrames.mDisplayWidth, displayFrames.mDisplayHeight);
|
||||||
|
}
|
||||||
// Rotate the WindowState's bounds based on the displayFrames rotation
|
// Rotate the WindowState's bounds based on the displayFrames rotation
|
||||||
mDisplayContent.rotateBounds(sTmpDisplayFrameBounds, windowRotation,
|
rotateBounds(outBounds, sTmpDisplayFrameBounds, deltaRotation);
|
||||||
displayFrames.mRotation, outBounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||||
|
import static android.util.RotationUtils.deltaRotation;
|
||||||
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
|
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
|
||||||
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
|
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
|
||||||
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
|
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE;
|
||||||
@@ -475,7 +476,7 @@ public class DisplayRotation {
|
|||||||
"Display id=%d rotation changed to %d from %d, lastOrientation=%d",
|
"Display id=%d rotation changed to %d from %d, lastOrientation=%d",
|
||||||
displayId, rotation, oldRotation, lastOrientation);
|
displayId, rotation, oldRotation, lastOrientation);
|
||||||
|
|
||||||
if (DisplayContent.deltaRotation(rotation, oldRotation) != 2) {
|
if (deltaRotation(oldRotation, rotation) != Surface.ROTATION_180) {
|
||||||
mDisplayContent.mWaitingForConfig = true;
|
mDisplayContent.mWaitingForConfig = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
||||||
|
import static android.util.RotationUtils.deltaRotation;
|
||||||
|
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
|
||||||
@@ -174,7 +175,7 @@ class ScreenRotationAnimation {
|
|||||||
// apply rotation animation because there should be a top app shown as rotated. So the
|
// apply rotation animation because there should be a top app shown as rotated. So the
|
||||||
// specified original rotation customizes the direction of animation to have better look
|
// specified original rotation customizes the direction of animation to have better look
|
||||||
// when restoring the rotated app to the same rotation as current display.
|
// when restoring the rotated app to the same rotation as current display.
|
||||||
final int delta = DisplayContent.deltaRotation(originalRotation, realOriginalRotation);
|
final int delta = deltaRotation(originalRotation, realOriginalRotation);
|
||||||
final boolean flipped = delta == Surface.ROTATION_90 || delta == Surface.ROTATION_270;
|
final boolean flipped = delta == Surface.ROTATION_90 || delta == Surface.ROTATION_270;
|
||||||
mOriginalWidth = flipped ? originalHeight : originalWidth;
|
mOriginalWidth = flipped ? originalHeight : originalWidth;
|
||||||
mOriginalHeight = flipped ? originalWidth : originalHeight;
|
mOriginalHeight = flipped ? originalWidth : originalHeight;
|
||||||
@@ -330,7 +331,7 @@ class ScreenRotationAnimation {
|
|||||||
// Compute the transformation matrix that must be applied
|
// Compute the transformation matrix that must be applied
|
||||||
// to the snapshot to make it stay in the same original position
|
// to the snapshot to make it stay in the same original position
|
||||||
// with the current screen rotation.
|
// with the current screen rotation.
|
||||||
int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0);
|
int delta = deltaRotation(rotation, Surface.ROTATION_0);
|
||||||
RotationAnimationUtils.createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
|
RotationAnimationUtils.createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);
|
||||||
|
|
||||||
setRotationTransform(t, mSnapshotInitialMatrix);
|
setRotationTransform(t, mSnapshotInitialMatrix);
|
||||||
@@ -352,8 +353,7 @@ class ScreenRotationAnimation {
|
|||||||
mStarted = true;
|
mStarted = true;
|
||||||
|
|
||||||
// Figure out how the screen has moved from the original rotation.
|
// Figure out how the screen has moved from the original rotation.
|
||||||
int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation);
|
int delta = deltaRotation(mCurRotation, mOriginalRotation);
|
||||||
|
|
||||||
|
|
||||||
final boolean customAnim;
|
final boolean customAnim;
|
||||||
if (exitAnim != 0 && enterAnim != 0) {
|
if (exitAnim != 0 && enterAnim != 0) {
|
||||||
|
|||||||
@@ -2361,9 +2361,7 @@ class Task extends WindowContainer<WindowContainer> {
|
|||||||
final int newRotation = getWindowConfiguration().getRotation();
|
final int newRotation = getWindowConfiguration().getRotation();
|
||||||
final boolean rotationChanged = prevRotation != newRotation;
|
final boolean rotationChanged = prevRotation != newRotation;
|
||||||
if (rotationChanged) {
|
if (rotationChanged) {
|
||||||
mDisplayContent.rotateBounds(
|
mDisplayContent.rotateBounds(prevRotation, newRotation, newBounds);
|
||||||
newParentConfig.windowConfiguration.getBounds(), prevRotation, newRotation,
|
|
||||||
newBounds);
|
|
||||||
setBounds(newBounds);
|
setBounds(newBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
|||||||
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
||||||
import static android.view.Surface.ROTATION_0;
|
import static android.view.Surface.ROTATION_0;
|
||||||
import static android.view.Surface.ROTATION_180;
|
import static android.view.Surface.ROTATION_180;
|
||||||
|
import static android.view.Surface.ROTATION_270;
|
||||||
import static android.view.Surface.ROTATION_90;
|
import static android.view.Surface.ROTATION_90;
|
||||||
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
|
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
|
||||||
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
|
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
|
||||||
@@ -1845,6 +1846,37 @@ public class DisplayContentTests extends WindowTestsBase {
|
|||||||
verify(t).show(mDisplayContent.mImeScreenshot);
|
verify(t).show(mDisplayContent.mImeScreenshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRotateBounds_keepSamePhysicalPosition() {
|
||||||
|
final DisplayContent dc =
|
||||||
|
new TestDisplayContent.Builder(mAtm, 1000, 2000).build();
|
||||||
|
final Rect initBounds = new Rect(0, 0, 700, 1500);
|
||||||
|
final Rect rotateBounds = new Rect(initBounds);
|
||||||
|
|
||||||
|
// Rotate from 0 to 0
|
||||||
|
dc.rotateBounds(ROTATION_0, ROTATION_0, rotateBounds);
|
||||||
|
|
||||||
|
assertEquals(new Rect(0, 0, 700, 1500), rotateBounds);
|
||||||
|
|
||||||
|
// Rotate from 0 to 90
|
||||||
|
rotateBounds.set(initBounds);
|
||||||
|
dc.rotateBounds(ROTATION_0, ROTATION_90, rotateBounds);
|
||||||
|
|
||||||
|
assertEquals(new Rect(0, 300, 1500, 1000), rotateBounds);
|
||||||
|
|
||||||
|
// Rotate from 0 to 180
|
||||||
|
rotateBounds.set(initBounds);
|
||||||
|
dc.rotateBounds(ROTATION_0, ROTATION_180, rotateBounds);
|
||||||
|
|
||||||
|
assertEquals(new Rect(300, 500, 1000, 2000), rotateBounds);
|
||||||
|
|
||||||
|
// Rotate from 0 to 270
|
||||||
|
rotateBounds.set(initBounds);
|
||||||
|
dc.rotateBounds(ROTATION_0, ROTATION_270, rotateBounds);
|
||||||
|
|
||||||
|
assertEquals(new Rect(500, 0, 2000, 700), rotateBounds);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isOptionsPanelAtRight(int displayId) {
|
private boolean isOptionsPanelAtRight(int displayId) {
|
||||||
return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
|
return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user