Add force default orientation.
Devices can be configured to remain in their default landscape or
portrait orientation by setting config_forceDefaultOrientation true
in overlay/.../values/config.xml.
Activities that desire to run in the non-default orientation are
supported by creating a logical display within the physical display.
Transitions to and from the activity perform a crossfade rather than
the normal rotation animation.
Also, improve SurfaceTrace debug output.
Fixes bug 9695710.
Change-Id: I053e136cd2b9ae200028595f245b6ada5927cfe9
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index b2fbec1..7d90858 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -26,6 +26,7 @@
import android.graphics.Rect;
import android.util.Slog;
import android.view.Display;
+import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
@@ -43,7 +44,7 @@
static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;
final Context mContext;
- final Display mDisplay;
+ final DisplayContent mDisplayContent;
SurfaceControl mSurfaceControl;
BlackFrame mCustomBlackFrame;
BlackFrame mExitingBlackFrame;
@@ -53,6 +54,8 @@
int mOriginalRotation;
int mOriginalWidth, mOriginalHeight;
int mCurRotation;
+ Rect mOriginalDisplayRect = new Rect();
+ Rect mCurrentDisplayRect = new Rect();
// For all animations, "exit" is for the UI elements that are going
// away (that is the snapshot of the old screen), and "enter" is for
@@ -108,6 +111,7 @@
boolean mAnimRunning;
boolean mFinishAnimReady;
long mFinishAnimStartTime;
+ boolean mForceDefaultOrientation;
final Matrix mFrameInitialMatrix = new Matrix();
final Matrix mSnapshotInitialMatrix = new Matrix();
@@ -186,14 +190,35 @@
pw.print(prefix); pw.print("mExitFrameFinalMatrix=");
mExitFrameFinalMatrix.printShortString(pw);
pw.println();
+ pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation);
+ if (mForceDefaultOrientation) {
+ pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString());
+ pw.print(" mCurrentDisplayRect="); pw.println(mCurrentDisplayRect.toShortString());
+ }
}
- public ScreenRotationAnimation(Context context, Display display, SurfaceSession session,
- boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
+ public ScreenRotationAnimation(Context context, DisplayContent displayContent,
+ SurfaceSession session, boolean inTransaction, boolean forceDefaultOrientation) {
mContext = context;
- mDisplay = display;
+ mDisplayContent = displayContent;
+ displayContent.getLogicalDisplayRect(mOriginalDisplayRect);
// Screenshot does NOT include rotation!
+ final Display display = displayContent.getDisplay();
+ int originalRotation = display.getRotation();
+ final int originalWidth;
+ final int originalHeight;
+ DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ if (forceDefaultOrientation) {
+ // Emulated orientation.
+ mForceDefaultOrientation = true;
+ originalWidth = displayContent.mBaseDisplayWidth;
+ originalHeight = displayContent.mBaseDisplayHeight;
+ } else {
+ // Normal situation
+ originalWidth = displayInfo.logicalWidth;
+ originalHeight = displayInfo.logicalHeight;
+ }
if (originalRotation == Surface.ROTATION_90
|| originalRotation == Surface.ROTATION_270) {
mWidth = originalHeight;
@@ -219,6 +244,8 @@
mSurfaceControl = new SurfaceTrace(session, "ScreenshotSurface",
mWidth, mHeight,
PixelFormat.OPAQUE, SurfaceControl.HIDDEN);
+ Slog.w(TAG, "ScreenRotationAnimation ctor: displayOffset="
+ + mOriginalDisplayRect.toShortString());
} else {
mSurfaceControl = new SurfaceControl(session, "ScreenshotSurface",
mWidth, mHeight,
@@ -230,7 +257,7 @@
// FIXME: we should use the proper display
SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), sur);
- mSurfaceControl.setLayerStack(mDisplay.getLayerStack());
+ mSurfaceControl.setLayerStack(display.getLayerStack());
mSurfaceControl.setLayer(FREEZE_LAYER + 1);
mSurfaceControl.setAlpha(0);
mSurfaceControl.show();
@@ -266,7 +293,14 @@
private void setSnapshotTransformInTransaction(Matrix matrix, float alpha) {
if (mSurfaceControl != null) {
matrix.getValues(mTmpFloats);
- mSurfaceControl.setPosition(mTmpFloats[Matrix.MTRANS_X], mTmpFloats[Matrix.MTRANS_Y]);
+ float x = mTmpFloats[Matrix.MTRANS_X];
+ float y = mTmpFloats[Matrix.MTRANS_Y];
+ if (mForceDefaultOrientation) {
+ mDisplayContent.getLogicalDisplayRect(mCurrentDisplayRect);
+ x -= mCurrentDisplayRect.left;
+ y -= mCurrentDisplayRect.top;
+ }
+ mSurfaceControl.setPosition(x, y);
mSurfaceControl.setMatrix(
mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
@@ -491,7 +525,7 @@
mRotateFrameAnimation.scaleCurrentDuration(animationScale);
}
- final int layerStack = mDisplay.getLayerStack();
+ final int layerStack = mDisplayContent.getDisplay().getLayerStack();
if (USE_CUSTOM_BLACK_FRAME && mCustomBlackFrame == null) {
if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i(
WindowManagerService.TAG,
@@ -511,7 +545,7 @@
mOriginalWidth*2, mOriginalHeight*2);
Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
mCustomBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 3,
- layerStack);
+ layerStack, false);
mCustomBlackFrame.setMatrix(mFrameInitialMatrix);
} catch (SurfaceControl.OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate black surface", e);
@@ -537,11 +571,21 @@
// we were last in.
createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix);
- Rect outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
- mOriginalWidth*2, mOriginalHeight*2);
- Rect inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
+ final Rect outer;
+ final Rect inner;
+ if (mForceDefaultOrientation) {
+ // Going from a smaller Display to a larger Display, add curtains to sides
+ // or top and bottom. Going from a larger to smaller display will result in
+ // no BlackSurfaces being constructed.
+ outer = mCurrentDisplayRect;
+ inner = mOriginalDisplayRect;
+ } else {
+ outer = new Rect(-mOriginalWidth*1, -mOriginalHeight*1,
+ mOriginalWidth*2, mOriginalHeight*2);
+ inner = new Rect(0, 0, mOriginalWidth, mOriginalHeight);
+ }
mExitingBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER + 2,
- layerStack);
+ layerStack, mForceDefaultOrientation);
mExitingBlackFrame.setMatrix(mFrameInitialMatrix);
} catch (SurfaceControl.OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate black surface", e);
@@ -564,7 +608,7 @@
finalWidth*2, finalHeight*2);
Rect inner = new Rect(0, 0, finalWidth, finalHeight);
mEnteringBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER,
- layerStack);
+ layerStack, false);
} catch (SurfaceControl.OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate black surface", e);
} finally {
@@ -888,6 +932,9 @@
} else {
mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix);
mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix);
+ if (mForceDefaultOrientation) {
+ mExitingBlackFrame.setAlpha(mExitTransformation.getAlpha());
+ }
}
}