diff options
author | Craig Mautner <cmautner@google.com> | 2013-08-01 10:06:34 -0700 |
---|---|---|
committer | Craig Mautner <cmautner@google.com> | 2013-08-02 16:23:58 -0700 |
commit | 46ac6fa614131d567bed93d1d2067d765ecef85d (patch) | |
tree | 720caf051afb40d98ec279bc19022efc5037ffa5 /services | |
parent | cb92a8d9428c2e4a9f038cd5f10e9d61bf265cd4 (diff) | |
download | frameworks_base-46ac6fa614131d567bed93d1d2067d765ecef85d.zip frameworks_base-46ac6fa614131d567bed93d1d2067d765ecef85d.tar.gz frameworks_base-46ac6fa614131d567bed93d1d2067d765ecef85d.tar.bz2 |
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
Diffstat (limited to 'services')
5 files changed, 116 insertions, 48 deletions
diff --git a/services/java/com/android/server/wm/BlackFrame.java b/services/java/com/android/server/wm/BlackFrame.java index 774b165..737d854 100644 --- a/services/java/com/android/server/wm/BlackFrame.java +++ b/services/java/com/android/server/wm/BlackFrame.java @@ -22,7 +22,6 @@ import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.Rect; import android.util.Slog; -import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceSession; @@ -62,6 +61,10 @@ public class BlackFrame { " BLACK " + surface + ": CREATE layer=" + layer); } + void setAlpha(float alpha) { + surface.setAlpha(alpha); + } + void setMatrix(Matrix matrix) { mTmpMatrix.setTranslate(left, top); mTmpMatrix.postConcat(matrix); @@ -93,6 +96,8 @@ public class BlackFrame { final float[] mTmpFloats = new float[9]; final BlackSurface[] mBlackSurfaces = new BlackSurface[4]; + final boolean mForceDefaultOrientation; + public void printTo(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("Outer: "); mOuterRect.printShortString(pw); pw.print(" / Inner: "); mInnerRect.printShortString(pw); @@ -106,10 +111,12 @@ public class BlackFrame { } } - public BlackFrame(SurfaceSession session, Rect outer, Rect inner, - int layer, final int layerStack) throws SurfaceControl.OutOfResourcesException { + public BlackFrame(SurfaceSession session, Rect outer, Rect inner, int layer, int layerStack, + boolean forceDefaultOrientation) throws SurfaceControl.OutOfResourcesException { boolean success = false; + mForceDefaultOrientation = forceDefaultOrientation; + mOuterRect = new Rect(outer); mInnerRect = new Rect(inner); try { @@ -162,6 +169,14 @@ public class BlackFrame { } } + public void setAlpha(float alpha) { + for (int i=0; i<mBlackSurfaces.length; i++) { + if (mBlackSurfaces[i] != null) { + mBlackSurfaces[i].setAlpha(alpha); + } + } + } + public void setMatrix(Matrix matrix) { for (int i=0; i<mBlackSurfaces.length; i++) { if (mBlackSurfaces[i] != null) { diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java index 4f699ae..74676ca 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/java/com/android/server/wm/DisplayContent.java @@ -176,10 +176,20 @@ class DisplayContent { return mHomeStack; } - public void updateDisplayInfo() { + void updateDisplayInfo() { mDisplay.getDisplayInfo(mDisplayInfo); } + void getLogicalDisplayRect(Rect out) { + updateDisplayInfo(); + // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked. + int width = mDisplayInfo.logicalWidth; + int left = (mBaseDisplayWidth - width) / 2; + int height = mDisplayInfo.logicalHeight; + int top = (mBaseDisplayHeight - height) / 2; + out.set(left, top, left + width, top + height); + } + /** @return The number of tokens in all of the Tasks on this display. */ int numTokens() { getTasks(); 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.PixelFormat; 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 @@ class ScreenRotationAnimation { 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 @@ class ScreenRotationAnimation { 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 @@ class ScreenRotationAnimation { boolean mAnimRunning; boolean mFinishAnimReady; long mFinishAnimStartTime; + boolean mForceDefaultOrientation; final Matrix mFrameInitialMatrix = new Matrix(); final Matrix mSnapshotInitialMatrix = new Matrix(); @@ -186,14 +190,35 @@ class ScreenRotationAnimation { 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 @@ class ScreenRotationAnimation { 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 @@ class ScreenRotationAnimation { // 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 @@ class ScreenRotationAnimation { 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 @@ class ScreenRotationAnimation { 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 @@ class ScreenRotationAnimation { 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 @@ class ScreenRotationAnimation { // 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 @@ class ScreenRotationAnimation { 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 @@ class ScreenRotationAnimation { } else { mExitFrameFinalMatrix.setConcat(mExitTransformation.getMatrix(), mFrameInitialMatrix); mExitingBlackFrame.setMatrix(mExitFrameFinalMatrix); + if (mForceDefaultOrientation) { + mExitingBlackFrame.setAlpha(mExitTransformation.getAlpha()); + } } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 9a5026d..4636a80 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -9903,11 +9903,8 @@ public class WindowManagerService extends IWindowManager.Stub } // TODO(multidisplay): rotation on main screen only. - final Display display = displayContent.getDisplay(); - final DisplayInfo displayInfo = displayContent.getDisplayInfo(); - screenRotationAnimation = new ScreenRotationAnimation(mContext, - display, mFxSession, inTransaction, displayInfo.logicalWidth, - displayInfo.logicalHeight, display.getRotation()); + screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent, + mFxSession, inTransaction, mPolicy.isDefaultOrientationForced()); mAnimator.setScreenRotationAnimationLocked(displayId, screenRotationAnimation); } } diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index a52d85c..6fa9cd0 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -494,22 +494,22 @@ class WindowStateAnimator { @Override public void setAlpha(float alpha) { - super.setAlpha(alpha); - if (alpha != mSurfaceTraceAlpha) { - mSurfaceTraceAlpha = alpha; - Slog.v(SURFACE_TAG, "setAlpha: " + this + ". Called by " + if (mSurfaceTraceAlpha != alpha) { + Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this + ". Called by " + Debug.getCallers(3)); + mSurfaceTraceAlpha = alpha; } + super.setAlpha(alpha); } @Override public void setLayer(int zorder) { - super.setLayer(zorder); if (zorder != mLayer) { - mLayer = zorder; - Slog.v(SURFACE_TAG, "setLayer: " + this + ". Called by " + Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this + ". Called by " + Debug.getCallers(3)); + mLayer = zorder; } + super.setLayer(zorder); sSurfaces.remove(this); int i; @@ -524,69 +524,68 @@ class WindowStateAnimator { @Override public void setPosition(float x, float y) { - super.setPosition(x, y); if (x != mPosition.x || y != mPosition.y) { + Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:" + this + + ". Called by " + Debug.getCallers(3)); mPosition.set(x, y); - Slog.v(SURFACE_TAG, "setPosition: " + this + ". Called by " - + Debug.getCallers(3)); } + super.setPosition(x, y); } @Override public void setSize(int w, int h) { - super.setSize(w, h); if (w != mSize.x || h != mSize.y) { - mSize.set(w, h); - Slog.v(SURFACE_TAG, "setSize: " + this + ". Called by " + Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:" + this + ". Called by " + Debug.getCallers(3)); + mSize.set(w, h); } + super.setSize(w, h); } @Override public void setWindowCrop(Rect crop) { - super.setWindowCrop(crop); if (crop != null) { if (!crop.equals(mWindowCrop)) { + Slog.v(SURFACE_TAG, "setWindowCrop(" + crop.toShortString() + "): OLD:" + this + + ". Called by " + Debug.getCallers(3)); mWindowCrop.set(crop); - Slog.v(SURFACE_TAG, "setWindowCrop: " + this + ". Called by " - + Debug.getCallers(3)); } } + super.setWindowCrop(crop); } @Override public void setLayerStack(int layerStack) { - super.setLayerStack(layerStack); if (layerStack != mLayerStack) { + Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:" + this + + ". Called by " + Debug.getCallers(3)); mLayerStack = layerStack; - Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3)); } + super.setLayerStack(layerStack); } @Override public void hide() { - super.hide(); if (mShown) { + Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " + Debug.getCallers(3)); mShown = false; - Slog.v(SURFACE_TAG, "hide: " + this + ". Called by " - + Debug.getCallers(3)); } + super.hide(); } + @Override public void show() { - super.show(); if (!mShown) { + Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by " + Debug.getCallers(3)); mShown = true; - Slog.v(SURFACE_TAG, "show: " + this + ". Called by " - + Debug.getCallers(3)); } + super.show(); } @Override public void destroy() { super.destroy(); - Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " - + Debug.getCallers(3)); + Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by " + Debug.getCallers(3)); sSurfaces.remove(this); } |