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

Commit e9e4ca3e authored by Hongwei Wang's avatar Hongwei Wang
Browse files

Get PiP state from Shell in EdgeBackGestureHandler

We use to rely on the onActivityPinned and onActivityUnpinned callbacks
from Window Manager in EdgeBackGestureHandler to determine the current
PiP state and it will always be reset to false when
EdgeBackGestureHandler is being re-created, for instance, as a result of
folded state change.

Deprecated also the Pip#setPinnedStackAnimationListener interface method
since it's not in use and it may cause confusions over
IPip#setPinnedStackAnimationListener.

Bug: 174702196
Bug: 198651351
Test: stash in unfolded state -> fold -> drag to unstash \
      stash in folded state -> unfold -> drag to unstash
Test: atest WMShellUnitTests:PipControllerTest
Change-Id: Id874056415011ee8a55dadcd4ec6af6e1b568092
parent 0c83561a
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -68,15 +68,15 @@ import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.transition.Transitions;
import com.android.wm.shell.unfold.UnfoldAnimationController;
import com.android.wm.shell.unfold.ShellUnfoldProgressProvider;
import com.android.wm.shell.unfold.UnfoldAnimationController;
import com.android.wm.shell.unfold.UnfoldBackgroundController;
import com.android.wm.shell.unfold.UnfoldTransitionHandler;
import com.android.wm.shell.unfold.animation.FullscreenUnfoldTaskAnimator;
import com.android.wm.shell.unfold.animation.SplitTaskUnfoldAnimator;
import com.android.wm.shell.unfold.animation.UnfoldTaskAnimator;
import com.android.wm.shell.unfold.qualifier.UnfoldTransition;
import com.android.wm.shell.unfold.qualifier.UnfoldShellTransition;
import com.android.wm.shell.unfold.qualifier.UnfoldTransition;
import com.android.wm.shell.windowdecor.CaptionWindowDecorViewModel;
import com.android.wm.shell.windowdecor.WindowDecorViewModel;

