Fixing some launcher model tests
> Removing static mocks and using Sandbox context instead
> Removing inheritence in LauncherModel and converting LauncherApps.Callbacks
to a separate class. decMaker sometimes fails because of API changes in
LauncherApps.Callbacks
Bug: 319877828
Test: atest LoaderTaskTest
Flag: N/A
Change-Id: If78b5d83595627a355b284f52d887d75fef53014
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index d4bcd24..e015021 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -44,6 +44,7 @@
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIconProvider;
import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.model.ModelLauncherCallbacks;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.InstallSessionTracker;
@@ -101,9 +102,10 @@
}
});
- mContext.getSystemService(LauncherApps.class).registerCallback(mModel);
+ ModelLauncherCallbacks callbacks = mModel.newModelCallbacks();
+ mContext.getSystemService(LauncherApps.class).registerCallback(callbacks);
mOnTerminateCallback.add(() ->
- mContext.getSystemService(LauncherApps.class).unregisterCallback(mModel));
+ mContext.getSystemService(LauncherApps.class).unregisterCallback(callbacks));
SimpleBroadcastReceiver modelChangeReceiver =
new SimpleBroadcastReceiver(mModel::onBroadcastIntent);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index c81db63..d124746 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.LauncherAppState.ACTION_FORCE_ROLOAD;
import static com.android.launcher3.config.FeatureFlags.IS_STUDIO_BUILD;
+import static com.android.launcher3.model.PackageUpdatedTask.OP_UPDATE;
import static com.android.launcher3.pm.UserCache.ACTION_PROFILE_AVAILABLE;
import static com.android.launcher3.pm.UserCache.ACTION_PROFILE_UNAVAILABLE;
import static com.android.launcher3.testing.shared.TestProtocol.sDebugTracing;
@@ -28,7 +29,6 @@
import android.content.Context;
import android.content.Intent;
-import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller;
import android.content.pm.ShortcutInfo;
import android.os.UserHandle;
@@ -43,7 +43,6 @@
import com.android.launcher3.celllayout.CellPosMapper;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.AddWorkspaceItemsTask;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BaseModelUpdateTask;
@@ -55,8 +54,8 @@
import com.android.launcher3.model.LoaderTask;
import com.android.launcher3.model.ModelDbController;
import com.android.launcher3.model.ModelDelegate;
+import com.android.launcher3.model.ModelLauncherCallbacks;
import com.android.launcher3.model.ModelWriter;
-import com.android.launcher3.model.PackageIncrementalDownloadUpdatedTask;
import com.android.launcher3.model.PackageInstallStateChangedTask;
import com.android.launcher3.model.PackageUpdatedTask;
import com.android.launcher3.model.ReloadStringCacheTask;
@@ -89,7 +88,7 @@
* LauncherModel object held in a static. Also provide APIs for updating the database state
* for the Launcher.
*/
-public class LauncherModel extends LauncherApps.Callback implements InstallSessionTracker.Callback {
+public class LauncherModel implements InstallSessionTracker.Callback {
private static final boolean DEBUG_RECEIVER = false;
static final String TAG = "Launcher.Model";
@@ -168,6 +167,10 @@
return mModelDbController;
}
+ public ModelLauncherCallbacks newModelCallbacks() {
+ return new ModelLauncherCallbacks(this::enqueueModelUpdateTask);
+ }
+
/**
* Adds the provided items to the workspace.
*/
@@ -186,77 +189,6 @@
owner);
}
- @Override
- public void onPackageChanged(
- @NonNull final String packageName, @NonNull final UserHandle user) {
- int op = PackageUpdatedTask.OP_UPDATE;
- enqueueModelUpdateTask(new PackageUpdatedTask(op, user, packageName));
- }
-
- @Override
- public void onPackageRemoved(
- @NonNull final String packageName, @NonNull final UserHandle user) {
- onPackagesRemoved(user, packageName);
- }
-
- public void onPackagesRemoved(
- @NonNull final UserHandle user, @NonNull final String... packages) {
- int op = PackageUpdatedTask.OP_REMOVE;
- FileLog.d(TAG, "package removed received " + TextUtils.join(",", packages));
- enqueueModelUpdateTask(new PackageUpdatedTask(op, user, packages));
- }
-
- @Override
- public void onPackageAdded(@NonNull final String packageName, @NonNull final UserHandle user) {
- int op = PackageUpdatedTask.OP_ADD;
- enqueueModelUpdateTask(new PackageUpdatedTask(op, user, packageName));
- }
-
- @Override
- public void onPackagesAvailable(@NonNull final String[] packageNames,
- @NonNull final UserHandle user, final boolean replacing) {
- enqueueModelUpdateTask(
- new PackageUpdatedTask(PackageUpdatedTask.OP_UPDATE, user, packageNames));
- }
-
- @Override
- public void onPackagesUnavailable(@NonNull final String[] packageNames,
- @NonNull final UserHandle user, final boolean replacing) {
- if (!replacing) {
- enqueueModelUpdateTask(new PackageUpdatedTask(
- PackageUpdatedTask.OP_UNAVAILABLE, user, packageNames));
- }
- }
-
- @Override
- public void onPackagesSuspended(
- @NonNull final String[] packageNames, @NonNull final UserHandle user) {
- enqueueModelUpdateTask(new PackageUpdatedTask(
- PackageUpdatedTask.OP_SUSPEND, user, packageNames));
- }
-
- @Override
- public void onPackagesUnsuspended(
- @NonNull final String[] packageNames, @NonNull final UserHandle user) {
- enqueueModelUpdateTask(new PackageUpdatedTask(
- PackageUpdatedTask.OP_UNSUSPEND, user, packageNames));
- }
-
- @Override
- public void onPackageLoadingProgressChanged(@NonNull final String packageName,
- @NonNull final UserHandle user, final float progress) {
- if (Utilities.ATLEAST_S) {
- enqueueModelUpdateTask(new PackageIncrementalDownloadUpdatedTask(
- packageName, user, progress));
- }
- }
-
- @Override
- public void onShortcutsChanged(@NonNull final String packageName,
- @NonNull final List<ShortcutInfo> shortcuts, @NonNull final UserHandle user) {
- enqueueModelUpdateTask(new ShortcutsChangedTask(packageName, shortcuts, user, true));
- }
-
/**
* Called when the icon for an app changes, outside of package event
*/
@@ -265,7 +197,7 @@
@NonNull final UserHandle user) {
// Update the icon for the calendar package
Context context = mApp.getContext();
- onPackageChanged(packageName, user);
+ enqueueModelUpdateTask(new PackageUpdatedTask(OP_UPDATE, user, packageName));
List<ShortcutInfo> pinnedShortcuts = new ShortcutRequest(context, user)
.forPackage(packageName).query(ShortcutRequest.PINNED);
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 7b9f6fa..905d03a 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -123,6 +123,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CancellationException;
@@ -185,7 +186,7 @@
mLauncherBinder = launcherBinder;
mLauncherApps = mApp.getContext().getSystemService(LauncherApps.class);
mUserManager = mApp.getContext().getSystemService(UserManager.class);
- mUserCache = UserCache.getInstance(mApp.getContext());
+ mUserCache = UserCache.INSTANCE.get(mApp.getContext());
mSessionHelper = InstallSessionHelper.INSTANCE.get(mApp.getContext());
mIconCache = mApp.getIconCache();
mUserManagerState = userManagerState;
@@ -247,7 +248,7 @@
// sanitizeData should not be invoked if the workspace is loaded from a db different
// from the main db as defined in the invariant device profile.
// (e.g. both grid preview and minimal device mode uses a different db)
- if (mApp.getInvariantDeviceProfile().dbFile.equals(mDbName)) {
+ if (Objects.equals(mApp.getInvariantDeviceProfile().dbFile, mDbName)) {
verifyNotStopped();
sanitizeFolders(mItemsDeleted);
sanitizeWidgetsShortcutsAndPackages();
diff --git a/src/com/android/launcher3/model/ModelLauncherCallbacks.kt b/src/com/android/launcher3/model/ModelLauncherCallbacks.kt
new file mode 100644
index 0000000..b12b2bc
--- /dev/null
+++ b/src/com/android/launcher3/model/ModelLauncherCallbacks.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.model
+
+import android.content.pm.LauncherApps
+import android.content.pm.ShortcutInfo
+import android.os.UserHandle
+import android.text.TextUtils
+import com.android.launcher3.LauncherModel.ModelUpdateTask
+import com.android.launcher3.logging.FileLog
+import com.android.launcher3.model.PackageUpdatedTask.OP_ADD
+import com.android.launcher3.model.PackageUpdatedTask.OP_REMOVE
+import com.android.launcher3.model.PackageUpdatedTask.OP_SUSPEND
+import com.android.launcher3.model.PackageUpdatedTask.OP_UNAVAILABLE
+import com.android.launcher3.model.PackageUpdatedTask.OP_UNSUSPEND
+import com.android.launcher3.model.PackageUpdatedTask.OP_UPDATE
+import java.util.function.Consumer
+
+/**
+ * Implementation of {@link LauncherApps#Callbacks} which converts various events to corresponding
+ * model tasks
+ */
+class ModelLauncherCallbacks(private var taskExecutor: Consumer<ModelUpdateTask>) :
+ LauncherApps.Callback() {
+
+ override fun onPackageAdded(packageName: String, user: UserHandle) {
+ taskExecutor.accept(PackageUpdatedTask(OP_ADD, user, packageName))
+ }
+
+ override fun onPackageChanged(packageName: String, user: UserHandle) {
+ taskExecutor.accept(PackageUpdatedTask(OP_UPDATE, user, packageName))
+ }
+
+ override fun onPackageLoadingProgressChanged(
+ packageName: String,
+ user: UserHandle,
+ progress: Float
+ ) {
+ taskExecutor.accept(PackageIncrementalDownloadUpdatedTask(packageName, user, progress))
+ }
+
+ override fun onPackageRemoved(packageName: String, user: UserHandle) {
+ FileLog.d(TAG, "package removed received $packageName")
+ taskExecutor.accept(PackageUpdatedTask(OP_REMOVE, user, packageName))
+ }
+
+ override fun onPackagesAvailable(
+ vararg packageNames: String,
+ user: UserHandle,
+ replacing: Boolean
+ ) {
+ taskExecutor.accept(PackageUpdatedTask(OP_UPDATE, user, *packageNames))
+ }
+
+ override fun onPackagesSuspended(vararg packageNames: String, user: UserHandle) {
+ taskExecutor.accept(PackageUpdatedTask(OP_SUSPEND, user, *packageNames))
+ }
+
+ override fun onPackagesUnavailable(
+ packageNames: Array<String>,
+ user: UserHandle,
+ replacing: Boolean
+ ) {
+ if (!replacing) {
+ taskExecutor.accept(PackageUpdatedTask(OP_UNAVAILABLE, user, *packageNames))
+ }
+ }
+
+ override fun onPackagesUnsuspended(vararg packageNames: String, user: UserHandle) {
+ taskExecutor.accept(PackageUpdatedTask(OP_UNSUSPEND, user, *packageNames))
+ }
+
+ override fun onShortcutsChanged(
+ packageName: String,
+ shortcuts: MutableList<ShortcutInfo>,
+ user: UserHandle
+ ) {
+ taskExecutor.accept(ShortcutsChangedTask(packageName, shortcuts, user, true))
+ }
+
+ fun onPackagesRemoved(user: UserHandle, packages: List<String>) {
+ FileLog.d(TAG, "package removed received " + TextUtils.join(",", packages))
+ taskExecutor.accept(PackageUpdatedTask(OP_REMOVE, user, *packages.toTypedArray()))
+ }
+
+ companion object {
+ private const val TAG = "LauncherAppsCallbackImpl"
+ }
+}
diff --git a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
index 76a87ed..2457a42 100644
--- a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
+++ b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
@@ -52,7 +52,8 @@
ApplicationInfo ai = app.getContext()
.getPackageManager().getApplicationInfo(mInstallInfo.packageName, 0);
if (InstantAppResolver.newInstance(app.getContext()).isInstantApp(ai)) {
- app.getModel().onPackageAdded(ai.packageName, mInstallInfo.user);
+ app.getModel().newModelCallbacks()
+ .onPackageAdded(ai.packageName, mInstallInfo.user);
}
} catch (PackageManager.NameNotFoundException e) {
// Ignore
diff --git a/src/com/android/launcher3/model/SdCardAvailableReceiver.java b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
index 3798575..8cfa3aa 100644
--- a/src/com/android/launcher3/model/SdCardAvailableReceiver.java
+++ b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
@@ -67,11 +67,10 @@
}
}
if (!packagesRemoved.isEmpty()) {
- mModel.onPackagesRemoved(user,
- packagesRemoved.toArray(new String[packagesRemoved.size()]));
+ mModel.newModelCallbacks().onPackagesRemoved(user, packagesRemoved);
}
if (!packagesUnavailable.isEmpty()) {
- mModel.onPackagesUnavailable(
+ mModel.newModelCallbacks().onPackagesUnavailable(
packagesUnavailable.toArray(new String[packagesUnavailable.size()]),
user, false);
}