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

Commit 96088059 authored by Jacqueline Bronger's avatar Jacqueline Bronger
Browse files

Add broadcast receiver to open PiP move menu on TV

- Adds broadcast receiver protected by systemui permission
- Adds option to show only the move menu instead of the button menu

Bug: 219723009
Test: manual - add action to TV PiP notification temporarily and trigger
from notification, also open menu while in move mode (double click home
or keyevent WINDOW)

Change-Id: I5044fbe26dfc6adc46aca6f2dc0cda2d9b6dacff
parent aa3a7e62
Loading
Loading
Loading
Loading
+9 −12
Original line number Original line Diff line number Diff line
@@ -234,11 +234,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
        }
        }


        setState(STATE_PIP_MENU);
        setState(STATE_PIP_MENU);
        mTvPipMenuController.showMenu();
        updatePinnedStackBounds();
        updatePinnedStackBounds();
    }
    }


    @Override
    @Override
    public void closeMenu() {
    public void onMenuClosed() {
        if (DEBUG) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: closeMenu(), state before=%s", TAG, stateToName(mState));
                    "%s: closeMenu(), state before=%s", TAG, stateToName(mState));
@@ -284,6 +285,12 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
        updatePinnedStackBounds();
        updatePinnedStackBounds();
    }
    }


    @Override
    public void enterPipMovementMenu() {
        setState(STATE_PIP_MENU);
        mTvPipMenuController.showMovementMenuOnly();
    }

    @Override
    @Override
    public void movePip(int keycode) {
    public void movePip(int keycode) {
        if (mTvPipBoundsAlgorithm.updateGravity(keycode)) {
        if (mTvPipBoundsAlgorithm.updateGravity(keycode)) {
@@ -438,7 +445,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
        }
        }


        mPipNotificationController.dismiss();
        mPipNotificationController.dismiss();
        mTvPipMenuController.hideMenu();
        mTvPipMenuController.closeMenu();
        mTvPipBoundsState.resetTvPipState();
        mTvPipBoundsState.resetTvPipState();
        setState(STATE_NO_PIP);
        setState(STATE_NO_PIP);
        mPinnedTaskId = NONEXISTENT_TASK_ID;
        mPinnedTaskId = NONEXISTENT_TASK_ID;
@@ -478,16 +485,6 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
                    TAG, stateToName(state), stateToName(mState));
                    TAG, stateToName(state), stateToName(mState));
        }
        }
        mState = state;
        mState = state;

        if (mState == STATE_PIP_MENU) {
            if (DEBUG) {
                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                        "%s:  > show menu", TAG);
            }
            mTvPipMenuController.showMenu();
        }

        updatePinnedStackBounds();
    }
    }


    private void loadConfigurations() {
    private void loadConfigurations() {
+64 −44
Original line number Original line Diff line number Diff line
@@ -65,6 +65,9 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis


    // User can actively move the PiP via the DPAD.
    // User can actively move the PiP via the DPAD.
    private boolean mInMoveMode;
    private boolean mInMoveMode;
    // Used when only showing the move menu since we want to close the menu completely when
    // exiting the move menu instead of showing the regular button menu.
    private boolean mCloseAfterExitMoveMenu;


    private final List<RemoteAction> mMediaActions = new ArrayList<>();
    private final List<RemoteAction> mMediaActions = new ArrayList<>();
    private final List<RemoteAction> mAppActions = new ArrayList<>();
    private final List<RemoteAction> mAppActions = new ArrayList<>();
@@ -102,7 +105,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
        final BroadcastReceiver closeSystemDialogsBroadcastReceiver = new BroadcastReceiver() {
        final BroadcastReceiver closeSystemDialogsBroadcastReceiver = new BroadcastReceiver() {
            @Override
            @Override
            public void onReceive(Context context, Intent intent) {
            public void onReceive(Context context, Intent intent) {
                hideMenu();
                closeMenu();
            }
            }
        };
        };
        context.registerReceiverForAllUsers(closeSystemDialogsBroadcastReceiver,
        context.registerReceiverForAllUsers(closeSystemDialogsBroadcastReceiver,
@@ -155,14 +158,31 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
                0, SHELL_ROOT_LAYER_PIP);
                0, SHELL_ROOT_LAYER_PIP);
    }
    }


    void showMovementMenuOnly() {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: showMovementMenuOnly()", TAG);
        }
        mInMoveMode = true;
        mCloseAfterExitMoveMenu = true;
        showMenuInternal();
    }

    @Override
    @Override
    public void showMenu() {
    public void showMenu() {
        if (DEBUG) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: showMenu()", TAG);
                    "%s: showMenu()", TAG);
        }
        }
        mInMoveMode = false;
        mCloseAfterExitMoveMenu = false;
        showMenuInternal();
    }


        if (mPipMenuView != null) {
    private void showMenuInternal() {
        if (mPipMenuView == null) {
            return;
        }
        Rect menuBounds = getMenuBounds(mTvPipBoundsState.getBounds());
        Rect menuBounds = getMenuBounds(mTvPipBoundsState.getBounds());
        mSystemWindows.updateViewLayout(mPipMenuView, getPipMenuLayoutParams(
        mSystemWindows.updateViewLayout(mPipMenuView, getPipMenuLayoutParams(
                MENU_WINDOW_TITLE, menuBounds.width(), menuBounds.height()));
                MENU_WINDOW_TITLE, menuBounds.width(), menuBounds.height()));
@@ -177,7 +197,10 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
            t.apply();
            t.apply();
        }
        }
        grantPipMenuFocus(true);
        grantPipMenuFocus(true);
            mPipMenuView.show(mInMoveMode, mDelegate.getPipGravity());
        if (mInMoveMode) {
            mPipMenuView.showMoveMenu(mDelegate.getPipGravity());
        } else {
            mPipMenuView.showButtonMenu();
        }
        }
    }
    }


