Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6832082c authored by Andrii Kulian's avatar Andrii Kulian Committed by android-build-merger
Browse files

Merge "Place black background only behind nav bar when letterboxed" into oc-dr1-dev

am: 3289a5a1

Change-Id: Id4069e1c1126d9658a18a448a4bd7566af938cbb
parents 73e3d9f5 3289a5a1
Loading
Loading
Loading
Loading
+56 −47
Original line number Diff line number Diff line
@@ -29,12 +29,16 @@ import android.view.SurfaceSession;
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 @@ class SurfaceControlWithBackground extends SurfaceControl {
    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 @@ class SurfaceControlWithBackground extends SurfaceControl {
        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 @@ class SurfaceControlWithBackground extends SurfaceControl {
        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 @@ class SurfaceControlWithBackground extends SurfaceControl {
        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);
        }
        mHiddenForCrop = mTmpContainerRect.isEmpty();
        updateBackgroundVisibility();
    }

    @Override
@@ -164,34 +161,24 @@ class SurfaceControlWithBackground extends SurfaceControl {
        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);
    }
    }

    /** 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 @@ class SurfaceControlWithBackground extends SurfaceControl {
        // 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);

        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;
        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);

        // 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 @@ class SurfaceControlWithBackground extends SurfaceControl {
            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();