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

Commit 7fce162a authored by Mariia Sandrikova's avatar Mariia Sandrikova Committed by Android (Google) Code Review
Browse files

Merge changes from topic "letterbox-basic-reachability" into sc-v2-dev

* changes:
  [2/n] Letterbox reachability: Aspect ratio as in split screen.
  [1/n] Letterbox Reachability: Repositioning on double tap.
parents 4fbd82b5 9c293959
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -4873,6 +4873,21 @@
        or > 1, it is ignored and central positionis used (0.5). -->
    <item name="config_letterboxHorizontalPositionMultiplier" format="float" type="dimen">0.5</item>

    <!-- Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape
        device orientation. -->
    <bool name="config_letterboxIsReachabilityEnabled">false</bool>

    <!-- Default horizonal position of a center of the letterboxed app window when reachability is
        enabled and an app is fullscreen in landscape device orientation.
        0 corresponds to the left side of the screen and 1 to the right side. If given value < 0.0
        or > 1, it is ignored and right positionis used (1.0). The position multiplier is changed
        to a symmetrical value computed as (1 - current multiplier) after each double tap in the
        letterbox area. -->
    <item name="config_letterboxDefaultPositionMultiplierForReachability"
          format="float" type="dimen">
        0.9
    </item>

    <!-- If true, hide the display cutout with display area -->
    <bool name="config_hideDisplayCutoutWithDisplayArea">false</bool>

+2 −0
Original line number Diff line number Diff line
@@ -4254,6 +4254,8 @@
  <java-symbol type="integer" name="config_letterboxBackgroundType" />
  <java-symbol type="color" name="config_letterboxBackgroundColor" />
  <java-symbol type="dimen" name="config_letterboxHorizontalPositionMultiplier" />
  <java-symbol type="bool" name="config_letterboxIsReachabilityEnabled" />
  <java-symbol type="dimen" name="config_letterboxDefaultPositionMultiplierForReachability" />

  <java-symbol type="bool" name="config_hideDisplayCutoutWithDisplayArea" />

+12 −8
Original line number Diff line number Diff line
@@ -7526,11 +7526,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                    parentAppBounds.width(), screenResolvedBounds.width());
        } else {
            float positionMultiplier =
                    mWmService.mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier();
            positionMultiplier =
                    (positionMultiplier < 0.0f || positionMultiplier > 1.0f)
                            // Default to central position if invalid value is provided.
                            ? 0.5f : positionMultiplier;
                    mLetterboxUiController.getHorizontalPositionMultiplier(newParentConfiguration);
            offsetX = (int) Math.ceil((parentAppBounds.width() - screenResolvedBounds.width())
                    * positionMultiplier);
        }
