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

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

Fallback to clear disable_gesture_pip_animating

From the bug-report, we do see a series of events
- YT enters PiP
- Another app launches, triggers KCA update
    - sendOnPipTransitionStarted is called, sets the flag
- Somehow, wm_task_moved is triggered around the same time
    - which could be due to Activity#moveTaskToBack call originated from
      the app
- pinned task is removed as a result
    - there is no paired sendOnPipTransitionFinished observed

Work around this issue by forcefully clear the
disable_gesture_pip_animating flag when it's not in pip anymore though
we are unable to reproduce the bug.

Flag: EXEMPT bugfix
Bug: 365084002
Test: manually
Change-Id: I4a1d1882a526070c7826d95525599a42c38a52a7
parent 3885ea04
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -45,12 +45,17 @@ public interface Pip {
    }

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

    /**
     * Remove the callback when isInPip state is changed.
     * @param callback The callback accepts the state of isInPip when it's changed.
     */
    default void removeOnIsInPipStateChangedListener(@NonNull Consumer<Boolean> callback) {}

    /**
     * Called when showing Pip menu.
+25 −11
Original line number Diff line number Diff line
@@ -104,6 +104,7 @@ import com.android.wm.shell.sysui.UserChangeListener;
import com.android.wm.shell.transition.Transitions;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -215,7 +216,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb

    private boolean mIsKeyguardShowingOrAnimating;

    private Consumer<Boolean> mOnIsInPipStateChangedListener;
    private final List<Consumer<Boolean>> mOnIsInPipStateChangedListeners = new ArrayList<>();

    @VisibleForTesting
    interface PipAnimationListener {
@@ -501,11 +502,11 @@ public class PipController implements PipTransitionController.PipTransitionCallb
                    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);
                for (Consumer<Boolean> listener : mOnIsInPipStateChangedListeners) {
                    listener.accept(nowInPip);
                }
            }
        });
@@ -960,13 +961,19 @@ public class PipController implements PipTransitionController.PipTransitionCallb
        mPipBoundsState.getLauncherState().setAppIconSizePx(iconSizePx);
    }

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

    private void removeOnIsInPipStateChangedListener(@NonNull Consumer<Boolean> callback) {
        if (callback != null) {
            mOnIsInPipStateChangedListeners.remove(callback);
        }
    }

    private void setShelfHeightLocked(boolean visible, int height) {
        final int shelfHeight = visible ? height : 0;
        mPipBoundsState.setShelfVisibility(visible, shelfHeight);
@@ -1222,9 +1229,16 @@ public class PipController implements PipTransitionController.PipTransitionCallb
        }

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

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

+26 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;

import static com.android.wm.shell.shared.ShellSharedConstants.KEY_EXTRA_SHELL_PIP;

import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.PictureInPictureParams;
import android.content.ComponentName;
@@ -66,6 +67,8 @@ import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
@@ -94,7 +97,7 @@ public class PipController implements ConfigurationChangeListener,
    private final PipTouchHandler mPipTouchHandler;
    private final ShellExecutor mMainExecutor;
    private final PipImpl mImpl;
    private Consumer<Boolean> mOnIsInPipStateChangedListener;
    private final List<Consumer<Boolean>> mOnIsInPipStateChangedListeners = new ArrayList<>();

    // Wrapper for making Binder calls into PiP animation listener hosted in launcher's Recents.
    private PipAnimationListener mPipRecentsAnimationListener;
@@ -413,13 +416,13 @@ public class PipController implements ConfigurationChangeListener,
                if (mPipTransitionState.isInSwipePipToHomeTransition()) {
                    mPipTransitionState.resetSwipePipToHomeState();
                }
                if (mOnIsInPipStateChangedListener != null) {
                    mOnIsInPipStateChangedListener.accept(true /* inPip */);
                for (Consumer<Boolean> listener : mOnIsInPipStateChangedListeners) {
                    listener.accept(true /* inPip */);
                }
                break;
            case PipTransitionState.EXITED_PIP:
                if (mOnIsInPipStateChangedListener != null) {
                    mOnIsInPipStateChangedListener.accept(false /* inPip */);
                for (Consumer<Boolean> listener : mOnIsInPipStateChangedListeners) {
                    listener.accept(false /* inPip */);
                }
                break;
        }
@@ -451,13 +454,19 @@ public class PipController implements ConfigurationChangeListener,
        mPipTransitionState.dump(pw, innerPrefix);
    }

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

    private void removeOnIsInPipStateChangedListener(@NonNull Consumer<Boolean> callback) {
        if (callback != null) {
            mOnIsInPipStateChangedListeners.remove(callback);
        }
    }

    private void setLauncherAppIconSize(int iconSizePx) {
        mPipBoundsState.getLauncherState().setAppIconSizePx(iconSizePx);
    }
@@ -473,9 +482,16 @@ public class PipController implements ConfigurationChangeListener,
        public void onSystemUiStateChanged(boolean isSysUiStateValid, long flag) {}

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

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

+3 −2
Original line number Diff line number Diff line
@@ -696,7 +696,8 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
                TaskStackChangeListeners.getInstance().unregisterTaskStackListener(
                        mTaskStackListener);
                DeviceConfig.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
                mPipOptional.ifPresent(pip -> pip.setOnIsInPipStateChangedListener(null));
                mPipOptional.ifPresent(pip -> pip.removeOnIsInPipStateChangedListener(
                        mOnIsInPipStateChangedListener));

                try {
                    mWindowManagerService.unregisterSystemGestureExclusionListener(
@@ -720,7 +721,7 @@ public class EdgeBackGestureHandler implements PluginListener<NavigationEdgeBack
                        mTaskStackListener);
                DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
                        mUiThreadContext.getExecutor()::execute, mOnPropertiesChangedListener);
                mPipOptional.ifPresent(pip -> pip.setOnIsInPipStateChangedListener(
                mPipOptional.ifPresent(pip -> pip.addOnIsInPipStateChangedListener(
                        mOnIsInPipStateChangedListener));
                mDesktopModeOptional.ifPresent(
                        dm -> dm.addDesktopGestureExclusionRegionListener(
+6 −0
Original line number Diff line number Diff line
@@ -271,6 +271,12 @@ public final class WMShell implements
                        // No op.
                    }
                }, mSysUiMainExecutor);
        pip.addOnIsInPipStateChangedListener((isInPip) -> {
            if (!isInPip) {
                mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING, false)
                        .commitUpdate(mDisplayTracker.getDefaultDisplayId());
            }
        });
        mSysUiState.addCallback(sysUiStateFlag -> {
            mIsSysUiStateValid = (sysUiStateFlag & INVALID_SYSUI_STATE_MASK) == 0;
            pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag);