diff options
| author | 2024-11-06 16:45:20 -0800 | |
|---|---|---|
| committer | 2024-11-07 16:31:50 -0800 | |
| commit | fb29cc0328e9de6a11ca2c1f6e091c8448fc1936 (patch) | |
| tree | 19a04d8e7d3f63ec375ff7a00a4de18caab6ce3c | |
| parent | 3885ea044727f2f7a24e32449c3a9c538ba1febd (diff) | |
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
5 files changed, 69 insertions, 27 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java index b27c428f1693..0154d0455e50 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java @@ -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. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 7f6118689dad..588b88753eb9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -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); + final boolean wasInPip = PipTransitionState.isInPip(oldState); + final boolean nowInPip = PipTransitionState.isInPip(newState); + if (nowInPip != wasInPip) { + 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); }); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java index d3f537b8f904..bc0918331168 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java @@ -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); }); } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java index 53177de89733..e5cf3c6b17f0 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java @@ -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( diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java index 8039e00159f0..073781e6101d 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java @@ -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); |