@@ -7547,6 +7543,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration);
    }

    void recomputeConfiguration() {
        onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration());
    }

    boolean isInTransition() {
        return mAtmService.getTransitionController().inTransition() // Shell transitions.
                || isAnimating(PARENTS | TRANSITION); // Legacy transitions.
    }

    /**
     * Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
     * orientation then aspect ratio restrictions are also already respected.
@@ -7649,6 +7654,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // If the activity requires a different orientation (either by override or activityInfo),
        // make it fit the available bounds by scaling down its bounds.
        final int forcedOrientation = getRequestedConfigurationOrientation();

        if (forcedOrientation == ORIENTATION_UNDEFINED
                || (forcedOrientation == parentOrientation && orientationRespectedWithInsets)) {
            return;
@@ -7700,10 +7706,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final Rect prevResolvedBounds = new Rect(resolvedBounds);
        resolvedBounds.set(containingBounds);

        // Override from config_fixedOrientationLetterboxAspectRatio or via ADB with
        // set-fixed-orientation-letterbox-aspect-ratio.
        final float letterboxAspectRatioOverride =
                mWmService.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio();
                mLetterboxUiController.getFixedOrientationLetterboxAspectRatio(newParentConfig);
        final float desiredAspectRatio =
                letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO
                        ? letterboxAspectRatioOverride : computeAspectRatio(parentBounds);
+46 −14
Original line number Diff line number Diff line
@@ -19,14 +19,18 @@ package com.android.server.wm;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.view.SurfaceControl.HIDDEN;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.Process;
import android.view.GestureDetector;
import android.view.InputChannel;
import android.view.InputEvent;
import android.view.InputEventReceiver;
import android.view.InputWindowHandle;
import android.view.MotionEvent;
import android.view.SurfaceControl;
import android.view.WindowManager;

@@ -65,6 +69,8 @@ public class Letterbox {
    // for overlaping an app window and letterbox surfaces.
    private final LetterboxSurface mFullWindowSurface = new LetterboxSurface("fullWindow");
    private final LetterboxSurface[] mSurfaces = { mLeft, mTop, mRight, mBottom };
    // Reachability gestures.
    private final Runnable mDoubleTapCallback;

    /**
     * Constructs a Letterbox.
@@ -77,7 +83,8 @@ public class Letterbox {
            Supplier<Color> colorSupplier,
            Supplier<Boolean> hasWallpaperBackgroundSupplier,
            Supplier<Integer> blurRadiusSupplier,
            Supplier<Float> darkScrimAlphaSupplier) {
            Supplier<Float> darkScrimAlphaSupplier,
            Runnable doubleTapCallback) {
        mSurfaceControlFactory = surfaceControlFactory;
        mTransactionFactory = transactionFactory;
        mAreCornersRounded = areCornersRounded;
@@ -85,6 +92,7 @@ public class Letterbox {
        mHasWallpaperBackgroundSupplier = hasWallpaperBackgroundSupplier;
        mBlurRadiusSupplier = blurRadiusSupplier;
        mDarkScrimAlphaSupplier = darkScrimAlphaSupplier;
        mDoubleTapCallback = doubleTapCallback;
    }

    /**
@@ -231,18 +239,48 @@ public class Letterbox {
        return mAreCornersRounded.get() || mHasWallpaperBackgroundSupplier.get();
    }

    private static class InputInterceptor {
        final InputChannel mClientChannel;
        final InputWindowHandle mWindowHandle;
        final InputEventReceiver mInputEventReceiver;
        final WindowManagerService mWmService;
        final IBinder mToken;
    private final class TapEventReceiver extends InputEventReceiver {

        private final GestureDetector mDoubleTapDetector;
        private final DoubleTapListener mDoubleTapListener;

        TapEventReceiver(InputChannel inputChannel, Context context) {
            super(inputChannel, UiThread.getHandler().getLooper());
            mDoubleTapListener = new DoubleTapListener();
            mDoubleTapDetector = new GestureDetector(context, mDoubleTapListener);
        }

        @Override
        public void onInputEvent(InputEvent event) {
            final MotionEvent motionEvent = (MotionEvent) event;
            finishInputEvent(event, mDoubleTapDetector.onTouchEvent(motionEvent));
        }
    }

    private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            if (e.getAction() == MotionEvent.ACTION_UP) {
                mDoubleTapCallback.run();
                return true;
            }
            return false;
        }
    }

    private final class InputInterceptor {

        private final InputChannel mClientChannel;
        private final InputWindowHandle mWindowHandle;
        private final InputEventReceiver mInputEventReceiver;
        private final WindowManagerService mWmService;
        private final IBinder mToken;

        InputInterceptor(String namePrefix, WindowState win) {
            mWmService = win.mWmService;
            final String name = namePrefix + (win.mActivityRecord != null ? win.mActivityRecord : win);
            mClientChannel = mWmService.mInputManager.createInputChannel(name);
            mInputEventReceiver = new SimpleInputReceiver(mClientChannel);
            mInputEventReceiver = new TapEventReceiver(mClientChannel, mWmService.mContext);

            mToken = mClientChannel.getToken();

@@ -280,12 +318,6 @@ public class Letterbox {
            mInputEventReceiver.dispose();
            mClientChannel.dispose();
        }

        private static class SimpleInputReceiver extends InputEventReceiver {
            SimpleInputReceiver(InputChannel inputChannel) {
                super(inputChannel, UiThread.getHandler().getLooper());
            }
        }
    }

    private class LetterboxSurface {
+109 −4
Original line number Diff line number Diff line
@@ -85,6 +85,26 @@ final class LetterboxConfiguration {
    // side of the screen and 1.0 to the right side.
    private float mLetterboxHorizontalPositionMultiplier;

    // Default horizontal position of a center of the letterboxed app window when reachability is
    // enabled and an app is fullscreen in landscape device orientatio. 0 corresponds to the left
    // side of the screen and 1.0 to the right side.
    // It is used as a starting point for mLetterboxHorizontalMultiplierForReachability.
    private float mDefaultPositionMultiplierForReachability;

    // Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape
    // device orientation.
    private boolean mIsReachabilityEnabled;

    // Horizontal position of a center of the letterboxed app window. 0 corresponds to
    // the left side of the screen and 1 to the right side. Keep it global to prevent
    // "jumps" when switching between letterboxed apps. It's updated to reposition the app
    // window in response to a double tap gesture (see LetterboxUiController#handleDoubleTap).
    // Used in LetterboxUiController#getHorizontalPositionMultiplier which is called from
    // ActivityRecord#updateResolvedBoundsHorizontalPosition.
    // TODO(b/199426138): Global reachability setting causes a jump when resuming an app from
    // Overview after changing position in another app.
    private volatile float mLetterboxHorizontalMultiplierForReachability;

    LetterboxConfiguration(Context systemUiContext) {
        mContext = systemUiContext;
        mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
@@ -98,6 +118,11 @@ final class LetterboxConfiguration {
                R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha);
        mLetterboxHorizontalPositionMultiplier = mContext.getResources().getFloat(
                R.dimen.config_letterboxHorizontalPositionMultiplier);
        mIsReachabilityEnabled = mContext.getResources().getBoolean(
                R.bool.config_letterboxIsReachabilityEnabled);
        mDefaultPositionMultiplierForReachability = mContext.getResources().getFloat(
                R.dimen.config_letterboxDefaultPositionMultiplierForReachability);
        mLetterboxHorizontalMultiplierForReachability = mDefaultPositionMultiplierForReachability;
    }

    /**
@@ -317,12 +342,12 @@ final class LetterboxConfiguration {
     * in {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}
     * or via an ADB command. 0 corresponds to the left side of the screen and 1 to the
     * right side.
     *
     * <p>This value can be outside of [0, 1] range so clients need to check and default to the
     * central position (0.5).
     */
    float getLetterboxHorizontalPositionMultiplier() {
        return mLetterboxHorizontalPositionMultiplier;
        return (mLetterboxHorizontalPositionMultiplier < 0.0f
                || mLetterboxHorizontalPositionMultiplier > 1.0f)
                        // Default to central position if invalid value is provided.
                        ? 0.5f : mLetterboxHorizontalPositionMultiplier;
    }

    /**
@@ -344,4 +369,84 @@ final class LetterboxConfiguration {
                com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier);
    }

    /*
     * Whether reachability repositioning is allowed for letterboxed fullscreen apps in landscape
     * device orientation.
     */
    boolean getIsReachabilityEnabled() {
        return mIsReachabilityEnabled;
    }

    /**
     * Overrides whether reachability repositioning is allowed for letterboxed fullscreen apps in
     * landscape device orientation.
     */
    void setIsReachabilityEnabled(boolean enabled) {
        mIsReachabilityEnabled = enabled;
    }

    /**
     * Resets whether reachability repositioning is allowed for letterboxed fullscreen apps in
     * landscape device orientation to {@link R.bool.config_letterboxIsReachabilityEnabled}.
     */
    void resetIsReachabilityEnabled() {
        mIsReachabilityEnabled = mContext.getResources().getBoolean(
                R.bool.config_letterboxIsReachabilityEnabled);
    }

    /*
     * Gets default horizontal position of a center of the letterboxed app window when reachability
     * is enabled specified in {@link
     * R.dimen.config_letterboxDefaultPositionMultiplierForReachability} or via an ADB command.
     * 0 corresponds to the left side of the screen and 1 to the right side. The returned value is
     * >= 0.0 and <= 1.0.
     */
    float getDefaultPositionMultiplierForReachability() {
        return (mDefaultPositionMultiplierForReachability < 0.0f
                || mDefaultPositionMultiplierForReachability > 1.0f)
                        // Default to a right position if invalid value is provided.
                        ? 1.0f : mDefaultPositionMultiplierForReachability;
    }

    /**
     * Overrides default horizontal position of a center of the letterboxed app window when
     * reachability is enabled. If given value < 0.0 or > 1.0, then it and a value of {@link
     * R.dimen.config_letterboxDefaultPositionMultiplierForReachability} are ignored and the right
     * position (1.0) is used.
     */
    void setDefaultPositionMultiplierForReachability(float multiplier) {
        mDefaultPositionMultiplierForReachability = multiplier;
    }

    /**
     * Resets default horizontal position of a center of the letterboxed app window when
     * reachability is enabled to {@link
     * R.dimen.config_letterboxDefaultPositionMultiplierForReachability}.
     */
    void resetDefaultPositionMultiplierForReachability() {
        mDefaultPositionMultiplierForReachability = mContext.getResources().getFloat(
                R.dimen.config_letterboxDefaultPositionMultiplierForReachability);
    }

    /*
     * Gets horizontal position of a center of the letterboxed app window when reachability
     * is enabled specified. 0 corresponds to the left side of the screen and 1 to the right side.
     *
     * <p>The position multiplier is changed to a symmetrical value computed as (1 - current
     * multiplier) after each double tap in the letterbox area.
     */
    float getHorizontalMultiplierForReachability() {
        return mLetterboxHorizontalMultiplierForReachability;
    }

    /**
     * Changes horizontal position of a center of the letterboxed app window to the opposite
     * (1 - current multiplier) when reachability is enabled specified. 0 corresponds to the left
     * side of the screen and 1 to the right side.
     */
    void flipHorizontalMultiplierForReachability() {
        mLetterboxHorizontalMultiplierForReachability =
                1.0f - mLetterboxHorizontalMultiplierForReachability;
    }

}
Loading