summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/launcher3/AppFilter.java5
-rw-r--r--src/com/android/launcher3/Launcher.java2
-rw-r--r--src/com/android/launcher3/LauncherAppState.java4
-rw-r--r--src/com/android/launcher3/LauncherModel.java288
-rw-r--r--src/com/android/launcher3/model/BgDataModel.java10
-rw-r--r--src/com/android/launcher3/model/ExtendedModelTask.java11
-rw-r--r--src/com/android/launcher3/model/LoaderResults.java17
-rw-r--r--src/com/android/launcher3/model/PackageUpdatedTask.java7
-rw-r--r--src/com/android/launcher3/model/SdCardAvailableReceiver.java7
-rw-r--r--src/com/android/launcher3/model/WidgetsModel.java41
10 files changed, 209 insertions, 183 deletions
diff --git a/src/com/android/launcher3/AppFilter.java b/src/com/android/launcher3/AppFilter.java
index db8f5dd0e..923835a67 100644
--- a/src/com/android/launcher3/AppFilter.java
+++ b/src/com/android/launcher3/AppFilter.java
@@ -1,9 +1,14 @@
package com.android.launcher3;
import android.content.ComponentName;
+import android.content.Context;
public class AppFilter {
+ public static AppFilter newInstance(Context context) {
+ return Utilities.getOverrideObject(AppFilter.class, context, R.string.app_filter_class);
+ }
+
public boolean shouldShowApp(ComponentName app) {
return true;
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ff7ca812b..c8c566187 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -3970,7 +3970,7 @@ public class Launcher extends BaseActivity
* refreshes the widgets and shortcuts associated with the given package/user
*/
public void refreshAndBindWidgetsForPackageUser(@Nullable PackageUserKey packageUser) {
- mModel.refreshAndBindWidgetsAndShortcuts(this, mWidgetsView.isEmpty(), packageUser);
+ mModel.refreshAndBindWidgetsAndShortcuts(packageUser);
}
public void lockScreenOrientation() {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 27ccabea9..cf20febd5 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -93,9 +93,7 @@ public class LauncherAppState {
mInvariantDeviceProfile = new InvariantDeviceProfile(mContext);
mIconCache = new IconCache(mContext, mInvariantDeviceProfile);
mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
-
- mModel = new LauncherModel(this, mIconCache,
- Utilities.getOverrideObject(AppFilter.class, mContext, R.string.app_filter_class));
+ mModel = new LauncherModel(this, mIconCache, AppFilter.newInstance(mContext));
LauncherAppsCompat.getInstance(mContext).addOnAppsChangedCallback(mModel);
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index ee06d9e58..265c7e33a 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -69,7 +69,6 @@ import com.android.launcher3.model.SdCardAvailableReceiver;
import com.android.launcher3.model.ShortcutsChangedTask;
import com.android.launcher3.model.UserLockStateChangedTask;
import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.provider.ImportDataTask;
import com.android.launcher3.provider.LauncherDbUtils;
import com.android.launcher3.shortcuts.DeepShortcutManager;
@@ -116,7 +115,6 @@ public class LauncherModel extends BroadcastReceiver
@Thunk final Object mLock = new Object();
@Thunk LoaderTask mLoaderTask;
@Thunk boolean mIsLoaderTaskRunning;
- @Thunk boolean mHasLoaderCompletedOnce;
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
static {
@@ -139,10 +137,13 @@ public class LauncherModel extends BroadcastReceiver
// < only access in worker thread >
private final AllAppsList mBgAllAppsList;
- // Entire list of widgets.
- private final WidgetsModel mBgWidgetsModel;
- private boolean mHasShortcutHostPermission;
+ /**
+ * All the static data should be accessed on the background thread, A lock should be acquired
+ * on this object when accessing any data from this model.
+ */
+ static final BgDataModel sBgDataModel = new BgDataModel();
+
// Runnable to check if the shortcuts permission has changed.
private final Runnable mShortcutPermissionCheckRunnable = new Runnable() {
@Override
@@ -150,26 +151,13 @@ public class LauncherModel extends BroadcastReceiver
if (mModelLoaded) {
boolean hasShortcutHostPermission =
DeepShortcutManager.getInstance(mApp.getContext()).hasHostPermission();
- if (hasShortcutHostPermission != mHasShortcutHostPermission) {
+ if (hasShortcutHostPermission != sBgDataModel.hasShortcutHostPermission) {
forceReload();
}
}
}
};
- /**
- * All the static data should be accessed on the background thread, A lock should be acquired
- * on this object when accessing any data from this model.
- */
- static final BgDataModel sBgDataModel = new BgDataModel();
-
- // </ only access in worker thread >
-
- private final IconCache mIconCache;
-
- private final LauncherAppsCompat mLauncherApps;
- private final UserManagerCompat mUserManager;
-
public interface Callbacks {
public boolean setLoadOnResume();
public int getCurrentWorkspaceScreen();
@@ -204,14 +192,8 @@ public class LauncherModel extends BroadcastReceiver
}
LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) {
- Context context = app.getContext();
mApp = app;
mBgAllAppsList = new AllAppsList(iconCache, appFilter);
- mBgWidgetsModel = new WidgetsModel(iconCache, appFilter);
- mIconCache = iconCache;
-
- mLauncherApps = LauncherAppsCompat.getInstance(context);
- mUserManager = UserManagerCompat.getInstance(context);
}
/** Runs the specified runnable immediately if called from the worker thread, otherwise it is
@@ -539,9 +521,10 @@ public class LauncherModel extends BroadcastReceiver
// issues that arise from that.
loaderResults.bindAllApps();
loaderResults.bindDeepShortcuts();
+ loaderResults.bindWidgets();
return true;
} else {
- mLoaderTask = new LoaderTask(mApp.getContext(), loaderResults);
+ mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, loaderResults);
sWorker.post(mLoaderTask);
}
}
@@ -588,6 +571,44 @@ public class LauncherModel extends BroadcastReceiver
});
}
+ public class LoaderTransaction implements AutoCloseable {
+
+ private final LoaderTask mTask;
+
+ private LoaderTransaction(LoaderTask task) throws CancellationException {
+ synchronized (mLock) {
+ if (mLoaderTask != task) {
+ throw new CancellationException("Loader already stopped");
+ }
+ mTask = task;
+ mIsLoaderTaskRunning = true;
+ mModelLoaded = false;
+ }
+ }
+
+ public void commit() {
+ synchronized (mLock) {
+ // Everything loaded bind the data.
+ mModelLoaded = true;
+ }
+ }
+
+ @Override
+ public void close() {
+ synchronized (mLock) {
+ // If we are still the last one to be scheduled, remove ourselves.
+ if (mLoaderTask == mTask) {
+ mLoaderTask = null;
+ }
+ mIsLoaderTaskRunning = false;
+ }
+ }
+ }
+
+ public LoaderTransaction beginLoader(LoaderTask task) throws CancellationException {
+ return new LoaderTransaction(task);
+ }
+
/**
* Runnable for the thread that loads the contents of the launcher:
* - workspace icons
@@ -595,46 +616,62 @@ public class LauncherModel extends BroadcastReceiver
* - all apps icons
* - deep shortcuts within apps
*/
- private class LoaderTask implements Runnable {
- private Context mContext;
+ private static class LoaderTask implements Runnable {
+ private final LauncherAppState mApp;
+ private final AllAppsList mBgAllAppsList;
+ private final BgDataModel mBgDataModel;
+
private final LoaderResults mResults;
+ private final LauncherAppsCompat mLauncherApps;
+ private final UserManagerCompat mUserManager;
+ private final DeepShortcutManager mShortcutManager;
+ private final PackageInstallerCompat mPackageInstaller;
+ private final AppWidgetManagerCompat mAppWidgetManager;
+ private final IconCache mIconCache;
+
private boolean mStopped;
- LoaderTask(Context context, LoaderResults results) {
- mContext = context;
+ LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel,
+ LoaderResults results) {
+ mApp = app;
+ mBgAllAppsList = bgAllAppsList;
+ mBgDataModel = dataModel;
mResults = results;
+
+ mLauncherApps = LauncherAppsCompat.getInstance(mApp.getContext());
+ mUserManager = UserManagerCompat.getInstance(mApp.getContext());
+ mShortcutManager = DeepShortcutManager.getInstance(mApp.getContext());
+ mPackageInstaller = PackageInstallerCompat.getInstance(mApp.getContext());
+ mAppWidgetManager = AppWidgetManagerCompat.getInstance(mApp.getContext());
+ mIconCache = mApp.getIconCache();
}
- private void waitForIdle() {
+ private synchronized void waitForIdle() {
// Wait until the either we're stopped or the other threads are done.
// This way we don't start loading all apps until the workspace has settled
// down.
- synchronized (LoaderTask.this) {
- LooperIdleLock idleLock = new LooperIdleLock(this, Looper.getMainLooper());
- // Just in case mFlushingWorkerThread changes but we aren't woken up,
- // wait no longer than 1sec at a time
- while (!mStopped && idleLock.awaitLocked(1000));
- }
+ LooperIdleLock idleLock = new LooperIdleLock(this, Looper.getMainLooper());
+ // Just in case mFlushingWorkerThread changes but we aren't woken up,
+ // wait no longer than 1sec at a time
+ while (!mStopped && idleLock.awaitLocked(1000));
}
- private void verifyNotStopped() throws CancellationException {
- synchronized (LoaderTask.this) {
- if (mStopped) {
- throw new CancellationException("Loader stopped");
- }
+ private synchronized void verifyNotStopped() throws CancellationException {
+ if (mStopped) {
+ throw new CancellationException("Loader stopped");
}
}
public void run() {
- synchronized (mLock) {
+ synchronized (this) {
+ // Skip fast if we are already stopped.
if (mStopped) {
return;
}
- mIsLoaderTaskRunning = true;
}
- try {
+ try (LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
long now = 0;
if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
loadWorkspace();
@@ -688,36 +725,21 @@ public class LauncherModel extends BroadcastReceiver
// fourth step
if (DEBUG_LOADERS) Log.d(TAG, "step 4.1: loading widgets");
- refreshAndBindWidgetsAndShortcuts(getCallback(), false /* bindFirst */,
- null /* packageUser */);
+ mBgDataModel.widgetsModel.update(mApp, null);
- synchronized (mLock) {
- // Everything loaded bind the data.
- mModelLoaded = true;
- mHasLoaderCompletedOnce = true;
- }
+ verifyNotStopped();
+ if (DEBUG_LOADERS) Log.d(TAG, "step 4.2: Binding widgets");
+ mResults.bindWidgets();
+
+ transaction.commit();
} catch (CancellationException e) {
// Loader stopped, ignore
- } finally {
- // Clear out this reference, otherwise we end up holding it until all of the
- // callback runnables are done.
- mContext = null;
-
- synchronized (mLock) {
- // If we are still the last one to be scheduled, remove ourselves.
- if (mLoaderTask == this) {
- mLoaderTask = null;
- }
- mIsLoaderTaskRunning = false;
- }
}
}
- public void stopLocked() {
- synchronized (LoaderTask.this) {
- mStopped = true;
- this.notify();
- }
+ public synchronized void stopLocked() {
+ mStopped = true;
+ this.notify();
}
private void loadWorkspace() {
@@ -725,12 +747,10 @@ public class LauncherModel extends BroadcastReceiver
Trace.beginSection("Loading Workspace");
}
- final Context context = mContext;
+ final Context context = mApp.getContext();
final ContentResolver contentResolver = context.getContentResolver();
final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
final boolean isSafeMode = pmHelper.isSafeMode();
- final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
- final DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(context);
final boolean isSdCardReady = Utilities.isBootCompleted();
final MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>();
@@ -743,7 +763,7 @@ public class LauncherModel extends BroadcastReceiver
}
if (!clearDb && GridSizeMigrationTask.ENABLED &&
- !GridSizeMigrationTask.migrateGridIfNeeded(mContext)) {
+ !GridSizeMigrationTask.migrateGridIfNeeded(context)) {
// Migration failed. Clear workspace.
clearDb = true;
}
@@ -758,12 +778,12 @@ public class LauncherModel extends BroadcastReceiver
LauncherSettings.Settings.call(contentResolver,
LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES);
- synchronized (sBgDataModel) {
- sBgDataModel.clear();
+ synchronized (mBgDataModel) {
+ mBgDataModel.clear();
- final HashMap<String, Integer> installingPkgs = PackageInstallerCompat
- .getInstance(mContext).updateAndGetActiveSessionCache();
- sBgDataModel.workspaceScreens.addAll(loadWorkspaceScreensDb(mContext));
+ final HashMap<String, Integer> installingPkgs =
+ mPackageInstaller.updateAndGetActiveSessionCache();
+ mBgDataModel.workspaceScreens.addAll(loadWorkspaceScreensDb(context));
Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>();
final LoaderCursor c = new LoaderCursor(contentResolver.query(
@@ -798,8 +818,8 @@ public class LauncherModel extends BroadcastReceiver
// We can only query for shortcuts when the user is unlocked.
if (userUnlocked) {
List<ShortcutInfoCompat> pinnedShortcuts =
- shortcutManager.queryForPinnedShortcuts(null, user);
- if (shortcutManager.wasLastCallSuccess()) {
+ mShortcutManager.queryForPinnedShortcuts(null, user);
+ if (mShortcutManager.wasLastCallSuccess()) {
for (ShortcutInfoCompat shortcut : pinnedShortcuts) {
shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
shortcut);
@@ -864,14 +884,14 @@ public class LauncherModel extends BroadcastReceiver
// If there is no target package, its an implicit intent
// (legacy shortcut) which is always valid
boolean validTarget = TextUtils.isEmpty(targetPkg) ||
- launcherApps.isPackageEnabledForProfile(targetPkg, c.user);
+ mLauncherApps.isPackageEnabledForProfile(targetPkg, c.user);
if (cn != null && validTarget) {
// If the apk is present and the shortcut points to a specific
// component.
// If the component is already present
- if (launcherApps.isActivityEnabledForProfile(cn, c.user)) {
+ if (mLauncherApps.isActivityEnabledForProfile(cn, c.user)) {
// no special handling necessary for this item
c.markRestored();
} else {
@@ -1022,14 +1042,14 @@ public class LauncherModel extends BroadcastReceiver
}
}
- c.checkAndAddItem(info, sBgDataModel);
+ c.checkAndAddItem(info, mBgDataModel);
} else {
throw new RuntimeException("Unexpected null ShortcutInfo");
}
break;
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
- FolderInfo folderInfo = sBgDataModel.findOrMakeFolder(c.id);
+ FolderInfo folderInfo = mBgDataModel.findOrMakeFolder(c.id);
c.applyCommonProperties(folderInfo);
// Do not trim the folder label, as is was set by the user.
@@ -1041,7 +1061,7 @@ public class LauncherModel extends BroadcastReceiver
// no special handling required for restored folders
c.markRestored();
- c.checkAndAddItem(folderInfo, sBgDataModel);
+ c.checkAndAddItem(folderInfo, mBgDataModel);
break;
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
@@ -1062,8 +1082,7 @@ public class LauncherModel extends BroadcastReceiver
LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
if (widgetProvidersMap == null) {
- widgetProvidersMap = AppWidgetManagerCompat
- .getInstance(mContext).getAllProvidersMap();
+ widgetProvidersMap = mAppWidgetManager.getAllProvidersMap();
}
final AppWidgetProviderInfo provider = widgetProvidersMap.get(
new ComponentKey(
@@ -1161,7 +1180,7 @@ public class LauncherModel extends BroadcastReceiver
appWidgetInfo.pendingItemInfo, false);
}
- c.checkAndAddItem(appWidgetInfo, sBgDataModel);
+ c.checkAndAddItem(appWidgetInfo, mBgDataModel);
}
break;
}
@@ -1175,7 +1194,7 @@ public class LauncherModel extends BroadcastReceiver
// Break early if we've stopped loading
if (mStopped) {
- sBgDataModel.clear();
+ mBgDataModel.clear();
return;
}
@@ -1187,9 +1206,9 @@ public class LauncherModel extends BroadcastReceiver
LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS)
.getSerializable(LauncherSettings.Settings.EXTRA_VALUE);
for (long folderId : deletedFolderIds) {
- sBgDataModel.workspaceItems.remove(sBgDataModel.folders.get(folderId));
- sBgDataModel.folders.remove(folderId);
- sBgDataModel.itemsIdMap.remove(folderId);
+ mBgDataModel.workspaceItems.remove(mBgDataModel.folders.get(folderId));
+ mBgDataModel.folders.remove(folderId);
+ mBgDataModel.itemsIdMap.remove(folderId);
}
// Remove any ghost widgets
@@ -1201,18 +1220,18 @@ public class LauncherModel extends BroadcastReceiver
HashSet<ShortcutKey> pendingShortcuts =
InstallShortcutReceiver.getPendingShortcuts(context);
for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) {
- MutableInt numTimesPinned = sBgDataModel.pinnedShortcutCounts.get(key);
+ MutableInt numTimesPinned = mBgDataModel.pinnedShortcutCounts.get(key);
if ((numTimesPinned == null || numTimesPinned.value == 0)
&& !pendingShortcuts.contains(key)) {
// Shortcut is pinned but doesn't exist on the workspace; unpin it.
- shortcutManager.unpinShortcut(key);
+ mShortcutManager.unpinShortcut(key);
}
}
FolderIconPreviewVerifier verifier =
new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile());
// Sort the folder items and make sure all items in the preview are high resolution.
- for (FolderInfo folder : sBgDataModel.folders) {
+ for (FolderInfo folder : mBgDataModel.folders) {
Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
verifier.setFolderInfo(folder);
@@ -1234,16 +1253,15 @@ public class LauncherModel extends BroadcastReceiver
c.commitRestoredItems();
if (!isSdCardReady && !pendingPackages.isEmpty()) {
context.registerReceiver(
- new SdCardAvailableReceiver(
- LauncherModel.this, mContext, pendingPackages),
+ new SdCardAvailableReceiver(mApp, pendingPackages),
new IntentFilter(Intent.ACTION_BOOT_COMPLETED),
null,
sWorker);
}
// Remove any empty screens
- ArrayList<Long> unusedScreens = new ArrayList<>(sBgDataModel.workspaceScreens);
- for (ItemInfo item: sBgDataModel.itemsIdMap) {
+ ArrayList<Long> unusedScreens = new ArrayList<>(mBgDataModel.workspaceScreens);
+ for (ItemInfo item: mBgDataModel.itemsIdMap) {
long screenId = item.screenId;
if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
unusedScreens.contains(screenId)) {
@@ -1253,8 +1271,8 @@ public class LauncherModel extends BroadcastReceiver
// If there are any empty screens remove them, and update.
if (unusedScreens.size() != 0) {
- sBgDataModel.workspaceScreens.removeAll(unusedScreens);
- updateWorkspaceScreenOrder(context, sBgDataModel.workspaceScreens);
+ mBgDataModel.workspaceScreens.removeAll(unusedScreens);
+ updateWorkspaceScreenOrder(context, mBgDataModel.workspaceScreens);
}
}
if (LauncherAppState.PROFILE_STARTUP) {
@@ -1265,8 +1283,8 @@ public class LauncherModel extends BroadcastReceiver
private void updateIconCache() {
// Ignore packages which have a promise icon.
HashSet<String> packagesToIgnore = new HashSet<>();
- synchronized (sBgDataModel) {
- for (ItemInfo info : sBgDataModel.itemsIdMap) {
+ synchronized (mBgDataModel) {
+ for (ItemInfo info : mBgDataModel.itemsIdMap) {
if (info instanceof ShortcutInfo) {
ShortcutInfo si = (ShortcutInfo) info;
if (si.isPromise() && si.getTargetComponent() != null) {
@@ -1312,14 +1330,14 @@ public class LauncherModel extends BroadcastReceiver
mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
}
- ManagedProfileHeuristic.onAllAppsLoaded(mContext, apps, user);
+ ManagedProfileHeuristic.onAllAppsLoaded(mApp.getContext(), apps, user);
}
if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) {
// get all active sessions and add them to the all apps list
- PackageInstallerCompat installer = PackageInstallerCompat.getInstance(mContext);
- for (PackageInstaller.SessionInfo info : installer.getAllVerifiedSessions()) {
- mBgAllAppsList.addPromiseApp(mContext,
+ for (PackageInstaller.SessionInfo info :
+ mPackageInstaller.getAllVerifiedSessions()) {
+ mBgAllAppsList.addPromiseApp(mApp.getContext(),
PackageInstallInfo.fromInstallingState(info));
}
}
@@ -1332,15 +1350,14 @@ public class LauncherModel extends BroadcastReceiver
}
private void loadDeepShortcuts() {
- sBgDataModel.deepShortcutMap.clear();
- DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(mContext);
- mHasShortcutHostPermission = shortcutManager.hasHostPermission();
- if (mHasShortcutHostPermission) {
+ mBgDataModel.deepShortcutMap.clear();
+ mBgDataModel.hasShortcutHostPermission = mShortcutManager.hasHostPermission();
+ if (mBgDataModel.hasShortcutHostPermission) {
for (UserHandle user : mUserManager.getUserProfiles()) {
if (mUserManager.isUserUnlocked(user)) {
List<ShortcutInfoCompat> shortcuts =
- shortcutManager.queryForAllShortcuts(user);
- sBgDataModel.updateDeepShortcutMap(null, user, shortcuts);
+ mShortcutManager.queryForAllShortcuts(user);
+ mBgDataModel.updateDeepShortcutMap(null, user, shortcuts);
}
}
}
@@ -1370,12 +1387,6 @@ public class LauncherModel extends BroadcastReceiver
}
public void enqueueModelUpdateTask(BaseModelUpdateTask task) {
- if (!mModelLoaded && mLoaderTask == null) {
- if (DEBUG_LOADERS) {
- Log.d(TAG, "enqueueModelUpdateTask Ignoring task since loader is pending=" + task);
- }
- return;
- }
task.init(this);
runOnWorkerThread(task);
}
@@ -1404,8 +1415,11 @@ public class LauncherModel extends BroadcastReceiver
}
@Override
- public void run() {
- if (!mModel.mHasLoaderCompletedOnce) {
+ public final void run() {
+ if (!mModel.mModelLoaded) {
+ if (DEBUG_LOADERS) {
+ Log.d(TAG, "Ignoring model task since loader is pending=" + this);
+ }
// Loader has not yet run.
return;
}
@@ -1465,34 +1479,12 @@ public class LauncherModel extends BroadcastReceiver
});
}
- private void bindWidgetsModel(final Callbacks callbacks) {
- final MultiHashMap<PackageItemInfo, WidgetItem> widgets
- = mBgWidgetsModel.getWidgetsMap().clone();
- mUiExecutor.execute(new Runnable() {
- @Override
- public void run() {
- Callbacks cb = getCallback();
- if (callbacks == cb && cb != null) {
- callbacks.bindAllWidgets(widgets);
- }
- }
- });
- }
-
- public void refreshAndBindWidgetsAndShortcuts(final Callbacks callbacks,
- final boolean bindFirst, @Nullable final PackageUserKey packageUser) {
- runOnWorkerThread(new Runnable() {
+ public void refreshAndBindWidgetsAndShortcuts(@Nullable final PackageUserKey packageUser) {
+ enqueueModelUpdateTask(new ExtendedModelTask() {
@Override
- public void run() {
- if (bindFirst && !mBgWidgetsModel.isEmpty()) {
- bindWidgetsModel(callbacks);
- }
- ArrayList<WidgetItem> widgets = mBgWidgetsModel.update(
- mApp.getContext(), packageUser);
- bindWidgetsModel(callbacks);
-
- // update the Widget entries inside DB on the worker thread.
- mApp.getWidgetCache().removeObsoletePreviews(widgets, packageUser);
+ public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
+ dataModel.widgetsModel.update(app, packageUser);
+ bindUpdatedWidgets(dataModel);
}
});
}
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index be93be4dc..d9c5143f2 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -91,11 +91,21 @@ public class BgDataModel {
public final Map<ShortcutKey, MutableInt> pinnedShortcutCounts = new HashMap<>();
/**
+ * True if the launcher has permission to access deep shortcuts.
+ */
+ public boolean hasShortcutHostPermission;
+
+ /**
* Maps all launcher activities to the id's of their shortcuts (if they have any).
*/
public final MultiHashMap<ComponentKey, String> deepShortcutMap = new MultiHashMap<>();
/**
+ * Entire list of widgets.
+ */
+ public final WidgetsModel widgetsModel = new WidgetsModel();
+
+ /**
* Clears all the data
*/
public synchronized void clear() {
diff --git a/src/com/android/launcher3/model/ExtendedModelTask.java b/src/com/android/launcher3/model/ExtendedModelTask.java
index 05419662b..080aaf54b 100644
--- a/src/com/android/launcher3/model/ExtendedModelTask.java
+++ b/src/com/android/launcher3/model/ExtendedModelTask.java
@@ -59,4 +59,15 @@ public abstract class ExtendedModelTask extends BaseModelUpdateTask {
}
});
}
+
+ public void bindUpdatedWidgets(BgDataModel dataModel) {
+ final MultiHashMap<PackageItemInfo, WidgetItem> widgets
+ = dataModel.widgetsModel.getWidgetsMap();
+ scheduleCallbackTask(new CallbackTask() {
+ @Override
+ public void execute(Callbacks callbacks) {
+ callbacks.bindAllWidgets(widgets);
+ }
+ });
+ }
}
diff --git a/src/com/android/launcher3/model/LoaderResults.java b/src/com/android/launcher3/model/LoaderResults.java
index 61fd356b8..28df64d39 100644
--- a/src/com/android/launcher3/model/LoaderResults.java
+++ b/src/com/android/launcher3/model/LoaderResults.java
@@ -24,6 +24,7 @@ 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;
import com.android.launcher3.LauncherModel.Callbacks;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.MainThreadExecutor;
@@ -58,6 +59,7 @@ public class LoaderResults {
private final BgDataModel mBgDataModel;
private final AllAppsList mBgAllAppsList;
private final int mPageToBindFirst;
+
private final WeakReference<Callbacks> mCallbacks;
public LoaderResults(LauncherAppState app, BgDataModel dataModel,
@@ -358,7 +360,6 @@ public class LoaderResults {
mUiExecutor.execute(r);
}
-
public void bindAllApps() {
// shallow copy
@SuppressWarnings("unchecked")
@@ -374,4 +375,18 @@ public class LoaderResults {
};
mUiExecutor.execute(r);
}
+
+ public void bindWidgets() {
+ final MultiHashMap<PackageItemInfo, WidgetItem> widgets
+ = mBgDataModel.widgetsModel.getWidgetsMap();
+ Runnable r = new Runnable() {
+ public void run() {
+ Callbacks callbacks = mCallbacks.get();
+ if (callbacks != null) {
+ callbacks.bindAllWidgets(widgets);
+ }
+ }
+ };
+ mUiExecutor.execute(r);
+ }
}
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 8380f0136..46fea218f 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -44,6 +44,7 @@ import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.util.FlagOp;
import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.MultiHashMap;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
@@ -373,11 +374,9 @@ public class PackageUpdatedTask extends ExtendedModelTask {
} else if (Utilities.isAtLeastO() && mOp == OP_ADD) {
// Load widgets for the new package.
for (int i = 0; i < N; i++) {
- LauncherModel model = app.getModel();
- model.refreshAndBindWidgetsAndShortcuts(
- model.getCallback(), false /* bindFirst */,
- new PackageUserKey(packages[i], mUser) /* packageUser */);
+ dataModel.widgetsModel.update(app, new PackageUserKey(packages[i], mUser));
}
+ bindUpdatedWidgets(dataModel);
}
}
}
diff --git a/src/com/android/launcher3/model/SdCardAvailableReceiver.java b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
index bae5c73c1..3aedae69a 100644
--- a/src/com/android/launcher3/model/SdCardAvailableReceiver.java
+++ b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.util.MultiHashMap;
@@ -43,10 +44,10 @@ public class SdCardAvailableReceiver extends BroadcastReceiver {
private final Context mContext;
private final MultiHashMap<UserHandle, String> mPackages;
- public SdCardAvailableReceiver(LauncherModel model, Context context,
+ public SdCardAvailableReceiver(LauncherAppState app,
MultiHashMap<UserHandle, String> packages) {
- mModel = model;
- mContext = context;
+ mModel = app.getModel();
+ mContext = app.getContext();
mPackages = packages;
}
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index 827675a83..ed900bf35 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -38,36 +38,26 @@ public class WidgetsModel {
private static final boolean DEBUG = false;
/* Map of widgets and shortcuts that are tracked per package. */
- private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList;
+ private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList = new MultiHashMap<>();
- private final IconCache mIconCache;
- private final AppFilter mAppFilter;
+ private AppFilter mAppFilter;
- public WidgetsModel(IconCache iconCache, AppFilter appFilter) {
- mIconCache = iconCache;
- mAppFilter = appFilter;
- mWidgetsList = new MultiHashMap<>();
- }
-
- public MultiHashMap<PackageItemInfo, WidgetItem> getWidgetsMap() {
- return mWidgetsList;
- }
-
- public boolean isEmpty() {
- return mWidgetsList.isEmpty();
+ public synchronized MultiHashMap<PackageItemInfo, WidgetItem> getWidgetsMap() {
+ return mWidgetsList.clone();
}
/**
* @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
* only widgets and shortcuts associated with the package/user are.
*/
- public ArrayList<WidgetItem> update(Context context, @Nullable PackageUserKey packageUser) {
+ public void update(LauncherAppState app, @Nullable PackageUserKey packageUser) {
Preconditions.assertWorkerThread();
+ Context context = app.getContext();
final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
try {
PackageManager pm = context.getPackageManager();
- InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
+ InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
// Widgets
AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(context);
@@ -81,7 +71,7 @@ public class WidgetsModel {
.getCustomShortcutActivityList(packageUser)) {
widgetsAndShortcuts.add(new WidgetItem(info));
}
- setWidgetsAndShortcuts(widgetsAndShortcuts, context, packageUser);
+ setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser);
} catch (Exception e) {
if (!FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isBinderSizeError(e)) {
// the returned value may be incomplete and will not be refreshed until the next
@@ -92,11 +82,12 @@ public class WidgetsModel {
throw e;
}
}
- return widgetsAndShortcuts;
+
+ app.getWidgetCache().removeObsoletePreviews(widgetsAndShortcuts, packageUser);
}
- private void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
- Context context, @Nullable PackageUserKey packageUser) {
+ private synchronized void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
+ LauncherAppState app, @Nullable PackageUserKey packageUser) {
if (DEBUG) {
Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
}
@@ -133,7 +124,7 @@ public class WidgetsModel {
}
}
- InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
+ InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
UserHandle myUser = Process.myUserHandle();
// add and update.
@@ -152,6 +143,9 @@ public class WidgetsModel {
}
}
+ if (mAppFilter == null) {
+ mAppFilter = AppFilter.newInstance(app.getContext());
+ }
if (!mAppFilter.shouldShowApp(item.componentName)) {
if (DEBUG) {
Log.d(TAG, String.format("%s is filtered and not added to the widget tray.",
@@ -174,8 +168,9 @@ public class WidgetsModel {
}
// Update each package entry
+ IconCache iconCache = app.getIconCache();
for (PackageItemInfo p : tmpPackageItemInfos.values()) {
- mIconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
+ iconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
}
}
} \ No newline at end of file