Explicitly release references to the controller

- This is a workaround for lingering phantom references to binder
  stubs

Flag: EXEMPT bugfix
Bug: 332339792
Test: Presubmit
Change-Id: I3e790f627d434760e87be1dc6c8643d03fceb400
This commit is contained in:
Winson Chung
2024-08-09 19:57:00 +00:00
parent f28a059e5b
commit 08ef39c5ba
2 changed files with 78 additions and 29 deletions
@@ -26,6 +26,7 @@ import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.Launcher;
@@ -39,6 +40,7 @@ import com.android.wm.shell.desktopmode.IDesktopTaskListener;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executor;
/**
* Controls the visibility of the workspace and the resumed / paused state when desktop mode
@@ -57,7 +59,7 @@ public class DesktopVisibilityController {
private boolean mGestureInProgress;
@Nullable
private IDesktopTaskListener mDesktopTaskListener;
private DesktopTaskListenerImpl mDesktopTaskListener;
public DesktopVisibilityController(Launcher launcher) {
mLauncher = launcher;
@@ -67,24 +69,7 @@ public class DesktopVisibilityController {
* Register a listener with System UI to receive updates about desktop tasks state
*/
public void registerSystemUiListener() {
mDesktopTaskListener = new IDesktopTaskListener.Stub() {
@Override
public void onTasksVisibilityChanged(int displayId, int visibleTasksCount) {
MAIN_EXECUTOR.execute(() -> {
if (displayId == mLauncher.getDisplayId()) {
if (DEBUG) {
Log.d(TAG, "desktop visible tasks count changed=" + visibleTasksCount);
}
setVisibleDesktopTasksCount(visibleTasksCount);
}
});
}
@Override
public void onStashedChanged(int displayId, boolean stashed) {
Log.w(TAG, "IDesktopTaskListener: onStashedChanged is deprecated");
}
};
mDesktopTaskListener = new DesktopTaskListenerImpl(this, mLauncher.getDisplayId());
SystemUiProxy.INSTANCE.get(mLauncher).setDesktopTaskListener(mDesktopTaskListener);
}
@@ -93,6 +78,7 @@ public class DesktopVisibilityController {
*/
public void unregisterSystemUiListener() {
SystemUiProxy.INSTANCE.get(mLauncher).setDesktopTaskListener(null);
mDesktopTaskListener.release();
mDesktopTaskListener = null;
}
@@ -356,4 +342,43 @@ public class DesktopVisibilityController {
*/
void onDesktopVisibilityChanged(boolean visible);
}
/**
* Wrapper for the IDesktopTaskListener stub to prevent lingering references to the launcher
* activity via the controller.
*/
private static class DesktopTaskListenerImpl extends IDesktopTaskListener.Stub {
private DesktopVisibilityController mController;
private final int mDisplayId;
DesktopTaskListenerImpl(@NonNull DesktopVisibilityController controller, int displayId) {
mController = controller;
mDisplayId = displayId;
}
/**
* Clears any references to the controller.
*/
void release() {
mController = null;
}
@Override
public void onTasksVisibilityChanged(int displayId, int visibleTasksCount) {
MAIN_EXECUTOR.execute(() -> {
if (mController != null && displayId == mDisplayId) {
if (DEBUG) {
Log.d(TAG, "desktop visible tasks count changed=" + visibleTasksCount);
}
mController.setVisibleDesktopTasksCount(visibleTasksCount);
}
});
}
@Override
public void onStashedChanged(int displayId, boolean stashed) {
Log.w(TAG, "IDesktopTaskListener: onStashedChanged is deprecated");
}
}
}
@@ -961,7 +961,7 @@ public class SplitSelectStateController {
private final int mSplitPlaceholderSize;
private final int mSplitPlaceholderInset;
private ActivityManager.RunningTaskInfo mTaskInfo;
private ISplitSelectListener mSplitSelectListener;
private DesktopSplitSelectListenerImpl mSplitSelectListener;
private Drawable mAppIcon;
public SplitFromDesktopController(QuickstepLauncher launcher,
@@ -972,21 +972,14 @@ public class SplitSelectStateController {
R.dimen.split_placeholder_size);
mSplitPlaceholderInset = mLauncher.getResources().getDimensionPixelSize(
R.dimen.split_placeholder_inset);
mSplitSelectListener = new ISplitSelectListener.Stub() {
@Override
public boolean onRequestSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
int splitPosition, Rect taskBounds) {
MAIN_EXECUTOR.execute(() -> enterSplitSelect(taskInfo, splitPosition,
taskBounds));
return true;
}
};
mSplitSelectListener = new DesktopSplitSelectListenerImpl(this);
SystemUiProxy.INSTANCE.get(mLauncher).registerSplitSelectListener(mSplitSelectListener);
}
void onDestroy() {
SystemUiProxy.INSTANCE.get(mLauncher).unregisterSplitSelectListener(
mSplitSelectListener);
mSplitSelectListener.release();
mSplitSelectListener = null;
}
@@ -1079,4 +1072,35 @@ public class SplitSelectStateController {
}
}
}
/**
* Wrapper for the ISplitSelectListener stub to prevent lingering references to the launcher
* activity via the controller.
*/
private static class DesktopSplitSelectListenerImpl extends ISplitSelectListener.Stub {
private SplitFromDesktopController mController;
DesktopSplitSelectListenerImpl(@NonNull SplitFromDesktopController controller) {
mController = controller;
}
/**
* Clears any references to the controller.
*/
void release() {
mController = null;
}
@Override
public boolean onRequestSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
int splitPosition, Rect taskBounds) {
MAIN_EXECUTOR.execute(() -> {
if (mController != null) {
mController.enterSplitSelect(taskInfo, splitPosition, taskBounds);
}
});
return true;
}
}
}