[Memory Leak] Fix leak of TouchInteractionService from DisplayInfoChangeListener
Fix: 394672098
Flag: NONE - released code
Test: manual
Change-Id: I99bfd783e8be34066e29072f5c1a6719802bde05
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index e1e962a..090ccdc 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -114,7 +114,6 @@
private final RotationTouchHelper mRotationTouchHelper;
private final TaskStackChangeListener mPipListener;
- private final DaggerSingletonTracker mLifeCycle;
// Cache for better performance since it doesn't change at runtime.
private final boolean mCanImeRenderGesturalNavButtons =
InputMethodService.canImeRenderGesturalNavButtons();
@@ -152,16 +151,15 @@
mExclusionManager = exclusionManager;
mContextualSearchStateManager = contextualSearchStateManager;
mRotationTouchHelper = rotationTouchHelper;
- mLifeCycle = lifeCycle;
mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
// Register for exclusion updates
- mLifeCycle.addCloseable(this::unregisterExclusionListener);
+ lifeCycle.addCloseable(this::unregisterExclusionListener);
// Register for display changes changes
mDisplayController.addChangeListener(this);
onDisplayInfoChanged(context, mDisplayController.getInfo(), CHANGE_ALL);
- mLifeCycle.addCloseable(() -> mDisplayController.removeChangeListener(this));
+ lifeCycle.addCloseable(() -> mDisplayController.removeChangeListener(this));
if (mIsOneHandedModeSupported) {
Uri oneHandedUri = Settings.Secure.getUriFor(ONE_HANDED_ENABLED);
@@ -169,7 +167,7 @@
enabled -> mIsOneHandedModeEnabled = enabled;
settingsCache.register(oneHandedUri, onChangeListener);
mIsOneHandedModeEnabled = settingsCache.getValue(oneHandedUri);
- mLifeCycle.addCloseable(() -> settingsCache.unregister(oneHandedUri, onChangeListener));
+ lifeCycle.addCloseable(() -> settingsCache.unregister(oneHandedUri, onChangeListener));
} else {
mIsOneHandedModeEnabled = false;
}
@@ -180,7 +178,7 @@
enabled -> mIsSwipeToNotificationEnabled = enabled;
settingsCache.register(swipeBottomNotificationUri, onChangeListener);
mIsSwipeToNotificationEnabled = settingsCache.getValue(swipeBottomNotificationUri);
- mLifeCycle.addCloseable(
+ lifeCycle.addCloseable(
() -> settingsCache.unregister(swipeBottomNotificationUri, onChangeListener));
Uri setupCompleteUri = Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE);
@@ -188,7 +186,7 @@
if (!mIsUserSetupComplete) {
SettingsCache.OnChangeListener userSetupChangeListener = e -> mIsUserSetupComplete = e;
settingsCache.register(setupCompleteUri, userSetupChangeListener);
- mLifeCycle.addCloseable(
+ lifeCycle.addCloseable(
() -> settingsCache.unregister(setupCompleteUri, userSetupChangeListener));
}
@@ -210,15 +208,19 @@
}
};
TaskStackChangeListeners.getInstance().registerTaskStackListener(mPipListener);
- mLifeCycle.addCloseable(() ->
+ lifeCycle.addCloseable(() ->
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mPipListener));
}
/**
* Adds a listener for the nav mode change, guaranteed to be called after the device state's
* mode has changed.
+ *
+ * @return Added {@link DisplayInfoChangeListener} so that caller is
+ * responsible for removing the listener from {@link DisplayController} to avoid memory leak.
*/
- public void addNavigationModeChangedCallback(Runnable callback) {
+ public DisplayController.DisplayInfoChangeListener addNavigationModeChangedCallback(
+ Runnable callback) {
DisplayController.DisplayInfoChangeListener listener = (context, info, flags) -> {
if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
callback.run();
@@ -226,7 +228,16 @@
};
mDisplayController.addChangeListener(listener);
callback.run();
- mLifeCycle.addCloseable(() -> mDisplayController.removeChangeListener(listener));
+ return listener;
+ }
+
+ /**
+ * Remove the {DisplayController.DisplayInfoChangeListener} added from
+ * {@link #addNavigationModeChangedCallback} when {@link TouchInteractionService} is destroyed.
+ */
+ public void removeDisplayInfoChangeListener(
+ DisplayController.DisplayInfoChangeListener listener) {
+ mDisplayController.removeChangeListener(listener);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 51e59ff..d77516e 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -576,6 +576,8 @@
private DesktopAppLaunchTransitionManager mDesktopAppLaunchTransitionManager;
+ private DisplayController.DisplayInfoChangeListener mDisplayInfoChangeListener;
+
@Override
public void onCreate() {
super.onCreate();
@@ -605,7 +607,8 @@
// Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
LockedUserState.get(this).runOnUserUnlocked(mUserUnlockedRunnable);
- mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
+ mDisplayInfoChangeListener =
+ mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
ScreenOnTracker.INSTANCE.get(this).addListener(mScreenOnListener);
}
@@ -757,7 +760,7 @@
mDesktopAppLaunchTransitionManager.unregisterTransitions();
}
mDesktopAppLaunchTransitionManager = null;
-
+ mDeviceState.removeDisplayInfoChangeListener(mDisplayInfoChangeListener);
LockedUserState.get(this).removeOnUserUnlockedRunnable(mUserUnlockedRunnable);
ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
super.onDestroy();