Fixing leak in model tests
> InstallSessionTracker is not released immediately causing large memory objects
being held by tests
Bug: 198719724
Test: Presubmit
Change-Id: I1d19a2a498a9f255077818dc7d78422367ec1749
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index ab35bd6..4b86f65 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -17,7 +17,6 @@
package com.android.launcher3.pm;
import static com.android.launcher3.Utilities.getPrefs;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -25,7 +24,6 @@
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
-import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -238,24 +236,12 @@
}
public InstallSessionTracker registerInstallTracker(InstallSessionTracker.Callback callback) {
- InstallSessionTracker tracker = new InstallSessionTracker(this, callback);
-
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
- mInstaller.registerSessionCallback(tracker, MODEL_EXECUTOR.getHandler());
- } else {
- mLauncherApps.registerPackageInstallerSessionCallback(MODEL_EXECUTOR, tracker);
- }
+ InstallSessionTracker tracker = new InstallSessionTracker(
+ this, callback, mInstaller, mLauncherApps);
+ tracker.register();
return tracker;
}
- void unregister(InstallSessionTracker tracker) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
- mInstaller.unregisterSessionCallback(tracker);
- } else {
- mLauncherApps.unregisterPackageInstallerSessionCallback(tracker);
- }
- }
-
public static UserHandle getUserHandle(SessionInfo info) {
return Utilities.ATLEAST_Q ? info.getUser() : Process.myUserHandle();
}
diff --git a/src/com/android/launcher3/pm/InstallSessionTracker.java b/src/com/android/launcher3/pm/InstallSessionTracker.java
index b0b907a..e1b3c1a 100644
--- a/src/com/android/launcher3/pm/InstallSessionTracker.java
+++ b/src/com/android/launcher3/pm/InstallSessionTracker.java
@@ -18,9 +18,12 @@
import static com.android.launcher3.pm.InstallSessionHelper.getUserHandle;
import static com.android.launcher3.pm.PackageInstallInfo.STATUS_FAILED;
import static com.android.launcher3.pm.PackageInstallInfo.STATUS_INSTALLED;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
+import android.os.Build;
import android.os.UserHandle;
import android.util.SparseArray;
@@ -28,35 +31,53 @@
import com.android.launcher3.util.PackageUserKey;
+import java.lang.ref.WeakReference;
+
@WorkerThread
public class InstallSessionTracker extends PackageInstaller.SessionCallback {
// Lazily initialized
private SparseArray<PackageUserKey> mActiveSessions = null;
- private final InstallSessionHelper mInstallerCompat;
- private final Callback mCallback;
+ private final WeakReference<InstallSessionHelper> mWeakHelper;
+ private final WeakReference<Callback> mWeakCallback;
+ private final PackageInstaller mInstaller;
+ private final LauncherApps mLauncherApps;
- InstallSessionTracker(InstallSessionHelper installerCompat, Callback callback) {
- mInstallerCompat = installerCompat;
- mCallback = callback;
+
+ InstallSessionTracker(InstallSessionHelper installerCompat, Callback callback,
+ PackageInstaller installer, LauncherApps launcherApps) {
+ mWeakHelper = new WeakReference<>(installerCompat);
+ mWeakCallback = new WeakReference<>(callback);
+ mInstaller = installer;
+ mLauncherApps = launcherApps;
}
@Override
public void onCreated(int sessionId) {
- SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId);
+ InstallSessionHelper helper = mWeakHelper.get();
+ Callback callback = mWeakCallback.get();
+ if (callback == null || helper == null) {
+ return;
+ }
+ SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId, helper, callback);
if (sessionInfo != null) {
- mCallback.onInstallSessionCreated(PackageInstallInfo.fromInstallingState(sessionInfo));
+ callback.onInstallSessionCreated(PackageInstallInfo.fromInstallingState(sessionInfo));
}
- mInstallerCompat.tryQueuePromiseAppIcon(sessionInfo);
+ helper.tryQueuePromiseAppIcon(sessionInfo);
}
@Override
public void onFinished(int sessionId, boolean success) {
+ InstallSessionHelper helper = mWeakHelper.get();
+ Callback callback = mWeakCallback.get();
+ if (callback == null || helper == null) {
+ return;
+ }
// For a finished session, we can't get the session info. So use the
// packageName from our local cache.
- SparseArray<PackageUserKey> activeSessions = getActiveSessionMap();
+ SparseArray<PackageUserKey> activeSessions = getActiveSessionMap(helper);
PackageUserKey key = activeSessions.get(sessionId);
activeSessions.remove(sessionId);
@@ -65,21 +86,26 @@
PackageInstallInfo info = PackageInstallInfo.fromState(
success ? STATUS_INSTALLED : STATUS_FAILED,
packageName, key.mUser);
- mCallback.onPackageStateChanged(info);
+ callback.onPackageStateChanged(info);
- if (!success && mInstallerCompat.promiseIconAddedForId(sessionId)) {
- mCallback.onSessionFailure(packageName, key.mUser);
+ if (!success && helper.promiseIconAddedForId(sessionId)) {
+ callback.onSessionFailure(packageName, key.mUser);
// If it is successful, the id is removed in the the package added flow.
- mInstallerCompat.removePromiseIconId(sessionId);
+ helper.removePromiseIconId(sessionId);
}
}
}
@Override
public void onProgressChanged(int sessionId, float progress) {
- SessionInfo session = mInstallerCompat.getVerifiedSessionInfo(sessionId);
+ InstallSessionHelper helper = mWeakHelper.get();
+ Callback callback = mWeakCallback.get();
+ if (callback == null || helper == null) {
+ return;
+ }
+ SessionInfo session = helper.getVerifiedSessionInfo(sessionId);
if (session != null && session.getAppPackageName() != null) {
- mCallback.onPackageStateChanged(PackageInstallInfo.fromInstallingState(session));
+ callback.onPackageStateChanged(PackageInstallInfo.fromInstallingState(session));
}
}
@@ -88,35 +114,53 @@
@Override
public void onBadgingChanged(int sessionId) {
- SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId);
+ InstallSessionHelper helper = mWeakHelper.get();
+ Callback callback = mWeakCallback.get();
+ if (callback == null || helper == null) {
+ return;
+ }
+ SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId, helper, callback);
if (sessionInfo != null) {
- mInstallerCompat.tryQueuePromiseAppIcon(sessionInfo);
+ helper.tryQueuePromiseAppIcon(sessionInfo);
}
}
- private SessionInfo pushSessionDisplayToLauncher(int sessionId) {
- SessionInfo session = mInstallerCompat.getVerifiedSessionInfo(sessionId);
+ private SessionInfo pushSessionDisplayToLauncher(
+ int sessionId, InstallSessionHelper helper, Callback callback) {
+ SessionInfo session = helper.getVerifiedSessionInfo(sessionId);
if (session != null && session.getAppPackageName() != null) {
PackageUserKey key =
new PackageUserKey(session.getAppPackageName(), getUserHandle(session));
- getActiveSessionMap().put(session.getSessionId(), key);
- mCallback.onUpdateSessionDisplay(key, session);
+ getActiveSessionMap(helper).put(session.getSessionId(), key);
+ callback.onUpdateSessionDisplay(key, session);
return session;
}
return null;
}
- private SparseArray<PackageUserKey> getActiveSessionMap() {
+ private SparseArray<PackageUserKey> getActiveSessionMap(InstallSessionHelper helper) {
if (mActiveSessions == null) {
mActiveSessions = new SparseArray<>();
- mInstallerCompat.getActiveSessions().forEach(
+ helper.getActiveSessions().forEach(
(key, si) -> mActiveSessions.put(si.getSessionId(), key));
}
return mActiveSessions;
}
+ void register() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ mInstaller.registerSessionCallback(this, MODEL_EXECUTOR.getHandler());
+ } else {
+ mLauncherApps.registerPackageInstallerSessionCallback(MODEL_EXECUTOR, this);
+ }
+ }
+
public void unregister() {
- mInstallerCompat.unregister(this);
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ mInstaller.unregisterSessionCallback(this);
+ } else {
+ mLauncherApps.unregisterPackageInstallerSessionCallback(this);
+ }
}
public interface Callback {
diff --git a/tests/src/com/android/launcher3/util/LauncherModelHelper.java b/tests/src/com/android/launcher3/util/LauncherModelHelper.java
index c9b63ae..59966ee 100644
--- a/tests/src/com/android/launcher3/util/LauncherModelHelper.java
+++ b/tests/src/com/android/launcher3/util/LauncherModelHelper.java
@@ -66,7 +66,6 @@
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.testing.TestInformationProvider;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.util.MainThreadInitializedObject.ObjectProvider;
import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext;
import com.android.launcher3.widget.custom.CustomWidgetManager;
@@ -533,12 +532,6 @@
super.onDestroy();
}
-
- @Override
- protected <T> T createObject(ObjectProvider<T> provider) {
- return spy(provider.get(this));
- }
-
@Override
public PackageManager getPackageManager() {
return mPm;