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

Commit e15352e5 authored by Matthew Ng's avatar Matthew Ng
Browse files

Splitscreen for minimized state that works with resizable launchers

If a launcher is resizable, going to minimized mode (dock task and then
press home) would show a cropped height of the task at the top in a
minimized state and the fullscreen stack would show the home launcher
which takes the rest of the remaining height. If the launcher is not
resizable, it will default the original behavior.

To enable this in a launcher, add android:resizeableActivity="true" in
the AndroidManifest.xml in the <application/> tag.

Test: manual - rotating while minimized, minimizing using dragging task
or holding overview nav button, installing resizable launcher with a
non-resizable launcher
Fixes: 32504542
Change-Id: Idf4015b40f9bec81b70f146f0f2d7df8ccfb4cf0
parent 04b926a6
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -40,8 +40,11 @@ oneway interface IDockedStackListener {
     *
     * @param minimized Whether the docked stack is currently minimized.
     * @param animDuration The duration of the animation for changing the minimized state.
     * @param isHomeStackResizable If the home stack is resizable, a portion of the docked stack
     *        will be shown with the divider
     */
    void onDockedStackMinimizedChanged(boolean minimized, long animDuration);
    void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
            boolean isHomeStackResizable);

    /**
     * Called when window manager decides to adjust the divider for IME. Like the minimized state,
+25 −3
Original line number Diff line number Diff line
@@ -53,6 +53,11 @@ public class DividerSnapAlgorithm {
     */
    private static final int SNAP_ONLY_1_1 = 2;

    /**
     * 1 snap target: minimized height, (1 - minimized height)
     */
    private static final int SNAP_MODE_MINIMIZED = 3;

    private final float mMinFlingVelocityPxPerSecond;
    private final float mMinDismissVelocityPxPerSecond;
    private final int mDisplayWidth;