@@ -218,6 +218,7 @@ public abstract class WMShellModule {
            PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
            PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
            PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
            PipTransitionState pipTransitionState,
            PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
            WindowManagerShellWrapper windowManagerShellWrapper,
            TaskStackListenerImpl taskStackListener,
@@ -227,7 +228,7 @@ public abstract class WMShellModule {
        return Optional.ofNullable(PipController.create(context, displayController,
                pipAppOpsListener, pipBoundsAlgorithm, pipKeepClearAlgorithm, pipBoundsState,
                pipMotionHelper,
                pipMediaController, phonePipMenuController, pipTaskOrganizer,
                pipMediaController, phonePipMenuController, pipTaskOrganizer, pipTransitionState,
                pipTouchHandler, pipTransitionController, windowManagerShellWrapper,
                taskStackListener, pipParamsChangedForwarder, oneHandedController, mainExecutor));
    }
+4 −4
Original line number Diff line number Diff line
@@ -86,12 +86,12 @@ public interface Pip {
    }

    /**
     * Registers the pinned stack animation listener.
     * Set the callback when {@link PipTaskOrganizer#isInPip()} state is changed.
     *
     * @param callback The callback of pinned stack animation.
     * @param callback The callback accepts the result of {@link PipTaskOrganizer#isInPip()}
     *                 when it's changed.
     */
    default void setPinnedStackAnimationListener(Consumer<Boolean> callback) {
    }
    default void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {}

    /**
     * Set the pinned stack with {@link PipAnimationController.AnimationType}
+33 −3
Original line number Diff line number Diff line
@@ -17,12 +17,15 @@
package com.android.wm.shell.pip;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.app.PictureInPictureParams;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

/**
 * Used to keep track of PiP leash state as it appears and animates by {@link PipTaskOrganizer} and
@@ -37,6 +40,9 @@ public class PipTransitionState {
    public static final int ENTERED_PIP = 4;
    public static final int EXITING_PIP = 5;

    private final List<OnPipTransitionStateChangedListener> mOnPipTransitionStateChangedListeners =
            new ArrayList<>();

    /**
     * If set to {@code true}, no entering PiP transition would be kicked off and most likely
     * it's due to the fact that Launcher is handling the transition directly when swiping
@@ -65,16 +71,21 @@ public class PipTransitionState {
    }

    public void setTransitionState(@TransitionState int state) {
        if (mState != state) {
            for (int i = 0; i < mOnPipTransitionStateChangedListeners.size(); i++) {
                mOnPipTransitionStateChangedListeners.get(i).onPipTransitionStateChanged(
                        mState, state);
            }
            mState = state;
        }
    }

    public @TransitionState int getTransitionState() {
        return mState;
    }

    public boolean isInPip() {
        return mState >= TASK_APPEARED
                && mState != EXITING_PIP;
        return isInPip(mState);
    }

    public void setInSwipePipToHomeTransition(boolean inSwipePipToHomeTransition) {
@@ -94,4 +105,23 @@ public class PipTransitionState {
        return mState < ENTERING_PIP
                || mState == EXITING_PIP;
    }

    public void addOnPipTransitionStateChangedListener(
            @NonNull OnPipTransitionStateChangedListener listener) {
        mOnPipTransitionStateChangedListeners.add(listener);
    }

    public void removeOnPipTransitionStateChangedListener(
            @NonNull OnPipTransitionStateChangedListener listener) {
        mOnPipTransitionStateChangedListeners.remove(listener);
    }

    public static boolean isInPip(@TransitionState int state) {
        return state >= TASK_APPEARED && state != EXITING_PIP;
    }

    public interface OnPipTransitionStateChangedListener {
        void onPipTransitionStateChanged(@TransitionState int oldState,
                @TransitionState int newState);
    }
}
+32 −1
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.PipTransitionState;
import com.android.wm.shell.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.transition.Transitions;
@@ -128,11 +129,14 @@ public class PipController implements PipTransitionController.PipTransitionCallb

    protected PhonePipMenuController mMenuController;
    protected PipTaskOrganizer mPipTaskOrganizer;
    private PipTransitionState mPipTransitionState;
    protected PinnedStackListenerForwarder.PinnedTaskListener mPinnedTaskListener =
            new PipControllerPinnedTaskListener();

    private boolean mIsKeyguardShowingOrAnimating;

    private Consumer<Boolean> mOnIsInPipStateChangedListener;

    private interface PipAnimationListener {
        /**
         * Notifies the listener that the Pip animation is started.
@@ -291,6 +295,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
            PipKeepClearAlgorithm pipKeepClearAlgorithm, PipBoundsState pipBoundsState,
            PipMotionHelper pipMotionHelper, PipMediaController pipMediaController,
            PhonePipMenuController phonePipMenuController, PipTaskOrganizer pipTaskOrganizer,
            PipTransitionState pipTransitionState,
            PipTouchHandler pipTouchHandler, PipTransitionController pipTransitionController,
            WindowManagerShellWrapper windowManagerShellWrapper,
            TaskStackListenerImpl taskStackListener,
@@ -305,7 +310,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb

        return new PipController(context, displayController, pipAppOpsListener, pipBoundsAlgorithm,
                pipKeepClearAlgorithm, pipBoundsState, pipMotionHelper, pipMediaController,
                phonePipMenuController, pipTaskOrganizer, pipTouchHandler, pipTransitionController,
                phonePipMenuController, pipTaskOrganizer, pipTransitionState,
                pipTouchHandler, pipTransitionController,
                windowManagerShellWrapper, taskStackListener, pipParamsChangedForwarder,
                oneHandedController, mainExecutor)
                .mImpl;
@@ -321,6 +327,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
            PipMediaController pipMediaController,
            PhonePipMenuController phonePipMenuController,
            PipTaskOrganizer pipTaskOrganizer,
            PipTransitionState pipTransitionState,
            PipTouchHandler pipTouchHandler,
            PipTransitionController pipTransitionController,
            WindowManagerShellWrapper windowManagerShellWrapper,
@@ -344,6 +351,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
        mPipBoundsState = pipBoundsState;
        mPipMotionHelper = pipMotionHelper;
        mPipTaskOrganizer = pipTaskOrganizer;
        mPipTransitionState = pipTransitionState;
        mMainExecutor = mainExecutor;
        mMediaController = pipMediaController;
        mMenuController = phonePipMenuController;
@@ -370,6 +378,15 @@ public class PipController implements PipTransitionController.PipTransitionCallb
            onDisplayChanged(mDisplayController.getDisplayLayout(displayId),
                    false /* saveRestoreSnapFraction */);
        });
        mPipTransitionState.addOnPipTransitionStateChangedListener((oldState, newState) -> {
            if (mOnIsInPipStateChangedListener != null) {
                final boolean wasInPip = PipTransitionState.isInPip(oldState);
                final boolean nowInPip = PipTransitionState.isInPip(newState);
                if (nowInPip != wasInPip) {
                    mOnIsInPipStateChangedListener.accept(nowInPip);
                }
            }
        });
        mPipBoundsState.setOnMinimalSizeChangeCallback(
                () -> {
                    // The minimal size drives the normal bounds, so they need to be recalculated.
@@ -664,6 +681,13 @@ public class PipController implements PipTransitionController.PipTransitionCallb
        }
    }

    private void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {
        mOnIsInPipStateChangedListener = callback;
        if (mOnIsInPipStateChangedListener != null) {
            callback.accept(mPipTransitionState.isInPip());
        }
    }

    private void setShelfHeightLocked(boolean visible, int height) {
        final int shelfHeight = visible ? height : 0;
        mPipBoundsState.setShelfVisibility(visible, shelfHeight);
@@ -940,6 +964,13 @@ public class PipController implements PipTransitionController.PipTransitionCallb
            });
        }

        @Override
        public void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {
            mMainExecutor.execute(() -> {
                PipController.this.setOnIsInPipStateChangedListener(callback);
            });
        }

        @Override
        public void setPinnedStackAnimationType(int animationType) {
            mMainExecutor.execute(() -> {
+6 −4
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.PipTaskOrganizer;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.PipTransitionState;

import org.junit.Before;
import org.junit.Test;
@@ -80,6 +81,7 @@ public class PipControllerTest extends ShellTestCase {
    @Mock private PipSnapAlgorithm mMockPipSnapAlgorithm;
    @Mock private PipMediaController mMockPipMediaController;
    @Mock private PipTaskOrganizer mMockPipTaskOrganizer;
    @Mock private PipTransitionState mMockPipTransitionState;
    @Mock private PipTransitionController mMockPipTransitionController;
    @Mock private PipTouchHandler mMockPipTouchHandler;
    @Mock private PipMotionHelper mMockPipMotionHelper;
@@ -104,8 +106,8 @@ public class PipControllerTest extends ShellTestCase {
                mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
                mMockPipKeepClearAlgorithm,
                mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
                mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler,
                mMockPipTransitionController, mMockWindowManagerShellWrapper,
                mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTransitionState,
                mMockPipTouchHandler, mMockPipTransitionController, mMockWindowManagerShellWrapper,
                mMockTaskStackListener, mPipParamsChangedForwarder,
                mMockOneHandedController, mMockExecutor);
        when(mMockPipBoundsAlgorithm.getSnapAlgorithm()).thenReturn(mMockPipSnapAlgorithm);
@@ -138,8 +140,8 @@ public class PipControllerTest extends ShellTestCase {
                mMockPipAppOpsListener, mMockPipBoundsAlgorithm,
                mMockPipKeepClearAlgorithm,
                mMockPipBoundsState, mMockPipMotionHelper, mMockPipMediaController,
                mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTouchHandler,
                mMockPipTransitionController, mMockWindowManagerShellWrapper,
                mMockPhonePipMenuController, mMockPipTaskOrganizer, mMockPipTransitionState,
                mMockPipTouchHandler, mMockPipTransitionController, mMockWindowManagerShellWrapper,
                mMockTaskStackListener, mPipParamsChangedForwarder,
                mMockOneHandedController, mMockExecutor));
    }
Loading