summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hongwei Wang <hwwang@google.com> 2024-11-06 16:45:20 -0800
committer Hongwei Wang <hwwang@google.com> 2024-11-07 16:31:50 -0800
commitfb29cc0328e9de6a11ca2c1f6e091c8448fc1936 (patch)
tree19a04d8e7d3f63ec375ff7a00a4de18caab6ce3c
parent3885ea044727f2f7a24e32449c3a9c538ba1febd (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
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java13
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java36
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java6
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);