@@ -199,25 +222,18 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
        return menuBounds;
        return menuBounds;
    }
    }


    void hideMenu() {
    void closeMenu() {
        if (!isMenuVisible()) {
        if (DEBUG) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                        "%s: hideMenu() - Menu isn't visible, so don't hide", TAG);
                    "%s: closeMenu()", TAG);
        }
        }
        if (mPipMenuView == null) {
            return;
            return;
        } else {
            if (DEBUG) {
                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                        "%s: hideMenu()", TAG);
            }
        }
        }


        mPipMenuView.hide();
        mPipMenuView.hideAll();
        if (!mInMoveMode) {
        grantPipMenuFocus(false);
        grantPipMenuFocus(false);
            mDelegate.closeMenu();
        mDelegate.onMenuClosed();
        }
    }
    }


    boolean isInMoveMode() {
    boolean isInMoveMode() {
@@ -228,25 +244,29 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
    public void onEnterMoveMode() {
    public void onEnterMoveMode() {
        if (DEBUG) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: onEnterMoveMode - %b", TAG, mInMoveMode);
                    "%s: onEnterMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode,
                    mCloseAfterExitMoveMenu);
        }
        }
        mInMoveMode = true;
        mInMoveMode = true;
        mPipMenuView.showMenuButtons(false);
        mPipMenuView.showMoveMenu(mDelegate.getPipGravity());
        mPipMenuView.showMovementHints(mDelegate.getPipGravity());
        mDelegate.onInMoveModeChanged();
    }
    }


    @Override
    @Override
    public boolean onExitMoveMode() {
    public boolean onExitMoveMode() {
        if (DEBUG) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: onExitMoveMode - %b", TAG, mInMoveMode);
                    "%s: onExitMoveMode - %b, close when exiting move menu: %b", TAG, mInMoveMode,
                    mCloseAfterExitMoveMenu);
        }
        if (mCloseAfterExitMoveMenu) {
            mInMoveMode = false;
            mCloseAfterExitMoveMenu = false;
            closeMenu();
            return true;
        }
        }
        if (mInMoveMode) {
        if (mInMoveMode) {
            mInMoveMode = false;
            mInMoveMode = false;
            mPipMenuView.showMenuButtons(true);
            mPipMenuView.showButtonMenu();
            mPipMenuView.hideMovementHints();
            mDelegate.onInMoveModeChanged();
            return true;
            return true;
        }
        }
        return false;
        return false;
@@ -266,7 +286,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis


    @Override
    @Override
    public void detach() {
    public void detach() {
        hideMenu();
        closeMenu();
        detachPipMenuView();
        detachPipMenuView();
        mLeash = null;
        mLeash = null;
    }
    }
@@ -486,7 +506,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
    @Override
    @Override
    public void onBackPress() {
    public void onBackPress() {
        if (!onExitMoveMode()) {
        if (!onExitMoveMode()) {
            hideMenu();
            closeMenu();
        }
        }
    }
    }


@@ -516,7 +536,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis


        void togglePipExpansion();
        void togglePipExpansion();


        void closeMenu();
        void onMenuClosed();


        void closePip();
        void closePip();
    }
    }
