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

Commit 7ce98ef7 authored by Galia Peycheva's avatar Galia Peycheva Committed by Automerger Merge Worker
Browse files

Merge "Introduce TvPipMenuMode" into udc-dev am: 28352765

parents a829c8f3 28352765
Loading
Loading
Loading
Loading
+153 −95
Original line number Original line Diff line number Diff line
@@ -18,7 +18,7 @@ package com.android.wm.shell.pip.tv;


import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP;
import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP;


import android.app.ActivityManager;
import android.annotation.IntDef;
import android.app.RemoteAction;
import android.app.RemoteAction;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
@@ -36,6 +36,7 @@ import android.window.SurfaceSyncGroup;


import androidx.annotation.Nullable;
import androidx.annotation.Nullable;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.R;
import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.SystemWindows;
@@ -61,13 +62,36 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
    private SurfaceControl mLeash;
    private SurfaceControl mLeash;
    private TvPipMenuView mPipMenuView;
    private TvPipMenuView mPipMenuView;
    private View mPipBackgroundView;
    private View mPipBackgroundView;
    private boolean mMenuIsFocused;


    private boolean mMenuIsOpen;
    @TvPipMenuMode
    // User can actively move the PiP via the DPAD.
    private int mCurrentMenuMode = MODE_NO_MENU;
    private boolean mInMoveMode;
    @TvPipMenuMode
    // Used when only showing the move menu since we want to close the menu completely when
    private int mPrevMenuMode = MODE_NO_MENU;
    // exiting the move menu instead of showing the regular button menu.

    private boolean mCloseAfterExitMoveMenu;
    @IntDef(prefix = { "MODE_" }, value = {
        MODE_NO_MENU,
        MODE_MOVE_MENU,
        MODE_ALL_ACTIONS_MENU,
    })
    public @interface TvPipMenuMode {}

    /**
     * In this mode the PiP menu is not focused and no user controls are displayed.
     */
    static final int MODE_NO_MENU = 0;

    /**
     * In this mode the PiP menu is focused and the user can use the DPAD controls to move the PiP
     * to a different position on the screen. We draw arrows in all possible movement directions.
     */
    static final int MODE_MOVE_MENU = 1;

    /**
     * In this mode the PiP menu is focused and we display an array of actions that the user can
     * select. See {@link TvPipActionsProvider} for the types of available actions.
     */
    static final int MODE_ALL_ACTIONS_MENU = 2;


    public TvPipMenuController(Context context, TvPipBoundsState tvPipBoundsState,
    public TvPipMenuController(Context context, TvPipBoundsState tvPipBoundsState,
            SystemWindows systemWindows, Handler mainHandler) {
            SystemWindows systemWindows, Handler mainHandler) {
@@ -143,11 +167,16 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
                    "%s: Actions provider is not set", TAG);
                    "%s: Actions provider is not set", TAG);
            return;
            return;
        }
        }
        mPipMenuView = new TvPipMenuView(mContext, mMainHandler, this, mTvPipActionsProvider);
        mPipMenuView = createTvPipMenuView();
        setUpViewSurfaceZOrder(mPipMenuView, 1);
        setUpViewSurfaceZOrder(mPipMenuView, 1);
        addPipMenuViewToSystemWindows(mPipMenuView, MENU_WINDOW_TITLE);
        addPipMenuViewToSystemWindows(mPipMenuView, MENU_WINDOW_TITLE);
    }
    }


    @VisibleForTesting
    TvPipMenuView createTvPipMenuView() {
        return new TvPipMenuView(mContext, mMainHandler, this, mTvPipActionsProvider);
    }

    private void attachPipBackgroundView() {
    private void attachPipBackgroundView() {
        mPipBackgroundView = LayoutInflater.from(mContext)
        mPipBackgroundView = LayoutInflater.from(mContext)
                .inflate(R.layout.tv_pip_menu_background, null);
                .inflate(R.layout.tv_pip_menu_background, null);
@@ -188,37 +217,14 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis


    void showMovementMenu() {
    void showMovementMenu() {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: showMovementMenuOnly()", TAG);
                "%s: showMovementMenu()", TAG);
        setInMoveMode(true);
        switchToMenuMode(MODE_MOVE_MENU);
        if (mMenuIsOpen) {
            mPipMenuView.showMoveMenu(mTvPipBoundsState.getTvPipGravity());
        } else {
            mCloseAfterExitMoveMenu = true;
            showMenuInternal();
        }
    }
    }


    @Override
    @Override
    public void showMenu() {
    public void showMenu() {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMenu()", TAG);
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMenu()", TAG);
        setInMoveMode(false);
        switchToMenuMode(MODE_ALL_ACTIONS_MENU, true);
        mCloseAfterExitMoveMenu = false;
        showMenuInternal();
    }

    private void showMenuInternal() {
        if (mPipMenuView == null) {
            return;
        }

        mMenuIsOpen = true;
        grantPipMenuFocus(true);
        if (mInMoveMode) {
            mPipMenuView.showMoveMenu(mTvPipBoundsState.getTvPipGravity());
        } else {
            mPipMenuView.showButtonsMenu(/* exitingMoveMode= */ false);
        }
        mPipMenuView.updateBounds(mTvPipBoundsState.getBounds());
    }
    }


    void onPipTransitionToTargetBoundsStarted(Rect targetBounds) {
    void onPipTransitionToTargetBoundsStarted(Rect targetBounds) {
@@ -228,9 +234,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
    }
    }


    void updateGravity(int gravity) {
    void updateGravity(int gravity) {
        if (mInMoveMode) {
        mPipMenuView.setPipGravity(gravity);
            mPipMenuView.showMovementHints(gravity);
        }
    }
    }


    private Rect calculateMenuSurfaceBounds(Rect pipBounds) {
    private Rect calculateMenuSurfaceBounds(Rect pipBounds) {
@@ -240,58 +244,7 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
    void closeMenu() {
    void closeMenu() {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: closeMenu()", TAG);
                "%s: closeMenu()", TAG);

        switchToMenuMode(MODE_NO_MENU);
        if (mPipMenuView == null) {
            return;
        }

        mMenuIsOpen = false;
        mPipMenuView.hideAllUserControls();
        grantPipMenuFocus(false);
        mDelegate.onMenuClosed();
    }

    boolean isInMoveMode() {
        return mInMoveMode;
    }

    private void setInMoveMode(boolean moveMode) {
        if (mInMoveMode == moveMode) {
            return;
        }
        mInMoveMode = moveMode;
        if (mDelegate != null) {
            mDelegate.onInMoveModeChanged();
        }
    }

    @Override
    public boolean onExitMoveMode() {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: onExitMoveMode - %b, close when exiting move menu: %b",
                TAG, mInMoveMode, mCloseAfterExitMoveMenu);

        if (mInMoveMode) {
            setInMoveMode(false);
            if (mCloseAfterExitMoveMenu) {
                mCloseAfterExitMoveMenu = false;
                closeMenu();
            } else {
                mPipMenuView.showButtonsMenu(/* exitingMoveMode= */ true);
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean onPipMovement(int keycode) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: onPipMovement - %b", TAG, mInMoveMode);
        if (mInMoveMode) {
            mDelegate.movePip(keycode);
        }
        return mInMoveMode;
    }
    }


    @Override
    @Override
@@ -422,13 +375,90 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
                getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, menuBounds.width(),
                getPipMenuLayoutParams(mContext, MENU_WINDOW_TITLE, menuBounds.width(),
                        menuBounds.height()));
                        menuBounds.height()));
        if (mPipMenuView != null) {
        if (mPipMenuView != null) {
            mPipMenuView.updateBounds(pipBounds);
            mPipMenuView.setPipBounds(pipBounds);
        }
        }
    }
    }


    // Start methods handling {@link TvPipMenuMode}

    @VisibleForTesting
    boolean isMenuOpen() {
        return mCurrentMenuMode != MODE_NO_MENU;
    }

    @VisibleForTesting
    boolean isInMoveMode() {
        return mCurrentMenuMode == MODE_MOVE_MENU;
    }

    @VisibleForTesting
    boolean isInAllActionsMode() {
        return mCurrentMenuMode == MODE_ALL_ACTIONS_MENU;
    }

    private void switchToMenuMode(@TvPipMenuMode int menuMode) {
        switchToMenuMode(menuMode, false);
    }

    private void switchToMenuMode(@TvPipMenuMode int menuMode, boolean resetMenu) {
        // Note: we intentionally don't return early here, because the TvPipMenuView needs to
        // refresh the Ui even if there is no menu mode change.
        mPrevMenuMode = mCurrentMenuMode;
        mCurrentMenuMode = menuMode;

        ProtoLog.i(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: switchToMenuMode: setting mCurrentMenuMode=%s, mPrevMenuMode=%s", TAG,
                getMenuModeString(), getMenuModeString(mPrevMenuMode));

        updateUiOnNewMenuModeRequest(resetMenu);
        updateDelegateOnNewMenuModeRequest();
    }

    private void updateUiOnNewMenuModeRequest(boolean resetMenu) {
        if (mPipMenuView == null) return;

        mPipMenuView.setPipGravity(mTvPipBoundsState.getTvPipGravity());
        mPipMenuView.transitionToMenuMode(mCurrentMenuMode, resetMenu);
        grantPipMenuFocus(mCurrentMenuMode != MODE_NO_MENU);
    }

    private void updateDelegateOnNewMenuModeRequest() {
        if (mPrevMenuMode == mCurrentMenuMode) return;
        if (mDelegate == null) return;

        if (mPrevMenuMode == MODE_MOVE_MENU || isInMoveMode()) {
            mDelegate.onInMoveModeChanged();
        }

        if (mCurrentMenuMode == MODE_NO_MENU) {
            mDelegate.onMenuClosed();
        }
    }

    @VisibleForTesting
    String getMenuModeString() {
        return getMenuModeString(mCurrentMenuMode);
    }

    static String getMenuModeString(@TvPipMenuMode int menuMode) {
        switch(menuMode) {
            case MODE_NO_MENU:
                return "MODE_NO_MENU";
            case MODE_MOVE_MENU:
                return "MODE_MOVE_MENU";
            case MODE_ALL_ACTIONS_MENU:
                return "MODE_ALL_ACTIONS_MENU";
            default:
                return "Unknown";
        }
    }

    // Start {@link TvPipMenuView.Delegate} methods

    @Override
    @Override
    public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
    public void onCloseEduText() {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: onFocusTaskChanged", TAG);
        mTvPipBoundsState.setPipMenuTemporaryDecorInsets(Insets.NONE);
        mDelegate.closeEduText();
    }
    }


    @Override
    @Override
