summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/model
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/model')
-rw-r--r--src/com/android/launcher3/model/AddWorkspaceItemsTask.java50
-rw-r--r--src/com/android/launcher3/model/AllAppsList.java299
-rw-r--r--src/com/android/launcher3/model/AppLaunchTracker.java3
-rw-r--r--src/com/android/launcher3/model/BaseLoaderResults.java13
-rw-r--r--src/com/android/launcher3/model/BaseModelUpdateTask.java33
-rw-r--r--src/com/android/launcher3/model/BgDataModel.java33
-rw-r--r--src/com/android/launcher3/model/CacheDataUpdatedTask.java18
-rw-r--r--src/com/android/launcher3/model/LoaderTask.java58
-rw-r--r--src/com/android/launcher3/model/ModelPreload.java1
-rw-r--r--src/com/android/launcher3/model/ModelWriter.java31
-rw-r--r--src/com/android/launcher3/model/PackageInstallStateChangedTask.java40
-rw-r--r--src/com/android/launcher3/model/PackageItemInfo.java12
-rw-r--r--src/com/android/launcher3/model/PackageUpdatedTask.java65
-rw-r--r--src/com/android/launcher3/model/ShortcutsChangedTask.java3
-rw-r--r--src/com/android/launcher3/model/UserLockStateChangedTask.java6
15 files changed, 483 insertions, 182 deletions
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 7d4f2f722..b8c583c14 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -22,7 +22,6 @@ import android.os.UserHandle;
import android.util.LongSparseArray;
import android.util.Pair;
-import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.InvariantDeviceProfile;
@@ -30,14 +29,14 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel.CallbackTask;
-import com.android.launcher3.LauncherModel.Callbacks;
+import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.Utilities;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.PackageManagerHelper;
import java.util.ArrayList;
import java.util.List;
@@ -77,6 +76,11 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
if (shortcutExists(dataModel, item.getIntent(), item.user)) {
continue;
}
+
+ // b/139663018 Short-circuit this logic if the icon is a system app
+ if (PackageManagerHelper.isSystemApp(app.getContext(), item.getIntent())) {
+ continue;
+ }
}
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
@@ -118,25 +122,39 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
}
SessionInfo sessionInfo = packageInstaller.getActiveSessionInfo(item.user,
packageName);
+ List<LauncherActivityInfo> activities = launcherApps
+ .getActivityList(packageName, item.user);
+ boolean hasActivity = activities != null && !activities.isEmpty();
+
if (sessionInfo == null) {
- List<LauncherActivityInfo> activities = launcherApps
- .getActivityList(packageName, item.user);
- if (activities != null && !activities.isEmpty()) {
- // App was installed while launcher was in the background.
- itemInfo = new AppInfo(app.getContext(), activities.get(0), item.user)
- .makeWorkspaceItem();
- WorkspaceItemInfo wii = (WorkspaceItemInfo) itemInfo;
- wii.title = "";
- wii.applyFrom(app.getIconCache().getDefaultIcon(item.user));
- app.getIconCache().getTitleAndIcon(wii,
- ((WorkspaceItemInfo) itemInfo).usingLowResIcon());
- } else {
+ if (!hasActivity) {
// Session was cancelled, do not add.
continue;
}
} else {
workspaceInfo.setInstallProgress((int) sessionInfo.getProgress());
}
+
+ if (hasActivity) {
+ // App was installed while launcher was in the background,
+ // or app was already installed for another user.
+ itemInfo = new AppInfo(app.getContext(), activities.get(0), item.user)
+ .makeWorkspaceItem();
+
+ if (shortcutExists(dataModel, itemInfo.getIntent(), itemInfo.user)) {
+ // We need this additional check here since we treat all auto added
+ // workspace items as promise icons. At this point we now have the
+ // correct intent to compare against existing workspace icons.
+ // Icon already exists on the workspace and should not be auto-added.
+ continue;
+ }
+
+ WorkspaceItemInfo wii = (WorkspaceItemInfo) itemInfo;
+ wii.title = "";
+ wii.applyFrom(app.getIconCache().getDefaultIcon(item.user));
+ app.getIconCache().getTitleAndIcon(wii,
+ ((WorkspaceItemInfo) itemInfo).usingLowResIcon());
+ }
}
// Add the shortcut to the db
@@ -200,7 +218,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
intentWithoutPkg = intent.toUri(0);
}
- boolean isLauncherAppTarget = Utilities.isLauncherAppTarget(intent);
+ boolean isLauncherAppTarget = PackageManagerHelper.isLauncherAppTarget(intent);
synchronized (dataModel) {
for (ItemInfo item : dataModel.itemsIdMap) {
if (item instanceof WorkspaceItemInfo) {
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
new file mode 100644
index 000000000..3873a17e0
--- /dev/null
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2008 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 static com.android.launcher3.AppInfo.COMPONENT_KEY_COMPARATOR;
+import static com.android.launcher3.AppInfo.EMPTY_ARRAY;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.LauncherActivityInfo;
+import android.os.LocaleList;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.launcher3.AppFilter;
+import com.android.launcher3.AppInfo;
+import com.android.launcher3.PromiseAppInfo;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.PackageInstallerCompat;
+import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.util.FlagOp;
+import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.SafeCloseable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.function.Consumer;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+
+/**
+ * Stores the list of all applications for the all apps view.
+ */
+public class AllAppsList {
+
+ private static final String TAG = "AllAppsList";
+ private static final Consumer<AppInfo> NO_OP_CONSUMER = a -> { };
+
+
+ public static final int DEFAULT_APPLICATIONS_NUMBER = 42;
+
+ /** The list off all apps. */
+ public final ArrayList<AppInfo> data = new ArrayList<>(DEFAULT_APPLICATIONS_NUMBER);
+
+ private IconCache mIconCache;
+ private AppFilter mAppFilter;
+
+ private boolean mDataChanged = false;
+ private Consumer<AppInfo> mRemoveListener = NO_OP_CONSUMER;
+
+ private AlphabeticIndexCompat mIndex;
+
+ /**
+ * Boring constructor.
+ */
+ public AllAppsList(IconCache iconCache, AppFilter appFilter) {
+ mIconCache = iconCache;
+ mAppFilter = appFilter;
+ mIndex = new AlphabeticIndexCompat(LocaleList.getDefault());
+ }
+
+ /**
+ * Returns true if there have been any changes since last call.
+ */
+ public boolean getAndResetChangeFlag() {
+ boolean result = mDataChanged;
+ mDataChanged = false;
+ return result;
+ }
+
+ /**
+ * Add the supplied ApplicationInfo objects to the list, and enqueue it into the
+ * list to broadcast when notify() is called.
+ *
+ * If the app is already in the list, doesn't add it.
+ */
+ public void add(AppInfo info, LauncherActivityInfo activityInfo) {
+ if (!mAppFilter.shouldShowApp(info.componentName)) {
+ return;
+ }
+ if (findAppInfo(info.componentName, info.user) != null) {
+ return;
+ }
+ mIconCache.getTitleAndIcon(info, activityInfo, true /* useLowResIcon */);
+ info.sectionName = mIndex.computeSectionName(info.title);
+
+ data.add(info);
+ mDataChanged = true;
+ }
+
+ public void addPromiseApp(Context context,
+ PackageInstallerCompat.PackageInstallInfo installInfo) {
+ ApplicationInfo applicationInfo = LauncherAppsCompat.getInstance(context)
+ .getApplicationInfo(installInfo.packageName, 0, installInfo.user);
+ // only if not yet installed
+ if (applicationInfo == null) {
+ PromiseAppInfo info = new PromiseAppInfo(installInfo);
+ mIconCache.getTitleAndIcon(info, info.usingLowResIcon());
+ info.sectionName = mIndex.computeSectionName(info.title);
+
+ data.add(info);
+ mDataChanged = true;
+ }
+ }
+
+ public PromiseAppInfo updatePromiseInstallInfo(PackageInstallInfo installInfo) {
+ UserHandle user = Process.myUserHandle();
+ for (int i=0; i < data.size(); i++) {
+ final AppInfo appInfo = data.get(i);
+ final ComponentName tgtComp = appInfo.getTargetComponent();
+ if (tgtComp != null && tgtComp.getPackageName().equals(installInfo.packageName)
+ && appInfo.user.equals(user)
+ && appInfo instanceof PromiseAppInfo) {
+ final PromiseAppInfo promiseAppInfo = (PromiseAppInfo) appInfo;
+ if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLING) {
+ promiseAppInfo.level = installInfo.progress;
+ return promiseAppInfo;
+ } else if (installInfo.state == PackageInstallerCompat.STATUS_FAILED) {
+ removeApp(i);
+ }
+ }
+ }
+ return null;
+ }
+
+ private void removeApp(int index) {
+ AppInfo removed = data.remove(index);
+ if (removed != null) {
+ mDataChanged = true;
+ mRemoveListener.accept(removed);
+ }
+ }
+
+ public void clear() {
+ data.clear();
+ mDataChanged = false;
+ // Reset the index as locales might have changed
+ mIndex = new AlphabeticIndexCompat(LocaleList.getDefault());
+ }
+
+ /**
+ * Add the icons for the supplied apk called packageName.
+ */
+ public void addPackage(Context context, String packageName, UserHandle user) {
+ final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
+ final List<LauncherActivityInfo> matches = launcherApps.getActivityList(packageName,
+ user);
+
+ for (LauncherActivityInfo info : matches) {
+ add(new AppInfo(context, info, user), info);
+ }
+ }
+
+ /**
+ * Remove the apps for the given apk identified by packageName.
+ */
+ public void removePackage(String packageName, UserHandle user) {
+ final List<AppInfo> data = this.data;
+ for (int i = data.size() - 1; i >= 0; i--) {
+ AppInfo info = data.get(i);
+ if (info.user.equals(user) && packageName.equals(info.componentName.getPackageName())) {
+ removeApp(i);
+ }
+ }
+ }
+
+ /**
+ * Updates the disabled flags of apps matching {@param matcher} based on {@param op}.
+ */
+ public void updateDisabledFlags(ItemInfoMatcher matcher, FlagOp op) {
+ final List<AppInfo> data = this.data;
+ for (int i = data.size() - 1; i >= 0; i--) {
+ AppInfo info = data.get(i);
+ if (matcher.matches(info, info.componentName)) {
+ info.runtimeStatusFlags = op.apply(info.runtimeStatusFlags);
+ mDataChanged = true;
+ }
+ }
+ }
+
+ public void updateIconsAndLabels(HashSet<String> packages, UserHandle user) {
+ for (AppInfo info : data) {
+ if (info.user.equals(user) && packages.contains(info.componentName.getPackageName())) {
+ mIconCache.updateTitleAndIcon(info);
+ info.sectionName = mIndex.computeSectionName(info.title);
+ mDataChanged = true;
+ }
+ }
+ }
+
+ /**
+ * Add and remove icons for this package which has been updated.
+ */
+ public void updatePackage(Context context, String packageName, UserHandle user) {
+ final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
+ final List<LauncherActivityInfo> matches = launcherApps.getActivityList(packageName,
+ user);
+ if (matches.size() > 0) {
+ // Find disabled/removed activities and remove them from data and add them
+ // to the removed list.
+ for (int i = data.size() - 1; i >= 0; i--) {
+ final AppInfo applicationInfo = data.get(i);
+ if (user.equals(applicationInfo.user)
+ && packageName.equals(applicationInfo.componentName.getPackageName())) {
+ if (!findActivity(matches, applicationInfo.componentName)) {
+ Log.w(TAG, "Changing shortcut target due to app component name change.");
+ removeApp(i);
+ }
+ }
+ }
+
+ // Find enabled activities and add them to the adapter
+ // Also updates existing activities with new labels/icons
+ for (final LauncherActivityInfo info : matches) {
+ AppInfo applicationInfo = findAppInfo(info.getComponentName(), user);
+ if (applicationInfo == null) {
+ add(new AppInfo(context, info, user), info);
+ } else {
+ mIconCache.getTitleAndIcon(applicationInfo, info, true /* useLowResIcon */);
+ applicationInfo.sectionName = mIndex.computeSectionName(applicationInfo.title);
+
+ mDataChanged = true;
+ }
+ }
+ } else {
+ // Remove all data for this package.
+ for (int i = data.size() - 1; i >= 0; i--) {
+ final AppInfo applicationInfo = data.get(i);
+ if (user.equals(applicationInfo.user)
+ && packageName.equals(applicationInfo.componentName.getPackageName())) {
+ mIconCache.remove(applicationInfo.componentName, user);
+ removeApp(i);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns whether <em>apps</em> contains <em>component</em>.
+ */
+ private static boolean findActivity(List<LauncherActivityInfo> apps,
+ ComponentName component) {
+ for (LauncherActivityInfo info : apps) {
+ if (info.getComponentName().equals(component)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Find an AppInfo object for the given componentName
+ *
+ * @return the corresponding AppInfo or null
+ */
+ private @Nullable AppInfo findAppInfo(@NonNull ComponentName componentName,
+ @NonNull UserHandle user) {
+ for (AppInfo info: data) {
+ if (componentName.equals(info.componentName) && user.equals(info.user)) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ public AppInfo[] copyData() {
+ AppInfo[] result = data.toArray(EMPTY_ARRAY);
+ Arrays.sort(result, COMPONENT_KEY_COMPARATOR);
+ return result;
+ }
+
+ public SafeCloseable trackRemoves(Consumer<AppInfo> removeListener) {
+ mRemoveListener = removeListener;
+
+ return () -> mRemoveListener = NO_OP_CONSUMER;
+ }
+}
diff --git a/src/com/android/launcher3/model/AppLaunchTracker.java b/src/com/android/launcher3/model/AppLaunchTracker.java
index 29a46cfa5..13ab033e4 100644
--- a/src/com/android/launcher3/model/AppLaunchTracker.java
+++ b/src/com/android/launcher3/model/AppLaunchTracker.java
@@ -51,5 +51,8 @@ public class AppLaunchTracker implements ResourceBasedOverride {
public void onStartApp(ComponentName componentName, UserHandle user,
@Nullable String container) { }
+ public void onDismissApp(ComponentName componentName, UserHandle user,
+ @Nullable String container){}
+
public void onReturnedToHome() { }
}
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index 97cf267d3..0a4f00582 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -16,21 +16,21 @@
package com.android.launcher3.model;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
import android.os.Looper;
import android.util.Log;
-import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel.CallbackTask;
-import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.PagedView;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.LooperIdleLock;
@@ -65,7 +65,7 @@ public abstract class BaseLoaderResults {
public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel,
AllAppsList allAppsList, int pageToBindFirst, WeakReference<Callbacks> callbacks) {
- mUiExecutor = new MainThreadExecutor();
+ mUiExecutor = MAIN_EXECUTOR;
mApp = app;
mBgDataModel = dataModel;
mBgAllAppsList = allAppsList;
@@ -279,9 +279,8 @@ public abstract class BaseLoaderResults {
public void bindAllApps() {
// shallow copy
- @SuppressWarnings("unchecked")
- ArrayList<AppInfo> list = (ArrayList<AppInfo>) mBgAllAppsList.data.clone();
- executeCallbacksTask(c -> c.bindAllApplications(list), mUiExecutor);
+ AppInfo[] apps = mBgAllAppsList.copyData();
+ executeCallbacksTask(c -> c.bindAllApplications(apps), mUiExecutor);
}
public abstract void bindWidgets();
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index eea3d8c35..e12633bcd 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -17,12 +17,12 @@ package com.android.launcher3.model;
import android.util.Log;
-import com.android.launcher3.AllAppsList;
+import com.android.launcher3.AppInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherModel.ModelUpdateTask;
import com.android.launcher3.LauncherModel.CallbackTask;
-import com.android.launcher3.LauncherModel.Callbacks;
+import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.ItemInfoMatcher;
@@ -30,6 +30,7 @@ import com.android.launcher3.widget.WidgetListRowEntry;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.concurrent.Executor;
/**
@@ -95,12 +96,7 @@ public abstract class BaseModelUpdateTask implements ModelUpdateTask {
public void bindUpdatedWorkspaceItems(final ArrayList<WorkspaceItemInfo> updatedShortcuts) {
if (!updatedShortcuts.isEmpty()) {
- scheduleCallbackTask(new CallbackTask() {
- @Override
- public void execute(Callbacks callbacks) {
- callbacks.bindWorkspaceItemsChanged(updatedShortcuts);
- }
- });
+ scheduleCallbackTask(c -> c.bindWorkspaceItemsChanged(updatedShortcuts));
}
}
@@ -113,23 +109,20 @@ public abstract class BaseModelUpdateTask implements ModelUpdateTask {
public void bindUpdatedWidgets(BgDataModel dataModel) {
final ArrayList<WidgetListRowEntry> widgets =
dataModel.widgetsModel.getWidgetsList(mApp.getContext());
- scheduleCallbackTask(new CallbackTask() {
- @Override
- public void execute(Callbacks callbacks) {
- callbacks.bindAllWidgets(widgets);
- }
- });
+ scheduleCallbackTask(c -> c.bindAllWidgets(widgets));
}
public void deleteAndBindComponentsRemoved(final ItemInfoMatcher matcher) {
getModelWriter().deleteItemsFromDatabase(matcher);
// Call the components-removed callback
- scheduleCallbackTask(new CallbackTask() {
- @Override
- public void execute(Callbacks callbacks) {
- callbacks.bindWorkspaceComponentsRemoved(matcher);
- }
- });
+ scheduleCallbackTask(c -> c.bindWorkspaceComponentsRemoved(matcher));
+ }
+
+ public void bindApplicationsIfNeeded() {
+ if (mAllAppsList.getAndResetChangeFlag()) {
+ AppInfo[] apps = mAllAppsList.copyData();
+ scheduleCallbackTask(c -> c.bindAllApplications(apps));
+ }
}
}
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 8f0cd08a9..0e2027050 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -22,11 +22,13 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.MutableInt;
+import com.android.launcher3.AppInfo;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.PromiseAppInfo;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
@@ -40,6 +42,10 @@ import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.IntSparseArrayMap;
+import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.ViewOnDrawExecutor;
+import com.android.launcher3.widget.WidgetListRowEntry;
+
import com.google.protobuf.nano.MessageNano;
import java.io.FileDescriptor;
@@ -49,6 +55,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -391,4 +398,30 @@ public class BgDataModel {
}
}
}
+
+ public interface Callbacks {
+ void rebindModel();
+
+ int getCurrentWorkspaceScreen();
+ void clearPendingBinds();
+ void startBinding();
+ void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons);
+ void bindScreens(IntArray orderedScreenIds);
+ void finishFirstPageBind(ViewOnDrawExecutor executor);
+ void finishBindingItems(int pageBoundFirst);
+ void preAddApps();
+ void bindAppsAdded(IntArray newScreens,
+ ArrayList<ItemInfo> addNotAnimated, ArrayList<ItemInfo> addAnimated);
+ void bindPromiseAppProgressUpdated(PromiseAppInfo app);
+ void bindWorkspaceItemsChanged(ArrayList<WorkspaceItemInfo> updated);
+ void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
+ void bindRestoreItemsChange(HashSet<ItemInfo> updates);
+ void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher);
+ void bindAllWidgets(ArrayList<WidgetListRowEntry> widgets);
+ void onPageBoundSynchronously(int page);
+ void executeOnNextDraw(ViewOnDrawExecutor executor);
+ void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap);
+
+ void bindAllApplications(AppInfo[] apps);
+ }
}
diff --git a/src/com/android/launcher3/model/CacheDataUpdatedTask.java b/src/com/android/launcher3/model/CacheDataUpdatedTask.java
index 7852444de..c1c8be316 100644
--- a/src/com/android/launcher3/model/CacheDataUpdatedTask.java
+++ b/src/com/android/launcher3/model/CacheDataUpdatedTask.java
@@ -18,14 +18,10 @@ package com.android.launcher3.model;
import android.content.ComponentName;
import android.os.UserHandle;
-import com.android.launcher3.AllAppsList;
-import com.android.launcher3.AppInfo;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel.CallbackTask;
-import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.LauncherSettings;
import java.util.ArrayList;
@@ -53,9 +49,9 @@ public class CacheDataUpdatedTask extends BaseModelUpdateTask {
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
IconCache iconCache = app.getIconCache();
- final ArrayList<AppInfo> updatedApps = new ArrayList<>();
ArrayList<WorkspaceItemInfo> updatedShortcuts = new ArrayList<>();
+
synchronized (dataModel) {
for (ItemInfo info : dataModel.itemsIdMap) {
if (info instanceof WorkspaceItemInfo && mUser.equals(info.user)) {
@@ -69,18 +65,10 @@ public class CacheDataUpdatedTask extends BaseModelUpdateTask {
}
}
}
- apps.updateIconsAndLabels(mPackages, mUser, updatedApps);
+ apps.updateIconsAndLabels(mPackages, mUser);
}
bindUpdatedWorkspaceItems(updatedShortcuts);
-
- if (!updatedApps.isEmpty()) {
- scheduleCallbackTask(new CallbackTask() {
- @Override
- public void execute(Callbacks callbacks) {
- callbacks.bindAppsAddedOrUpdated(updatedApps);
- }
- });
- }
+ bindApplicationsIfNeeded();
}
public boolean isValidShortcut(WorkspaceItemInfo si) {
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 7593a3371..50e1d56ae 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -19,8 +19,9 @@ package com.android.launcher3.model;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
-import static com.android.launcher3.compat.PackageInstallerCompat.getUserHandle;
import static com.android.launcher3.model.LoaderResults.filterCurrentWorkspaceItems;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.launcher3.util.PackageManagerHelper.isSystemApp;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -32,7 +33,6 @@ import android.content.pm.LauncherActivityInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.ShortcutInfo;
-import android.os.Handler;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -40,7 +40,6 @@ import android.util.Log;
import android.util.LongSparseArray;
import android.util.MutableInt;
-import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.InstallShortcutReceiver;
@@ -58,7 +57,7 @@ import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderIconPreviewVerifier;
+import com.android.launcher3.folder.FolderGridOrganizer;
import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
import com.android.launcher3.icons.IconCache;
@@ -67,9 +66,11 @@ import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.provider.ImportDataTask;
+import com.android.launcher3.qsb.QsbContainerView;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.IOUtils;
import com.android.launcher3.util.LooperIdleLock;
import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
@@ -228,9 +229,10 @@ public class LoaderTask implements Runnable {
mResults.bindWidgets();
verifyNotStopped();
- TraceHelper.partitionSection(TAG, "step 4.3: Update icon cache");
- updateHandler.updateIcons(allWidgetsList, new ComponentCachingLogic(mApp.getContext()),
- mApp.getModel()::onWidgetLabelsUpdated);
+
+ TraceHelper.partitionSection(TAG, "step 4.3: save widgets in icon cache");
+ updateHandler.updateIcons(allWidgetsList, new ComponentCachingLogic(
+ mApp.getContext(), true), mApp.getModel()::onWidgetLabelsUpdated);
verifyNotStopped();
TraceHelper.partitionSection(TAG, "step 5: Finish icon cache update");
@@ -320,9 +322,9 @@ public class LoaderTask implements Runnable {
// We can only query for shortcuts when the user is unlocked.
if (userUnlocked) {
- List<ShortcutInfo> pinnedShortcuts =
+ DeepShortcutManager.QueryResult pinnedShortcuts =
mShortcutManager.queryForPinnedShortcuts(null, user);
- if (mShortcutManager.wasLastCallSuccess()) {
+ if (pinnedShortcuts.wasSuccess()) {
for (ShortcutInfo shortcut : pinnedShortcuts) {
shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
shortcut);
@@ -387,7 +389,9 @@ public class LoaderTask implements Runnable {
boolean validTarget = TextUtils.isEmpty(targetPkg) ||
mLauncherApps.isPackageEnabledForProfile(targetPkg, c.user);
- if (cn != null && validTarget) {
+ // If it's a deep shortcut, we'll use pinned shortcuts to restore it
+ if (cn != null && validTarget && c.itemType
+ != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
// If the apk is present and the shortcut points to a specific
// component.
@@ -535,7 +539,7 @@ public class LoaderTask implements Runnable {
info.spanX = 1;
info.spanY = 1;
info.runtimeStatusFlags |= disabledState;
- if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
+ if (isSafeMode && !isSystemApp(context, intent)) {
info.runtimeStatusFlags |= FLAG_DISABLED_SAFEMODE;
}
@@ -584,10 +588,19 @@ public class LoaderTask implements Runnable {
int appWidgetId = c.getInt(appWidgetIdIndex);
String savedProvider = c.getString(appWidgetProviderIndex);
-
- final ComponentName component =
- ComponentName.unflattenFromString(savedProvider);
-
+ final ComponentName component;
+
+ boolean isSearchWidget = (c.getInt(optionsIndex)
+ & LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET) != 0;
+ if (isSearchWidget) {
+ component = QsbContainerView.getSearchComponentName(context);
+ if (component == null) {
+ c.markDeleted("Discarding SearchWidget without packagename ");
+ continue;
+ }
+ } else {
+ component = ComponentName.unflattenFromString(savedProvider);
+ }
final boolean isIdValid = !c.hasRestoreFlag(
LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
final boolean wasProviderReady = !c.hasRestoreFlag(
@@ -597,9 +610,7 @@ public class LoaderTask implements Runnable {
widgetProvidersMap = mAppWidgetManager.getAllProvidersMap();
}
final AppWidgetProviderInfo provider = widgetProvidersMap.get(
- new ComponentKey(
- ComponentName.unflattenFromString(savedProvider),
- c.user));
+ new ComponentKey(component, c.user));
final boolean isProviderReady = isValidProvider(provider);
if (!isSafeMode && !customWidget &&
@@ -665,6 +676,7 @@ public class LoaderTask implements Runnable {
c.applyCommonProperties(appWidgetInfo);
appWidgetInfo.spanX = c.getInt(spanXIndex);
appWidgetInfo.spanY = c.getInt(spanYIndex);
+ appWidgetInfo.options = c.getInt(optionsIndex);
appWidgetInfo.user = c.user;
if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
@@ -710,7 +722,7 @@ public class LoaderTask implements Runnable {
}
}
} finally {
- Utilities.closeSilently(c);
+ IOUtils.closeSilently(c);
}
// Break early if we've stopped loading
@@ -750,8 +762,8 @@ public class LoaderTask implements Runnable {
}
// Sort the folder items, update ranks, and make sure all preview items are high res.
- FolderIconPreviewVerifier verifier =
- new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile());
+ FolderGridOrganizer verifier =
+ new FolderGridOrganizer(mApp.getInvariantDeviceProfile());
for (FolderInfo folder : mBgDataModel.folders) {
Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
verifier.setFolderInfo(folder);
@@ -778,7 +790,7 @@ public class LoaderTask implements Runnable {
new SdCardAvailableReceiver(mApp, pendingPackages),
new IntentFilter(Intent.ACTION_BOOT_COMPLETED),
null,
- new Handler(LauncherModel.getWorkerLooper()));
+ MODEL_EXECUTOR.getHandler());
}
}
}
@@ -836,7 +848,7 @@ public class LoaderTask implements Runnable {
}
}
- mBgAllAppsList.added = new ArrayList<>();
+ mBgAllAppsList.getAndResetChangeFlag();
return allActivityList;
}
diff --git a/src/com/android/launcher3/model/ModelPreload.java b/src/com/android/launcher3/model/ModelPreload.java
index b353810ef..2bd6cd4db 100644
--- a/src/com/android/launcher3/model/ModelPreload.java
+++ b/src/com/android/launcher3/model/ModelPreload.java
@@ -18,7 +18,6 @@ package com.android.launcher3.model;
import android.content.Context;
import android.util.Log;
-import com.android.launcher3.AllAppsList;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherModel.ModelUpdateTask;
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 4ce2f4ba9..bdf3a6918 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -16,6 +16,8 @@
package com.android.launcher3.model;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -31,23 +33,25 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetHost;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.LauncherProvider;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherSettings.Settings;
-import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.Utilities;
+import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.LooperExecutor;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
/**
* Class for handling model updates.
@@ -61,7 +65,6 @@ public class ModelWriter {
private final BgDataModel mBgDataModel;
private final Handler mUiHandler;
- private final Executor mWorkerExecutor;
private final boolean mHasVerticalHotseat;
private final boolean mVerifyChanges;
@@ -74,7 +77,6 @@ public class ModelWriter {
mContext = context;
mModel = model;
mBgDataModel = dataModel;
- mWorkerExecutor = new LooperExecutor(LauncherModel.getWorkerLooper());
mHasVerticalHotseat = hasVerticalHotseat;
mVerifyChanges = verifyChanges;
mUiHandler = new Handler(Looper.getMainLooper());
@@ -101,7 +103,7 @@ public class ModelWriter {
*/
public void addOrMoveItemInDatabase(ItemInfo item,
int container, int screenId, int cellX, int cellY) {
- if (item.container == ItemInfo.NO_ID) {
+ if (item.id == ItemInfo.NO_ID) {
// From all apps
addItemToDatabase(item, container, screenId, cellX, cellY);
} else {
@@ -194,7 +196,7 @@ public class ModelWriter {
item.spanX = spanX;
item.spanY = spanY;
- mWorkerExecutor.execute(new UpdateItemRunnable(item, () ->
+ ((Executor) MODEL_EXECUTOR).execute(new UpdateItemRunnable(item, () ->
new ContentWriter(mContext)
.put(Favorites.CONTAINER, item.container)
.put(Favorites.CELLX, item.cellX)
@@ -209,7 +211,7 @@ public class ModelWriter {
* Update an item to the database in a specified container.
*/
public void updateItemInDatabase(ItemInfo item) {
- mWorkerExecutor.execute(new UpdateItemRunnable(item, () -> {
+ ((Executor) MODEL_EXECUTOR).execute(new UpdateItemRunnable(item, () -> {
ContentWriter writer = new ContentWriter(mContext);
item.onAddToDatabase(writer);
return writer;
@@ -229,7 +231,7 @@ public class ModelWriter {
ModelVerifier verifier = new ModelVerifier();
final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
- mWorkerExecutor.execute(() -> {
+ ((Executor) MODEL_EXECUTOR).execute(() -> {
// Write the item on background thread, as some properties might have been updated in
// the background.
final ContentWriter writer = new ContentWriter(mContext);
@@ -263,9 +265,12 @@ public class ModelWriter {
/**
* Removes the specified items from the database
*/
- public void deleteItemsFromDatabase(final Iterable<? extends ItemInfo> items) {
+ public void deleteItemsFromDatabase(final Collection<? extends ItemInfo> items) {
ModelVerifier verifier = new ModelVerifier();
-
+ FileLog.d(TAG, "removing items from db " + items.stream().map(
+ (item) -> item.getTargetComponent() == null ? ""
+ : item.getTargetComponent().getPackageName()).collect(
+ Collectors.joining(",")), new Exception());
enqueueDeleteRunnable(() -> {
for (ItemInfo item : items) {
final Uri uri = Favorites.getContentUri(item.id);
@@ -333,14 +338,14 @@ public class ModelWriter {
if (mPreparingToUndo) {
mDeleteRunnables.add(r);
} else {
- mWorkerExecutor.execute(r);
+ ((Executor) MODEL_EXECUTOR).execute(r);
}
}
public void commitDelete() {
mPreparingToUndo = false;
for (Runnable runnable : mDeleteRunnables) {
- mWorkerExecutor.execute(runnable);
+ ((Executor) MODEL_EXECUTOR).execute(runnable);
}
mDeleteRunnables.clear();
}
diff --git a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
index 9fcab3887..802cbc7c5 100644
--- a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
+++ b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
@@ -19,20 +19,18 @@ import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import com.android.launcher3.AllAppsList;
import com.android.launcher3.AppInfo;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
import com.android.launcher3.LauncherModel.CallbackTask;
-import com.android.launcher3.LauncherModel.Callbacks;
+import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.PromiseAppInfo;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.util.InstantAppResolver;
-import java.util.ArrayList;
import java.util.HashSet;
/**
@@ -65,41 +63,11 @@ public class PackageInstallStateChangedTask extends BaseModelUpdateTask {
}
synchronized (apps) {
- PromiseAppInfo updated = null;
- final ArrayList<AppInfo> removed = new ArrayList<>();
- for (int i=0; i < apps.size(); i++) {
- final AppInfo appInfo = apps.get(i);
- final ComponentName tgtComp = appInfo.getTargetComponent();
- if (tgtComp != null && tgtComp.getPackageName().equals(mInstallInfo.packageName)) {
- if (appInfo instanceof PromiseAppInfo) {
- final PromiseAppInfo promiseAppInfo = (PromiseAppInfo) appInfo;
- if (mInstallInfo.state == PackageInstallerCompat.STATUS_INSTALLING) {
- promiseAppInfo.level = mInstallInfo.progress;
- updated = promiseAppInfo;
- } else if (mInstallInfo.state == PackageInstallerCompat.STATUS_FAILED) {
- apps.removePromiseApp(appInfo);
- removed.add(appInfo);
- }
- }
- }
- }
+ PromiseAppInfo updated = apps.updatePromiseInstallInfo(mInstallInfo);
if (updated != null) {
- final PromiseAppInfo updatedPromiseApp = updated;
- scheduleCallbackTask(new CallbackTask() {
- @Override
- public void execute(Callbacks callbacks) {
- callbacks.bindPromiseAppProgressUpdated(updatedPromiseApp);
- }
- });
- }
- if (!removed.isEmpty()) {
- scheduleCallbackTask(new CallbackTask() {
- @Override
- public void execute(Callbacks callbacks) {
- callbacks.bindAppInfosRemoved(removed);
- }
- });
+ scheduleCallbackTask(c -> c.bindPromiseAppProgressUpdated(updated));
}
+ bindApplicationsIfNeeded();
}
synchronized (dataModel) {
diff --git a/src/com/android/launcher3/model/PackageItemInfo.java b/src/com/android/launcher3/model/PackageItemInfo.java
index baeaa9492..3ef48cd8f 100644
--- a/src/com/android/launcher3/model/PackageItemInfo.java
+++ b/src/com/android/launcher3/model/PackageItemInfo.java
@@ -17,6 +17,7 @@
package com.android.launcher3.model;
import com.android.launcher3.ItemInfoWithIcon;
+import com.android.launcher3.LauncherSettings;
/**
* Represents a {@link Package} in the widget tray section.
@@ -30,10 +31,21 @@ public class PackageItemInfo extends ItemInfoWithIcon {
public PackageItemInfo(String packageName) {
this.packageName = packageName;
+ this.itemType = LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE;
+ }
+
+ public PackageItemInfo(PackageItemInfo copy) {
+ this.packageName = copy.packageName;
+ this.itemType = LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE;
}
@Override
protected String dumpProperties() {
return super.dumpProperties() + " packageName=" + packageName;
}
+
+ @Override
+ public PackageItemInfo clone() {
+ return new PackageItemInfo(this);
+ }
}
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 4428c8e6d..d6ebaaf10 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.model;
+import static com.android.launcher3.WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -23,23 +25,19 @@ import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
-import com.android.launcher3.AllAppsList;
-import com.android.launcher3.AppInfo;
-import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.icons.IconCache;
import com.android.launcher3.InstallShortcutReceiver;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetInfo;
-import com.android.launcher3.LauncherModel.CallbackTask;
-import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.SessionCommitReceiver;
import com.android.launcher3.Utilities;
+import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.shortcuts.DeepShortcutManager;
@@ -49,6 +47,7 @@ import com.android.launcher3.util.IntSparseArrayMap;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.SafeCloseable;
import java.util.ArrayList;
import java.util.Arrays;
@@ -57,6 +56,7 @@ import java.util.HashSet;
import java.util.List;
import static com.android.launcher3.WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON;
+import static com.android.launcher3.WorkspaceItemInfo.FLAG_RESTORED_ICON;
/**
* Handles updates due to changes in package manager (app installed/updated/removed)
@@ -100,6 +100,8 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
FlagOp flagOp = FlagOp.NO_OP;
final HashSet<String> packageSet = new HashSet<>(Arrays.asList(packages));
ItemInfoMatcher matcher = ItemInfoMatcher.ofPackages(packageSet, mUser);
+ final HashSet<ComponentName> removedComponents = new HashSet<>();
+
switch (mOp) {
case OP_ADD: {
for (int i = 0; i < N; i++) {
@@ -119,17 +121,21 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
break;
}
case OP_UPDATE:
- for (int i = 0; i < N; i++) {
- if (DEBUG) Log.d(TAG, "mAllAppsList.updatePackage " + packages[i]);
- iconCache.updateIconsForPkg(packages[i], mUser);
- appsList.updatePackage(context, packages[i], mUser);
- app.getWidgetCache().removePackage(packages[i], mUser);
+ try (SafeCloseable t =
+ appsList.trackRemoves(a -> removedComponents.add(a.componentName))) {
+ for (int i = 0; i < N; i++) {
+ if (DEBUG) Log.d(TAG, "mAllAppsList.updatePackage " + packages[i]);
+ iconCache.updateIconsForPkg(packages[i], mUser);
+ appsList.updatePackage(context, packages[i], mUser);
+ app.getWidgetCache().removePackage(packages[i], mUser);
+ }
}
// Since package was just updated, the target must be available now.
flagOp = FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
break;
case OP_REMOVE: {
for (int i = 0; i < N; i++) {
+ FileLog.d(TAG, "Removing app icon" + packages[i]);
iconCache.removeIconsForPkg(packages[i], mUser);
}
// Fall through
@@ -160,23 +166,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
break;
}
- final ArrayList<AppInfo> addedOrModified = new ArrayList<>();
- addedOrModified.addAll(appsList.added);
- appsList.added.clear();
- addedOrModified.addAll(appsList.modified);
- appsList.modified.clear();
- if (!addedOrModified.isEmpty()) {
- scheduleCallbackTask((callbacks) -> callbacks.bindAppsAddedOrUpdated(addedOrModified));
- }
-
- final ArrayList<AppInfo> removedApps = new ArrayList<>(appsList.removed);
- appsList.removed.clear();
- final HashSet<ComponentName> removedComponents = new HashSet<>();
- if (mOp == OP_UPDATE) {
- for (AppInfo ai : removedApps) {
- removedComponents.add(ai.componentName);
- }
- }
+ bindApplicationsIfNeeded();
final IntSparseArrayMap<Boolean> removedShortcuts = new IntSparseArrayMap<>();
@@ -234,7 +224,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
isTargetValid = LauncherAppsCompat.getInstance(context)
.isActivityEnabledForProfile(cn, mUser);
}
- if (si.hasStatusFlag(FLAG_AUTOINSTALL_ICON)) {
+ if (si.hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON)) {
if (updateWorkspaceItemIntent(context, si, packageName)) {
infoUpdated = true;
} else if (si.hasPromiseIconUi()) {
@@ -302,12 +292,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
}
if (!widgets.isEmpty()) {
- scheduleCallbackTask(new CallbackTask() {
- @Override
- public void execute(Callbacks callbacks) {
- callbacks.bindWidgetsRestored(widgets);
- }
- });
+ scheduleCallbackTask(c -> c.bindWidgetsRestored(widgets));
}
}
@@ -338,16 +323,6 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
InstallShortcutReceiver.removeFromInstallQueue(context, removedPackages, mUser);
}
- if (!removedApps.isEmpty()) {
- // Remove corresponding apps from All-Apps
- scheduleCallbackTask(new CallbackTask() {
- @Override
- public void execute(Callbacks callbacks) {
- callbacks.bindAppInfosRemoved(removedApps);
- }
- });
- }
-
if (Utilities.ATLEAST_OREO && mOp == OP_ADD) {
// Load widgets for the new package. Changes due to app updates are handled through
// AppWidgetHost events, this is just to initialize the long-press options.
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index 8528228f2..6c358b170 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -19,7 +19,6 @@ import android.content.Context;
import android.content.pm.ShortcutInfo;
import android.os.UserHandle;
-import com.android.launcher3.AllAppsList;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
@@ -65,7 +64,7 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask {
for (ItemInfo itemInfo : dataModel.itemsIdMap) {
if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
WorkspaceItemInfo si = (WorkspaceItemInfo) itemInfo;
- if (si.getIntent().getPackage().equals(mPackageName) && si.user.equals(mUser)) {
+ if (mPackageName.equals(si.getIntent().getPackage()) && si.user.equals(mUser)) {
keyToShortcutInfo.addToList(ShortcutKey.fromItemInfo(si), si);
allIds.add(si.getDeepShortcutId());
}
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 2cb256e09..4b773d720 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.content.pm.ShortcutInfo;
import android.os.UserHandle;
-import com.android.launcher3.AllAppsList;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
@@ -37,7 +36,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.List;
/**
* Task to handle changing of lock state of the user
@@ -58,9 +56,9 @@ public class UserLockStateChangedTask extends BaseModelUpdateTask {
HashMap<ShortcutKey, ShortcutInfo> pinnedShortcuts = new HashMap<>();
if (isUserUnlocked) {
- List<ShortcutInfo> shortcuts =
+ DeepShortcutManager.QueryResult shortcuts =
deepShortcutManager.queryForPinnedShortcuts(null, mUser);
- if (deepShortcutManager.wasLastCallSuccess()) {
+ if (shortcuts.wasSuccess()) {
for (ShortcutInfo shortcut : shortcuts) {
pinnedShortcuts.put(ShortcutKey.fromInfo(shortcut), shortcut);
}