+34 −13
Original line number Original line Diff line number Diff line
@@ -177,29 +177,43 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
                expanded ? R.string.pip_collapse : R.string.pip_expand);
                expanded ? R.string.pip_collapse : R.string.pip_expand);
    }
    }


    void show(boolean inMoveMode, int gravity) {
    /**
     * @param gravity for the arrow hints
     */
    void showMoveMenu(int gravity) {
        if (DEBUG) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMoveMenu()", TAG);
                    "%s: show(), inMoveMode: %b", TAG, inMoveMode);
        }
        }
        if (inMoveMode) {
        showMenuButtons(false);
        showMovementHints(gravity);
        showMovementHints(gravity);
        } else {
        showMenuFrame(true);
            animateAlphaTo(1, mActionButtonsContainer);
    }
    }
        animateAlphaTo(1, mMenuFrameView);

    void showButtonMenu() {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showButtonMenu()", TAG);
        }
        showMenuButtons(true);
        hideMovementHints();
        showMenuFrame(true);
    }
    }


    void hide() {
    /**
     * Hides all menu views, including the menu frame.
     */
    void hideAll() {
        if (DEBUG) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: hide()", TAG);
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: hideAll()", TAG);
        }
        }
        animateAlphaTo(0, mActionButtonsContainer);
        showMenuButtons(false);
        animateAlphaTo(0, mMenuFrameView);
        hideMovementHints();
        hideMovementHints();
        showMenuFrame(false);
    }
    }


    private void animateAlphaTo(float alpha, View view) {
    private void animateAlphaTo(float alpha, View view) {
        if (view.getAlpha() == alpha) {
            return;
        }
        view.animate()
        view.animate()
                .alpha(alpha)
                .alpha(alpha)
                .setInterpolator(alpha == 0f ? TvPipInterpolators.EXIT : TvPipInterpolators.ENTER)
                .setInterpolator(alpha == 0f ? TvPipInterpolators.EXIT : TvPipInterpolators.ENTER)
@@ -419,6 +433,10 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
        animateAlphaTo(show ? 1 : 0, mActionButtonsContainer);
        animateAlphaTo(show ? 1 : 0, mActionButtonsContainer);
    }
    }


    private void showMenuFrame(boolean show) {
        animateAlphaTo(show ? 1 : 0, mMenuFrameView);
    }

    interface Listener {
    interface Listener {


        void onBackPress();
        void onBackPress();
@@ -426,7 +444,10 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
        void onEnterMoveMode();
        void onEnterMoveMode();


        /**
        /**
         * @return whether move mode was exited
         * Called when a button for exiting move mode was pressed.
         *
         * @return true if the event was handled or false if the key event should be handled by the
         * next receiver.
         */
         */
        boolean onExitMoveMode();
        boolean onExitMoveMode();


+6 −0
Original line number Original line Diff line number Diff line
@@ -56,6 +56,8 @@ public class TvPipNotificationController {
            "com.android.wm.shell.pip.tv.notification.action.SHOW_PIP_MENU";
            "com.android.wm.shell.pip.tv.notification.action.SHOW_PIP_MENU";
    private static final String ACTION_CLOSE_PIP =
    private static final String ACTION_CLOSE_PIP =
            "com.android.wm.shell.pip.tv.notification.action.CLOSE_PIP";
            "com.android.wm.shell.pip.tv.notification.action.CLOSE_PIP";
    private static final String ACTION_MOVE_PIP =
            "com.android.wm.shell.pip.tv.notification.action.MOVE_PIP";


    private final Context mContext;
    private final Context mContext;
    private final PackageManager mPackageManager;
    private final PackageManager mPackageManager;
@@ -222,6 +224,7 @@ public class TvPipNotificationController {
            mIntentFilter = new IntentFilter();
            mIntentFilter = new IntentFilter();
            mIntentFilter.addAction(ACTION_CLOSE_PIP);
            mIntentFilter.addAction(ACTION_CLOSE_PIP);
            mIntentFilter.addAction(ACTION_SHOW_PIP_MENU);
            mIntentFilter.addAction(ACTION_SHOW_PIP_MENU);
            mIntentFilter.addAction(ACTION_MOVE_PIP);
        }
        }
        boolean mRegistered = false;
        boolean mRegistered = false;


@@ -252,6 +255,8 @@ public class TvPipNotificationController {
                mDelegate.showPictureInPictureMenu();
                mDelegate.showPictureInPictureMenu();
            } else if (ACTION_CLOSE_PIP.equals(action)) {
            } else if (ACTION_CLOSE_PIP.equals(action)) {
                mDelegate.closePip();
                mDelegate.closePip();
            } else if (ACTION_MOVE_PIP.equals(action)) {
                mDelegate.enterPipMovementMenu();
            }
            }
        }
        }
    }
    }
@@ -259,5 +264,6 @@ public class TvPipNotificationController {
    interface Delegate {
    interface Delegate {
        void showPictureInPictureMenu();
        void showPictureInPictureMenu();
        void closePip();
        void closePip();
        void enterPipMovementMenu();
    }
    }
}
}