@@ -439,9 +469,35 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
    }
    }


    @Override
    @Override
    public void onCloseEduText() {
    public boolean onExitMoveMode() {
        mTvPipBoundsState.setPipMenuTemporaryDecorInsets(Insets.NONE);
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        mDelegate.closeEduText();
                "%s: onExitMoveMode - mCurrentMenuMode=%s", TAG, getMenuModeString());

        final int saveMenuMode = mCurrentMenuMode;
        if (isInMoveMode()) {
            switchToMenuMode(mPrevMenuMode);
        }
        return saveMenuMode == MODE_MOVE_MENU;
    }

    @Override
    public boolean onPipMovement(int keycode) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: onPipMovement - mCurrentMenuMode=%s", TAG, getMenuModeString());
        if (isInMoveMode()) {
            mDelegate.movePip(keycode);
        }
        return isInMoveMode();
    }

    @Override
    public void onPipWindowFocusChanged(boolean focused) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: onPipWindowFocusChanged - focused=%b", TAG, focused);
        mMenuIsFocused = focused;
        if (!focused && isMenuOpen()) {
            closeMenu();
        }
    }
    }


    interface Delegate {
    interface Delegate {
@@ -455,6 +511,8 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
    }
    }


    private void grantPipMenuFocus(boolean grantFocus) {
    private void grantPipMenuFocus(boolean grantFocus) {
        if (mMenuIsFocused == grantFocus) return;

        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: grantWindowFocus(%b)", TAG, grantFocus);
                "%s: grantWindowFocus(%b)", TAG, grantFocus);


+95 −53
Original line number Original line Diff line number Diff line
@@ -26,6 +26,9 @@ import static android.view.KeyEvent.KEYCODE_DPAD_UP;
import static android.view.KeyEvent.KEYCODE_ENTER;
import static android.view.KeyEvent.KEYCODE_ENTER;


import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_MOVE;
import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_MOVE;
import static com.android.wm.shell.pip.tv.TvPipMenuController.MODE_ALL_ACTIONS_MENU;
import static com.android.wm.shell.pip.tv.TvPipMenuController.MODE_MOVE_MENU;
import static com.android.wm.shell.pip.tv.TvPipMenuController.MODE_NO_MENU;


import android.content.Context;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.Rect;
@@ -86,9 +89,9 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
    private final ImageView mArrowLeft;
    private final ImageView mArrowLeft;
    private final TvWindowMenuActionButton mA11yDoneButton;
    private final TvWindowMenuActionButton mA11yDoneButton;


    private Rect mCurrentPipBounds;
    private @TvPipMenuController.TvPipMenuMode int mCurrentMenuMode = MODE_NO_MENU;
    private boolean mMoveMenuIsVisible;
    private final Rect mCurrentPipBounds = new Rect();
    private boolean mButtonMenuIsVisible;
    private int mCurrentPipGravity;
    private boolean mSwitchingOrientation;
    private boolean mSwitchingOrientation;


    private final AccessibilityManager mA11yManager;
    private final AccessibilityManager mA11yManager;
@@ -172,7 +175,7 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
            return;
            return;
        }
        }


        if (mButtonMenuIsVisible) {
        if (mCurrentMenuMode == MODE_ALL_ACTIONS_MENU) {
            mSwitchingOrientation = true;
            mSwitchingOrientation = true;
            mActionButtonsRecyclerView.animate()
            mActionButtonsRecyclerView.animate()
                    .alpha(0)
                    .alpha(0)
@@ -217,19 +220,14 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
    /**
    /**
     * Also updates the button gravity.
     * Also updates the button gravity.
     */
     */
    void updateBounds(Rect updatedBounds) {
    void setPipBounds(Rect updatedPipBounds) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: updateLayout, width: %s, height: %s", TAG, updatedBounds.width(),
                "%s: updateLayout, width: %s, height: %s", TAG, updatedPipBounds.width(),
                updatedBounds.height());
                updatedPipBounds.height());
        mCurrentPipBounds = updatedBounds;
        if (updatedPipBounds.equals(mCurrentPipBounds)) return;
        updatePipFrameBounds();
    }


    Rect getPipMenuContainerBounds(Rect pipBounds) {
        mCurrentPipBounds.set(updatedPipBounds);
        final Rect menuUiBounds = new Rect(pipBounds);
        updatePipFrameBounds();
        menuUiBounds.inset(-mPipMenuOuterSpace, -mPipMenuOuterSpace);
        menuUiBounds.bottom += mEduTextDrawer.getHeight();
        return menuUiBounds;
    }
    }


    /**
    /**
@@ -264,12 +262,39 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
        }
        }
    }
    }


    /**
    Rect getPipMenuContainerBounds(Rect pipBounds) {
     * @param gravity for the arrow hints
        final Rect menuUiBounds = new Rect(pipBounds);
     */
        menuUiBounds.inset(-mPipMenuOuterSpace, -mPipMenuOuterSpace);
    void showMoveMenu(int gravity) {
        menuUiBounds.bottom += mEduTextDrawer.getHeight();
        return menuUiBounds;
    }

    void transitionToMenuMode(int menuMode, boolean resetMenu) {
        switch (menuMode) {
            case MODE_NO_MENU:
                hideAllUserControls();
                break;
            case MODE_MOVE_MENU:
                showMoveMenu();
                break;
            case MODE_ALL_ACTIONS_MENU:
                showAllActionsMenu(resetMenu);
                break;
            default:
                throw new IllegalArgumentException(
                        "Unknown TV PiP menu mode: "
                        + TvPipMenuController.getMenuModeString(mCurrentMenuMode));
        }

        mCurrentMenuMode = menuMode;
    }

    private void showMoveMenu() {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMoveMenu()", TAG);
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, "%s: showMoveMenu()", TAG);
        showMovementHints(gravity);

        if (mCurrentMenuMode == MODE_MOVE_MENU) return;

        showMovementHints();
        setMenuButtonsVisible(false);
        setMenuButtonsVisible(false);
        setFrameHighlighted(true);
        setFrameHighlighted(true);


