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

Commit 70a456e9 authored by Ikram Gabiyev's avatar Ikram Gabiyev
Browse files

Allow exclusion areas in PiP2

Set up Pip interface in PipController in pip2,
so that other components in the host process can
communicate with PiP.

In this specific CL, allow to add exclusion area update
callbacks, that are executed every time PiP bounds change.

This helps avoid back gesture to appear when PiP is stashed for instance
inside the PiP region.

Bug: 352552598
Flag: com.android.wm.shell.enable_pip2_implementation
Test: stash PiP and attempt a back gesture in PiP region
Change-Id: Ic68cf0e960cde77b9dbf88afb09f178edef68b3c
parent e5bad4c4
Loading
Loading
Loading
Loading
+11 −17
Original line number Diff line number Diff line
@@ -38,12 +38,10 @@ import com.android.wm.shell.common.pip.PipMediaController;
import com.android.wm.shell.common.pip.PipPerfHintController;
import com.android.wm.shell.common.pip.PipSnapAlgorithm;
import com.android.wm.shell.common.pip.PipUiEventLogger;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.common.pip.SizeSpecSource;
import com.android.wm.shell.dagger.WMShellBaseModule;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.onehanded.OneHandedController;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipAnimationController;
import com.android.wm.shell.pip.PipParamsChangedForwarder;
import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
@@ -79,7 +77,7 @@ import java.util.Optional;
public abstract class Pip1Module {
    @WMSingleton
    @Provides
    static Optional<Pip> providePip1(Context context,
    static Optional<PipController.PipImpl> providePip1(Context context,
            ShellInit shellInit,
            ShellCommandHandler shellCommandHandler,
            ShellController shellController,
@@ -104,9 +102,6 @@ public abstract class Pip1Module {
            TabletopModeController pipTabletopController,
            Optional<OneHandedController> oneHandedController,
            @ShellMainThread ShellExecutor mainExecutor) {
        if (PipUtils.isPip2ExperimentEnabled()) {
            return Optional.empty();
        } else {
        return Optional.ofNullable(PipController.create(
                context, shellInit, shellCommandHandler, shellController,
                displayController, pipAnimationController, pipAppOpsListener,
@@ -118,7 +113,6 @@ public abstract class Pip1Module {
                displayInsetsController, pipTabletopController, oneHandedController,
                mainExecutor));
    }
    }

    // Handler is used by Icon.loadDrawableAsync
    @WMSingleton
+10 −0
Original line number Diff line number Diff line
@@ -79,6 +79,16 @@ public abstract class Pip2Module {
                pipStackListenerController);
    }

    @WMSingleton
    @Provides
    static Optional<PipController.PipImpl> providePip2(Optional<PipController> pipController) {
        if (pipController.isEmpty()) {
            return Optional.empty();
        } else {
            return Optional.ofNullable(pipController.get().getPipImpl());
        }
    }

    @WMSingleton
    @Provides
    static Optional<PipController> providePipController(Context context,
+17 −0
Original line number Diff line number Diff line
@@ -18,12 +18,16 @@ package com.android.wm.shell.dagger.pip;

import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.dagger.WMSingleton;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip2.phone.PipController;
import com.android.wm.shell.pip2.phone.PipTransition;

import dagger.Module;
import dagger.Provides;

import java.util.Optional;

/**
 * Provides dependencies for external components / modules reference PiP and extracts away the
 * selection of legacy and new PiP implementation.
@@ -44,4 +48,17 @@ public abstract class PipModule {
            return legacyPipTransition;
        }
    }

    @WMSingleton
    @Provides
    static Optional<Pip> providePip(
            Optional<com.android.wm.shell.pip.phone.PipController.PipImpl> pip1,
            Optional<PipController.PipImpl> pip2) {
        if (PipUtils.isPip2ExperimentEnabled()) {
            return Optional.ofNullable(pip2.orElse(null));

        } else {
            return Optional.ofNullable(pip1.orElse(null));
        }
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -374,7 +374,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
     * Instantiates {@link PipController}, returns {@code null} if the feature not supported.
     */
    @Nullable
    public static Pip create(Context context,
    public static PipImpl create(Context context,
            ShellInit shellInit,
            ShellCommandHandler shellCommandHandler,
            ShellController shellController,
@@ -1177,7 +1177,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb
    /**
     * The interface for calls from outside the Shell, within the host process.
     */
    private class PipImpl implements Pip {
    public class PipImpl implements Pip {
        @Override
        public void expandPip() {
            mMainExecutor.execute(() -> {
+81 −16
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
import com.android.wm.shell.common.pip.PipBoundsState;
import com.android.wm.shell.common.pip.PipDisplayLayoutState;
import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
@@ -62,6 +64,8 @@ import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;

import java.io.PrintWriter;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

/**
 * Manages the picture-in-picture (PIP) UI and states for Phones.
@@ -86,6 +90,8 @@ public class PipController implements ConfigurationChangeListener,
    private final ShellTaskOrganizer mShellTaskOrganizer;
    private final PipTransitionState mPipTransitionState;
    private final ShellExecutor mMainExecutor;
    private final PipImpl mImpl;
    private Consumer<Boolean> mOnIsInPipStateChangedListener;

    // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents.
    private PipAnimationListener mPipRecentsAnimationListener;
@@ -140,6 +146,7 @@ public class PipController implements ConfigurationChangeListener,
        mPipTransitionState = pipTransitionState;
        mPipTransitionState.addPipTransitionStateChangedListener(this);
        mMainExecutor = mainExecutor;
        mImpl = new PipImpl();

        if (PipUtils.isPip2ExperimentEnabled()) {
            shellInit.addInitCallback(this::onInit, this);
@@ -174,6 +181,10 @@ public class PipController implements ConfigurationChangeListener,
                pipTransitionState, mainExecutor);
    }

    public PipImpl getPipImpl() {
        return mImpl;
    }

    private void onInit() {
        mShellCommandHandler.addDumpCallback(this::dump, this);
        // Ensure that we have the display info in case we get calls to update the bounds before the
@@ -310,7 +321,8 @@ public class PipController implements ConfigurationChangeListener,
    @Override
    public void onPipTransitionStateChanged(@PipTransitionState.TransitionState int oldState,
            @PipTransitionState.TransitionState int newState, @Nullable Bundle extra) {
        if (newState == PipTransitionState.SWIPING_TO_PIP) {
        switch (newState) {
            case PipTransitionState.SWIPING_TO_PIP:
                Preconditions.checkState(extra != null,
                        "No extra bundle for " + mPipTransitionState);

@@ -322,10 +334,16 @@ public class PipController implements ConfigurationChangeListener,
                Preconditions.checkState(appBounds != null,
                        "App bounds can't be null for " + mPipTransitionState);
                mPipTransitionState.setSwipePipToHomeState(overlay, appBounds);
        } else if (newState == PipTransitionState.ENTERED_PIP) {
                break;
            case PipTransitionState.ENTERED_PIP:
                if (mPipTransitionState.isInSwipePipToHomeTransition()) {
                    mPipTransitionState.resetSwipePipToHomeState();
                }
                mOnIsInPipStateChangedListener.accept(true /* inPip */);
                break;
            case PipTransitionState.EXITED_PIP:
                mOnIsInPipStateChangedListener.accept(false /* inPip */);
                break;
        }
    }

@@ -355,6 +373,53 @@ public class PipController implements ConfigurationChangeListener,
        mPipTransitionState.dump(pw, innerPrefix);
    }

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

    /**
     * The interface for calls from outside the Shell, within the host process.
     */
    public class PipImpl implements Pip {
        @Override
        public void expandPip() {}

        @Override
        public void onSystemUiStateChanged(boolean isSysUiStateValid, long flag) {}

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

        @Override
        public void addPipExclusionBoundsChangeListener(Consumer<Rect> listener) {
            mMainExecutor.execute(() -> {
                mPipBoundsState.addPipExclusionBoundsChangeCallback(listener);
            });
        }

        @Override
        public void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) {
            mMainExecutor.execute(() -> {
                mPipBoundsState.removePipExclusionBoundsChangeCallback(listener);
            });
        }

        @Override
        public void showPictureInPictureMenu() {}

        @Override
        public void registerPipTransitionCallback(
                PipTransitionController.PipTransitionCallback callback,
                Executor executor) {}
    }

    /**
     * The interface for calls from outside the host process.
     */