@@ -62,6 +67,7 @@ public class DividerSnapAlgorithm {
    private final Rect mInsets = new Rect();
    private final int mSnapMode;
    private final int mMinimalSizeResizableTask;
    private final int mTaskHeightInMinimizedMode;
    private final float mFixedRatio;
    private boolean mIsHorizontalDivision;

@@ -93,6 +99,11 @@ public class DividerSnapAlgorithm {

    public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
            boolean isHorizontalDivision, Rect insets) {
        this(res, displayWidth, displayHeight, dividerSize, isHorizontalDivision, insets, false);
    }

    public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize,
            boolean isHorizontalDivision, Rect insets, boolean isMinimizedMode) {
        mMinFlingVelocityPxPerSecond =
                MIN_FLING_VELOCITY_DP_PER_SECOND * res.getDisplayMetrics().density;
        mMinDismissVelocityPxPerSecond =
@@ -102,12 +113,14 @@ public class DividerSnapAlgorithm {
        mDisplayHeight = displayHeight;
        mIsHorizontalDivision = isHorizontalDivision;
        mInsets.set(insets);
        mSnapMode = res.getInteger(
                com.android.internal.R.integer.config_dockedStackDividerSnapMode);
        mSnapMode = isMinimizedMode ? SNAP_MODE_MINIMIZED :
                res.getInteger(com.android.internal.R.integer.config_dockedStackDividerSnapMode);
        mFixedRatio = res.getFraction(
                com.android.internal.R.fraction.docked_stack_divider_fixed_ratio, 1, 1);
        mMinimalSizeResizableTask = res.getDimensionPixelSize(
                com.android.internal.R.dimen.default_minimal_size_resizable_task);
        mTaskHeightInMinimizedMode = res.getDimensionPixelSize(
                com.android.internal.R.dimen.task_height_of_minimized_mode);
        calculateTargets(isHorizontalDivision);
        mFirstSplitTarget = mTargets.get(1);
        mLastSplitTarget = mTargets.get(mTargets.size() - 2);
@@ -246,6 +259,7 @@ public class DividerSnapAlgorithm {
        int dividerMax = isHorizontalDivision
                ? mDisplayHeight
                : mDisplayWidth;
        int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
        mTargets.add(new SnapTarget(-mDividerSize, -mDividerSize, SnapTarget.FLAG_DISMISS_START,
                0.35f));
        switch (mSnapMode) {
@@ -258,8 +272,10 @@ public class DividerSnapAlgorithm {
            case SNAP_ONLY_1_1:
                addMiddleTarget(isHorizontalDivision);
                break;
            case SNAP_MODE_MINIMIZED:
                addMinimizedTarget(isHorizontalDivision);
                break;
        }
        int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right;
        mTargets.add(new SnapTarget(dividerMax - navBarSize, dividerMax,
                SnapTarget.FLAG_DISMISS_END, 0.35f));
    }
@@ -315,6 +331,12 @@ public class DividerSnapAlgorithm {
        mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
    }

    private void addMinimizedTarget(boolean isHorizontalDivision) {
        int position = mTaskHeightInMinimizedMode;
        position += isHorizontalDivision ? mInsets.top : mInsets.left;
        mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE));
    }

    public SnapTarget getMiddleTarget() {
        return mMiddleTarget;
    }
+3 −0
Original line number Diff line number Diff line
@@ -488,6 +488,9 @@
    <!-- The default minimal size of a resizable task, in both dimensions. -->
    <dimen name="default_minimal_size_resizable_task">220dp</dimen>

    <!-- Height of a task when in minimized mode from the top when launcher is resizable. -->
    <dimen name="task_height_of_minimized_mode">80dp</dimen>

    <!-- Minimum "smallest width" of the display for cascading menus to be enabled. -->
    <dimen name="cascading_menus_min_smallest_width">720dp</dimen>

+1 −0
Original line number Diff line number Diff line
@@ -1772,6 +1772,7 @@
  <java-symbol type="id" name="replace_message" />
  <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
  <java-symbol type="dimen" name="default_minimal_size_resizable_task" />
  <java-symbol type="dimen" name="task_height_of_minimized_mode" />
  <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
  <java-symbol type="fraction" name="config_autoBrightnessAdjustmentMaxGamma" />
  <java-symbol type="integer" name="config_autoBrightnessAmbientLightHorizon"/>
+13 −9
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ public class Divider extends SystemUI {
    private boolean mVisible = false;
    private boolean mMinimized = false;
    private boolean mAdjustedForIme = false;
    private boolean mHomeStackResizable = false;
    private ForcedResizableInfoActivityController mForcedResizableController;

    @Override
@@ -75,6 +76,7 @@ public class Divider extends SystemUI {
        mView = (DividerView)
                LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
        mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE);
        mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
        final int size = mContext.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.docked_stack_divider_thickness);
        final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE;
@@ -92,7 +94,7 @@ public class Divider extends SystemUI {
        removeDivider();
        addDivider(configuration);
        if (mMinimized) {
            mView.setMinimizedDockStack(true);
            mView.setMinimizedDockStack(true, mHomeStackResizable);
            updateTouchable();
        }
    }
@@ -106,13 +108,14 @@ public class Divider extends SystemUI {
                    mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);

                    // Update state because animations won't finish.
                    mView.setMinimizedDockStack(mMinimized);
                    mView.setMinimizedDockStack(mMinimized, mHomeStackResizable);
                }
            }
        });
    }

    private void updateMinimizedDockedStack(final boolean minimized, final long animDuration) {
    private void updateMinimizedDockedStack(final boolean minimized, final long animDuration,
            final boolean isHomeStackResizable) {
        mView.post(new Runnable() {
            @Override
            public void run() {
@@ -120,9 +123,9 @@ public class Divider extends SystemUI {
                    mMinimized = minimized;
                    updateTouchable();
                    if (animDuration > 0) {
                        mView.setMinimizedDockStack(minimized, animDuration);
                        mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable);
                    } else {
                        mView.setMinimizedDockStack(minimized);
                        mView.setMinimizedDockStack(minimized, isHomeStackResizable);
                    }
                }
            }
@@ -139,7 +142,7 @@ public class Divider extends SystemUI {
    }

    private void updateTouchable() {
        mWindowManager.setTouchable(!mMinimized && !mAdjustedForIme);
        mWindowManager.setTouchable((mHomeStackResizable || !mMinimized) && !mAdjustedForIme);
    }

    @Override
@@ -162,9 +165,10 @@ public class Divider extends SystemUI {
        }

        @Override
        public void onDockedStackMinimizedChanged(boolean minimized, long animDuration)
                throws RemoteException {
            updateMinimizedDockedStack(minimized, animDuration);
        public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
                boolean isHomeStackResizable) throws RemoteException {
            mHomeStackResizable = isHomeStackResizable;
            updateMinimizedDockedStack(minimized, animDuration, isHomeStackResizable);
        }

        @Override
Loading