@@ -278,32 +303,38 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
        mEduTextDrawer.closeIfNeeded();
        mEduTextDrawer.closeIfNeeded();
    }
    }



    private void showAllActionsMenu(boolean resetMenu) {
    void showButtonsMenu(boolean exitingMoveMode) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: showButtonsMenu(), exitingMoveMode %b", TAG, exitingMoveMode);
                "%s: showAllActionsMenu(), resetMenu %b", TAG, resetMenu);

        if (resetMenu) {
            scrollToFirstAction();
        }

        if (mCurrentMenuMode == MODE_ALL_ACTIONS_MENU) return;

        setMenuButtonsVisible(true);
        setMenuButtonsVisible(true);
        hideMovementHints();
        hideMovementHints();
        setFrameHighlighted(true);
        setFrameHighlighted(true);
        animateAlphaTo(1f, mDimLayer);
        animateAlphaTo(1f, mDimLayer);
        mEduTextDrawer.closeIfNeeded();
        mEduTextDrawer.closeIfNeeded();


        if (exitingMoveMode) {
        if (mCurrentMenuMode == MODE_MOVE_MENU) {
            scrollAndRefocusButton(mTvPipActionsProvider.getFirstIndexOfAction(ACTION_MOVE),
            refocusButton(mTvPipActionsProvider.getFirstIndexOfAction(ACTION_MOVE));
                    /* alwaysScroll= */ false);
        } else {
            scrollAndRefocusButton(0, /* alwaysScroll= */ true);
        }
        }
        }


    private void scrollAndRefocusButton(int position, boolean alwaysScroll) {
    }
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: scrollAndRefocusButton, target: %d", TAG, position);


        if (alwaysScroll || !refocusButton(position)) {
    private void scrollToFirstAction() {
            mButtonLayoutManager.scrollToPositionWithOffset(position, 0);
        // Clearing the focus here is necessary to allow a smooth scroll even if the first action
            mActionButtonsRecyclerView.post(() -> refocusButton(position));
        // is currently not visible.
        final View focusedChild = mActionButtonsRecyclerView.getFocusedChild();
        if (focusedChild != null) {
            focusedChild.clearFocus();
        }
        }

        mButtonLayoutManager.scrollToPosition(0);
        mActionButtonsRecyclerView.post(() -> refocusButton(0));
    }
    }


    /**
    /**
@@ -311,6 +342,9 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
     * the view for the position not being available (scrolling beforehand will be necessary).
     * the view for the position not being available (scrolling beforehand will be necessary).
     */
     */
    private boolean refocusButton(int position) {
    private boolean refocusButton(int position) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: refocusButton, position: %d", TAG, position);

        View itemToFocus = mButtonLayoutManager.findViewByPosition(position);
        View itemToFocus = mButtonLayoutManager.findViewByPosition(position);
        if (itemToFocus != null) {
        if (itemToFocus != null) {
            itemToFocus.requestFocus();
            itemToFocus.requestFocus();
@@ -319,21 +353,29 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
        return itemToFocus != null;
        return itemToFocus != null;
    }
    }


    void hideAllUserControls() {
    private void hideAllUserControls() {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: hideAllUserControls()", TAG);
                "%s: hideAllUserControls()", TAG);

        if (mCurrentMenuMode == MODE_NO_MENU) return;

        setMenuButtonsVisible(false);
        setMenuButtonsVisible(false);
        hideMovementHints();
        hideMovementHints();
        setFrameHighlighted(false);
        setFrameHighlighted(false);
        animateAlphaTo(0f, mDimLayer);
        animateAlphaTo(0f, mDimLayer);
    }
    }


    void setPipGravity(int gravity) {
        mCurrentPipGravity = gravity;
        if (mCurrentMenuMode == MODE_MOVE_MENU) {
            showMovementHints();
        }
    }

    @Override
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        super.onWindowFocusChanged(hasWindowFocus);
        if (!hasWindowFocus) {
        mListener.onPipWindowFocusChanged(hasWindowFocus);
            hideAllUserControls();
        }
    }
    }


    private void animateAlphaTo(float alpha, View view) {
    private void animateAlphaTo(float alpha, View view) {
@@ -399,15 +441,13 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
    /**
    /**
     * Shows user hints for moving the PiP, e.g. arrows.
     * Shows user hints for moving the PiP, e.g. arrows.
     */
     */
    public void showMovementHints(int gravity) {
    public void showMovementHints() {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: showMovementHints(), position: %s", TAG, Gravity.toString(gravity));
                "%s: showMovementHints(), position: %s", TAG, Gravity.toString(mCurrentPipGravity));
        mMoveMenuIsVisible = true;
        animateAlphaTo(checkGravity(mCurrentPipGravity, Gravity.BOTTOM) ? 1f : 0f, mArrowUp);

        animateAlphaTo(checkGravity(mCurrentPipGravity, Gravity.TOP) ? 1f : 0f, mArrowDown);
        animateAlphaTo(checkGravity(gravity, Gravity.BOTTOM) ? 1f : 0f, mArrowUp);
        animateAlphaTo(checkGravity(mCurrentPipGravity, Gravity.RIGHT) ? 1f : 0f, mArrowLeft);
        animateAlphaTo(checkGravity(gravity, Gravity.TOP) ? 1f : 0f, mArrowDown);
        animateAlphaTo(checkGravity(mCurrentPipGravity, Gravity.LEFT) ? 1f : 0f, mArrowRight);
        animateAlphaTo(checkGravity(gravity, Gravity.RIGHT) ? 1f : 0f, mArrowLeft);
        animateAlphaTo(checkGravity(gravity, Gravity.LEFT) ? 1f : 0f, mArrowRight);


        boolean a11yEnabled = mA11yManager.isEnabled();
        boolean a11yEnabled = mA11yManager.isEnabled();
        setArrowA11yEnabled(mArrowUp, a11yEnabled, KEYCODE_DPAD_UP);
        setArrowA11yEnabled(mArrowUp, a11yEnabled, KEYCODE_DPAD_UP);
@@ -446,10 +486,7 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: hideMovementHints()", TAG);
                "%s: hideMovementHints()", TAG);


        if (!mMoveMenuIsVisible) {
        if (mCurrentMenuMode != MODE_MOVE_MENU) return;
            return;
        }
        mMoveMenuIsVisible = false;


        animateAlphaTo(0, mArrowUp);
        animateAlphaTo(0, mArrowUp);
        animateAlphaTo(0, mArrowRight);
        animateAlphaTo(0, mArrowRight);
@@ -464,7 +501,6 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
    private void setMenuButtonsVisible(boolean visible) {
    private void setMenuButtonsVisible(boolean visible) {
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                "%s: showUserActions: %b", TAG, visible);
                "%s: showUserActions: %b", TAG, visible);
        mButtonMenuIsVisible = visible;
        animateAlphaTo(visible ? 1 : 0, mActionButtonsRecyclerView);
        animateAlphaTo(visible ? 1 : 0, mActionButtonsRecyclerView);
    }
    }


@@ -534,5 +570,11 @@ public class TvPipMenuView extends FrameLayout implements TvPipActionsProvider.L
         * @return whether pip movement was handled.
         * @return whether pip movement was handled.
         */
         */
        boolean onPipMovement(int keycode);
        boolean onPipMovement(int keycode);

        /**
         * Called when the TvPipMenuView loses focus. This also means that the TV PiP menu window
         * has lost focus.
         */
        void onPipWindowFocusChanged(boolean focused);
    }
    }
}
}
+324 −0

File added.

Preview size limit exceeded, changes collapsed.