Merge "Place black background only behind nav bar when letterboxed" into oc-dr1-dev
am: 3289a5a1e0
Change-Id: Id4069e1c1126d9658a18a448a4bd7566af938cbb
diff --git a/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
index ac06c6d..3603f2f 100644
--- a/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
+++ b/services/core/java/com/android/server/wm/SurfaceControlWithBackground.java
@@ -29,12 +29,16 @@
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManagerPolicy.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicy.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicy.NAV_BAR_RIGHT;
/**
- * SurfaceControl extension that has background sized to match its container.
+ * SurfaceControl extension that has black background behind navigation bar area for fullscreen
+ * letterboxed apps.
*/
class SurfaceControlWithBackground extends SurfaceControl {
- // SurfaceControl that holds the background behind opaque letterboxed app windows.
+ // SurfaceControl that holds the background.
private SurfaceControl mBackgroundControl;
// Flag that defines whether the background should be shown.
@@ -51,8 +55,10 @@
private float mLastDsDx = 1, mLastDsDy = 1;
private float mLastX, mLastY;
- // Will skip alpha animation for background of starting window.
- private boolean mIsStartingWindow;
+ // SurfaceFlinger doesn't support crop rectangles where width or height is non-positive.
+ // If we just set an empty crop it will behave as if there is no crop at all.
+ // To fix this we explicitly hide the surface and won't let it to be shown.
+ private boolean mHiddenForCrop = false;
public SurfaceControlWithBackground(SurfaceControlWithBackground other) {
super(other);
@@ -76,7 +82,6 @@
mLastWidth = w;
mLastHeight = h;
mWindowSurfaceController.getContainerRect(mTmpContainerRect);
- mIsStartingWindow = windowType == TYPE_APPLICATION_STARTING;
mBackgroundControl = new SurfaceControl(s, "Background for - " + name,
mTmpContainerRect.width(), mTmpContainerRect.height(), PixelFormat.OPAQUE,
flags | SurfaceControl.FX_SURFACE_DIM);
@@ -89,10 +94,7 @@
if (mBackgroundControl == null) {
return;
}
- // We won't animate alpha for starting window because it will be visible as a flash for user
- // when fading out to reveal real app window.
- final float backgroundAlpha = mIsStartingWindow && alpha < 1.f ? 0 : alpha;
- mBackgroundControl.setAlpha(backgroundAlpha);
+ mBackgroundControl.setAlpha(alpha);
}
@Override
@@ -146,15 +148,10 @@
if (mBackgroundControl == null) {
return;
}
- if (crop.width() < mLastWidth || crop.height() < mLastHeight) {
- // We're animating and cropping window, compute the appropriate crop for background.
- calculateBgCrop(crop);
- mBackgroundControl.setWindowCrop(mTmpContainerRect);
- } else {
- // When not animating just set crop to container rect.
- mWindowSurfaceController.getContainerRect(mTmpContainerRect);
- mBackgroundControl.setWindowCrop(mTmpContainerRect);
- }
+ calculateBgCrop(crop);
+ mBackgroundControl.setWindowCrop(mTmpContainerRect);
+ mHiddenForCrop = mTmpContainerRect.isEmpty();
+ updateBackgroundVisibility();
}
@Override
@@ -164,34 +161,24 @@
if (mBackgroundControl == null) {
return;
}
- if (crop.width() < mLastWidth || crop.height() < mLastHeight) {
- // We're animating and cropping window, compute the appropriate crop for background.
- calculateBgCrop(crop);
- mBackgroundControl.setFinalCrop(mTmpContainerRect);
- } else {
- // When not animating just set crop to container rect.
- mWindowSurfaceController.getContainerRect(mTmpContainerRect);
- mBackgroundControl.setFinalCrop(mTmpContainerRect);
- }
+ mWindowSurfaceController.getContainerRect(mTmpContainerRect);
+ mBackgroundControl.setFinalCrop(mTmpContainerRect);
}
- /** Compute background crop based on current animation progress for main surface control. */
+ /**
+ * Compute background crop based on current animation progress for main surface control and
+ * update {@link #mTmpContainerRect} with new values.
+ */
private void calculateBgCrop(Rect crop) {
// Track overall progress of animation by computing cropped portion of status bar.
final Rect contentInsets = mWindowSurfaceController.mAnimator.mWin.mContentInsets;
float d = contentInsets.top == 0 ? 0 : (float) crop.top / contentInsets.top;
if (d > 1.f) {
// We're running expand animation from launcher, won't compute custom bg crop here.
- mTmpContainerRect.set(crop);
+ mTmpContainerRect.setEmpty();
return;
}
- // Compute additional offset for the background when app window is positioned not at (0,0).
- // E.g. landscape with navigation bar on the left.
- final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
- final int offsetX = (int) (winFrame.left * mLastDsDx * d + 0.5);
- final int offsetY = (int) (winFrame.top * mLastDsDy * d + 0.5);
-
// Compute new scaled width and height for background that will depend on current animation
// progress. Those consist of current crop rect for the main surface + scaled areas outside
// of letterboxed area.
@@ -201,17 +188,39 @@
// computing correct frames for letterboxed windows in WindowState.
d = d < 0.025f ? 0 : d;
mWindowSurfaceController.getContainerRect(mTmpContainerRect);
- final int backgroundWidth =
- (int) (crop.width() + (mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
- final int backgroundHeight =
- (int) (crop.height() + (mTmpContainerRect.height() - mLastHeight) * (1 - d) + 0.5);
+ int backgroundWidth = 0, backgroundHeight = 0;
+ // Compute additional offset for the background when app window is positioned not at (0,0).
+ // E.g. landscape with navigation bar on the left.
+ final Rect winFrame = mWindowSurfaceController.mAnimator.mWin.mFrame;
+ int offsetX = (int)((winFrame.left - mTmpContainerRect.left) * mLastDsDx),
+ offsetY = (int) ((winFrame.top - mTmpContainerRect.top) * mLastDsDy);
- mTmpContainerRect.set(crop);
- // Make sure that part of background to left/top is visible and scaled.
- mTmpContainerRect.offset(offsetX, offsetY);
- // Set correct width/height, so that area to right/bottom is cropped properly.
- mTmpContainerRect.right = mTmpContainerRect.left + backgroundWidth;
- mTmpContainerRect.bottom = mTmpContainerRect.top + backgroundHeight;
+ // Position and size background.
+ final int bgPosition = mWindowSurfaceController.mAnimator.mService.getNavBarPosition();
+
+ switch (bgPosition) {
+ case NAV_BAR_LEFT:
+ backgroundWidth = (int) ((mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
+ backgroundHeight = crop.height();
+ offsetX += crop.left - backgroundWidth;
+ offsetY += crop.top;
+ break;
+ case NAV_BAR_RIGHT:
+ backgroundWidth = (int) ((mTmpContainerRect.width() - mLastWidth) * (1 - d) + 0.5);
+ backgroundHeight = crop.height();
+ offsetX += crop.right;
+ offsetY += crop.top;
+ break;
+ case NAV_BAR_BOTTOM:
+ backgroundWidth = crop.width();
+ backgroundHeight = (int) ((mTmpContainerRect.height() - mLastHeight) * (1 - d)
+ + 0.5);
+ offsetX += crop.left;
+ offsetY += crop.bottom;
+ break;
+ }
+ mTmpContainerRect.set(offsetX, offsetY, offsetX + backgroundWidth,
+ offsetY + backgroundHeight);
}
@Override
@@ -317,7 +326,7 @@
return;
}
final AppWindowToken appWindowToken = mWindowSurfaceController.mAnimator.mWin.mAppToken;
- if (appWindowToken != null && appWindowToken.fillsParent() && mVisible) {
+ if (!mHiddenForCrop && mVisible && appWindowToken != null && appWindowToken.fillsParent()) {
mBackgroundControl.show();
} else {
mBackgroundControl.hide();