Fix RemoteTargetGluer crash
- Updated DesktopVisibilityController to track the numer of visible
freeform windows, and use it to initialize RemoteTargetGluer.
- Updated IDesktopTaskListener to observe visible freeform windows count
- Added resize remoteTargetHandles logic in RemoteTargetGLuer to update
handles size with targets.apps.size on assign.
- This is a workaround and should be removed when RemoteTargetGLuer
intialisation logic is refactored.
Bug: 288121021
Flag: None
Test: Manual
Change-Id: I0297616b4a140fac810c9736bddf6f817d0a98ed
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index b7e1092..2d4894c 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -49,7 +49,7 @@
"persist.wm.debug.desktop_stashing", false);
private final Launcher mLauncher;
- private boolean mFreeformTasksVisible;
+ private int mVisibleFreeformTasksCount;
private boolean mInOverviewState;
private boolean mBackgroundStateEnabled;
private boolean mGestureInProgress;
@@ -68,13 +68,13 @@
public void registerSystemUiListener() {
mDesktopTaskListener = new IDesktopTaskListener.Stub() {
@Override
- public void onVisibilityChanged(int displayId, boolean visible) {
+ public void onTasksVisibilityChanged(int displayId, int visibleTasksCount) {
MAIN_EXECUTOR.execute(() -> {
if (displayId == mLauncher.getDisplayId()) {
if (DEBUG) {
- Log.d(TAG, "desktop visibility changed value=" + visible);
+ Log.d(TAG, "desktop visible tasks count changed=" + visibleTasksCount);
}
- setFreeformTasksVisible(visible);
+ setVisibleFreeformTasksCount(visibleTasksCount);
}
});
}
@@ -112,39 +112,53 @@
* Whether freeform windows are visible in desktop mode.
*/
public boolean areFreeformTasksVisible() {
+ boolean freeformTasksVisible = mVisibleFreeformTasksCount > 0;
if (DEBUG) {
- Log.d(TAG, "areFreeformTasksVisible: freeformVisible=" + mFreeformTasksVisible
+ Log.d(TAG, "areFreeformTasksVisible: freeformVisible=" + freeformTasksVisible
+ " overview=" + mInOverviewState);
}
- return mFreeformTasksVisible && !mInOverviewState;
+ return freeformTasksVisible && !mInOverviewState;
}
/**
- * Sets whether freeform windows are visible and updates launcher visibility based on that.
+ * Number of visible freeform windows in desktop mode.
*/
- public void setFreeformTasksVisible(boolean freeformTasksVisible) {
+ public int getVisibleFreeformTasksCount() {
+ return mVisibleFreeformTasksCount;
+ }
+
+ /**
+ * Sets the number of freeform windows that are visible and updates launcher visibility based on
+ * it.
+ */
+ public void setVisibleFreeformTasksCount(int visibleTasksCount) {
if (DEBUG) {
- Log.d(TAG, "setFreeformTasksVisible: visible=" + freeformTasksVisible
- + " currentValue=" + mFreeformTasksVisible);
+ Log.d(TAG, "setVisibleFreeformTasksCount: visibleTasksCount=" + visibleTasksCount
+ + " currentValue=" + mVisibleFreeformTasksCount);
}
if (!isDesktopModeSupported()) {
return;
}
- if (freeformTasksVisible != mFreeformTasksVisible) {
- mFreeformTasksVisible = freeformTasksVisible;
- if (mFreeformTasksVisible) {
- setLauncherViewsVisibility(View.INVISIBLE);
- if (!mInOverviewState) {
- // When freeform is visible & we're not in overview, we want launcher to appear
- // paused, this ensures that taskbar displays.
- markLauncherPaused();
+ if (visibleTasksCount != mVisibleFreeformTasksCount) {
+ final boolean wasVisible = mVisibleFreeformTasksCount > 0;
+ final boolean isVisible = visibleTasksCount > 0;
+ mVisibleFreeformTasksCount = visibleTasksCount;
+
+ if (wasVisible != isVisible) {
+ if (mVisibleFreeformTasksCount > 0) {
+ setLauncherViewsVisibility(View.INVISIBLE);
+ if (!mInOverviewState) {
+ // When freeform is visible & we're not in overview, we want launcher to
+ // appear paused, this ensures that taskbar displays.
+ markLauncherPaused();
+ }
+ } else {
+ setLauncherViewsVisibility(View.VISIBLE);
+ // If freeform isn't visible ensure that launcher appears resumed to behave
+ // normally.
+ markLauncherResumed();
}
- } else {
- setLauncherViewsVisibility(View.VISIBLE);
- // If freeform isn't visible ensure that launcher appears resumed to behave
- // normally.
- markLauncherResumed();
}
}
}
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index 98d0ece..c25f244 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -27,6 +27,7 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.TaskViewSimulator;
@@ -62,13 +63,16 @@
*/
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
if (isDesktopModeSupported()) {
- // TODO(279931899): binder call, only for prototyping. Creating the gluer should be
- // postponed so we can create it when we have the remote animation targets ready.
- int desktopTasks = SystemUiProxy.INSTANCE.get(context).getVisibleDesktopTaskCount(
- context.getDisplayId());
- if (desktopTasks > 0) {
- init(context, sizingStrategy, desktopTasks, true /* forDesktop */);
- return;
+ DesktopVisibilityController desktopVisibilityController =
+ LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
+ if (desktopVisibilityController != null) {
+ int visibleTasksCount = desktopVisibilityController.getVisibleFreeformTasksCount();
+ if (visibleTasksCount > 0) {
+ // Allocate +1 to account for a new task added to the desktop mode
+ int numHandles = visibleTasksCount + 1;
+ init(context, sizingStrategy, numHandles, true /* forDesktop */);
+ return;
+ }
}
}
@@ -129,18 +133,7 @@
* the left/top task, index 1 right/bottom.
*/
public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets) {
- // Resize the mRemoteTargetHandles array since we started assuming split screen, but
- // targets.apps is the ultimate source of truth here
- long appCount = Arrays.stream(targets.apps)
- .filter(app -> app.mode == targets.targetMode)
- .count();
- Log.d(TAG, "appCount: " + appCount + " handleLength: " + mRemoteTargetHandles.length);
- if (appCount < mRemoteTargetHandles.length) {
- Log.d(TAG, "resizing handles");
- RemoteTargetHandle[] newHandles = new RemoteTargetHandle[(int) appCount];
- System.arraycopy(mRemoteTargetHandles, 0/*src*/, newHandles, 0/*dst*/, (int) appCount);
- mRemoteTargetHandles = newHandles;
- }
+ resizeRemoteTargetHandles(targets);
// If we are in a true split screen case (2 apps running on screen), either:
// a) mSplitBounds was already set (from the clicked GroupedTaskView)
@@ -198,6 +191,8 @@
* transform params per app in {@code targets.apps} list.
*/
public RemoteTargetHandle[] assignTargetsForDesktop(RemoteAnimationTargets targets) {
+ resizeRemoteTargetHandles(targets);
+
for (int i = 0; i < mRemoteTargetHandles.length; i++) {
RemoteAnimationTarget primaryTaskTarget = targets.apps[i];
mRemoteTargetHandles[i].mTransformParams.setTargetSet(
@@ -207,6 +202,23 @@
return mRemoteTargetHandles;
}
+ /**
+ * Resize the `mRemoteTargetHandles` array since we assumed initial size, but
+ * `targets.apps` is the ultimate source of truth here
+ */
+ private void resizeRemoteTargetHandles(RemoteAnimationTargets targets) {
+ long appCount = Arrays.stream(targets.apps)
+ .filter(app -> app.mode == targets.targetMode)
+ .count();
+ Log.d(TAG, "appCount: " + appCount + " handleLength: " + mRemoteTargetHandles.length);
+ if (appCount < mRemoteTargetHandles.length) {
+ Log.d(TAG, "resizing handles");
+ RemoteTargetHandle[] newHandles = new RemoteTargetHandle[(int) appCount];
+ System.arraycopy(mRemoteTargetHandles, 0/*src*/, newHandles, 0/*dst*/, (int) appCount);
+ mRemoteTargetHandles = newHandles;
+ }
+ }
+
private Rect getStartBounds(RemoteAnimationTarget target) {
return target.startBounds == null ? target.screenSpaceBounds : target.startBounds;
}