Moving LoaderTask to a separate class file
Bug: 34112546
Change-Id: I86d93cfb5d3903bfd3878564cbe8b67b64fd8423
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 265c7e3..48c5c56 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -16,7 +16,6 @@
package com.android.launcher3;
-import android.appwidget.AppWidgetProviderInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProviderOperation;
@@ -24,61 +23,40 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.PackageInstaller;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
-import android.os.SystemClock;
-import android.os.Trace;
import android.os.UserHandle;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
-import android.util.LongSparseArray;
-import android.util.MutableInt;
import android.util.Pair;
-import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dynamicui.ExtractionUtils;
-import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.folder.FolderIconPreviewVerifier;
import com.android.launcher3.graphics.LauncherIcons;
-import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.AddWorkspaceItemsTask;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.CacheDataUpdatedTask;
import com.android.launcher3.model.ExtendedModelTask;
-import com.android.launcher3.model.GridSizeMigrationTask;
-import com.android.launcher3.model.LoaderCursor;
import com.android.launcher3.model.LoaderResults;
+import com.android.launcher3.model.LoaderTask;
import com.android.launcher3.model.ModelWriter;
import com.android.launcher3.model.PackageInstallStateChangedTask;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.model.PackageUpdatedTask;
-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.provider.ImportDataTask;
import com.android.launcher3.provider.LauncherDbUtils;
import com.android.launcher3.shortcuts.DeepShortcutManager;
import com.android.launcher3.shortcuts.ShortcutInfoCompat;
-import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.LooperIdleLock;
-import com.android.launcher3.util.ManagedProfileHeuristic;
import com.android.launcher3.util.MultiHashMap;
-import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Provider;
@@ -89,12 +67,9 @@
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.CancellationException;
import java.util.concurrent.Executor;
@@ -105,7 +80,7 @@
*/
public class LauncherModel extends BroadcastReceiver
implements LauncherAppsCompat.OnAppsChangedCallbackCompat {
- static final boolean DEBUG_LOADERS = false;
+ static final boolean DEBUG_TASKS = false;
private static final boolean DEBUG_RECEIVER = false;
static final String TAG = "Launcher.Model";
@@ -113,7 +88,8 @@
private final MainThreadExecutor mUiExecutor = new MainThreadExecutor();
@Thunk final LauncherAppState mApp;
@Thunk final Object mLock = new Object();
- @Thunk LoaderTask mLoaderTask;
+ @Thunk
+ LoaderTask mLoaderTask;
@Thunk boolean mIsLoaderTaskRunning;
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
@@ -610,761 +586,6 @@
}
/**
- * Runnable for the thread that loads the contents of the launcher:
- * - workspace icons
- * - widgets
- * - all apps icons
- * - deep shortcuts within apps
- */
- 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(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 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.
- 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 synchronized void verifyNotStopped() throws CancellationException {
- if (mStopped) {
- throw new CancellationException("Loader stopped");
- }
- }
-
- public void run() {
- synchronized (this) {
- // Skip fast if we are already stopped.
- if (mStopped) {
- return;
- }
- }
-
- try (LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
- long now = 0;
- if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
- loadWorkspace();
-
- verifyNotStopped();
- if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace");
- mResults.bindWorkspace();
-
- // Take a break
- if (DEBUG_LOADERS) {
- Log.d(TAG, "step 1 completed, wait for idle");
- now = SystemClock.uptimeMillis();
- }
- waitForIdle();
- if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");
- verifyNotStopped();
-
- // second step
- if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps");
- loadAllApps();
-
- if (DEBUG_LOADERS) Log.d(TAG, "step 2.2: Binding all apps");
- verifyNotStopped();
- mResults.bindAllApps();
-
- verifyNotStopped();
- if (DEBUG_LOADERS) Log.d(TAG, "step 2.3: Update icon cache");
- updateIconCache();
-
- // Take a break
- if (DEBUG_LOADERS) {
- Log.d(TAG, "step 2 completed, wait for idle");
- now = SystemClock.uptimeMillis();
- }
- waitForIdle();
- if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");
- verifyNotStopped();
-
- // third step
- if (DEBUG_LOADERS) Log.d(TAG, "step 3.1: loading deep shortcuts");
- loadDeepShortcuts();
-
- verifyNotStopped();
- if (DEBUG_LOADERS) Log.d(TAG, "step 3.2: bind deep shortcuts");
- mResults.bindDeepShortcuts();
-
- // Take a break
- if (DEBUG_LOADERS) Log.d(TAG, "step 3 completed, wait for idle");
- waitForIdle();
- verifyNotStopped();
-
- // fourth step
- if (DEBUG_LOADERS) Log.d(TAG, "step 4.1: loading widgets");
- mBgDataModel.widgetsModel.update(mApp, null);
-
- verifyNotStopped();
- if (DEBUG_LOADERS) Log.d(TAG, "step 4.2: Binding widgets");
- mResults.bindWidgets();
-
- transaction.commit();
- } catch (CancellationException e) {
- // Loader stopped, ignore
- }
- }
-
- public synchronized void stopLocked() {
- mStopped = true;
- this.notify();
- }
-
- private void loadWorkspace() {
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.beginSection("Loading Workspace");
- }
-
- final Context context = mApp.getContext();
- final ContentResolver contentResolver = context.getContentResolver();
- final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
- final boolean isSafeMode = pmHelper.isSafeMode();
- final boolean isSdCardReady = Utilities.isBootCompleted();
- final MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>();
-
- boolean clearDb = false;
- try {
- ImportDataTask.performImportIfPossible(context);
- } catch (Exception e) {
- // Migration failed. Clear workspace.
- clearDb = true;
- }
-
- if (!clearDb && GridSizeMigrationTask.ENABLED &&
- !GridSizeMigrationTask.migrateGridIfNeeded(context)) {
- // Migration failed. Clear workspace.
- clearDb = true;
- }
-
- if (clearDb) {
- Log.d(TAG, "loadWorkspace: resetting launcher database");
- LauncherSettings.Settings.call(contentResolver,
- LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
- }
-
- Log.d(TAG, "loadWorkspace: loading default favorites");
- LauncherSettings.Settings.call(contentResolver,
- LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES);
-
- synchronized (mBgDataModel) {
- mBgDataModel.clear();
-
- 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(
- LauncherSettings.Favorites.CONTENT_URI, null, null, null, null), mApp);
-
- HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
-
- try {
- final int appWidgetIdIndex = c.getColumnIndexOrThrow(
- LauncherSettings.Favorites.APPWIDGET_ID);
- final int appWidgetProviderIndex = c.getColumnIndexOrThrow(
- LauncherSettings.Favorites.APPWIDGET_PROVIDER);
- final int spanXIndex = c.getColumnIndexOrThrow
- (LauncherSettings.Favorites.SPANX);
- final int spanYIndex = c.getColumnIndexOrThrow(
- LauncherSettings.Favorites.SPANY);
- final int rankIndex = c.getColumnIndexOrThrow(
- LauncherSettings.Favorites.RANK);
- final int optionsIndex = c.getColumnIndexOrThrow(
- LauncherSettings.Favorites.OPTIONS);
-
- final LongSparseArray<UserHandle> allUsers = c.allUsers;
- final LongSparseArray<Boolean> quietMode = new LongSparseArray<>();
- final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>();
- for (UserHandle user : mUserManager.getUserProfiles()) {
- long serialNo = mUserManager.getSerialNumberForUser(user);
- allUsers.put(serialNo, user);
- quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user));
-
- boolean userUnlocked = mUserManager.isUserUnlocked(user);
-
- // We can only query for shortcuts when the user is unlocked.
- if (userUnlocked) {
- List<ShortcutInfoCompat> pinnedShortcuts =
- mShortcutManager.queryForPinnedShortcuts(null, user);
- if (mShortcutManager.wasLastCallSuccess()) {
- for (ShortcutInfoCompat shortcut : pinnedShortcuts) {
- shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
- shortcut);
- }
- } else {
- // Shortcut manager can fail due to some race condition when the
- // lock state changes too frequently. For the purpose of the loading
- // shortcuts, consider the user is still locked.
- userUnlocked = false;
- }
- }
- unlockedUsers.put(serialNo, userUnlocked);
- }
-
- ShortcutInfo info;
- LauncherAppWidgetInfo appWidgetInfo;
- Intent intent;
- String targetPkg;
-
- FolderIconPreviewVerifier verifier =
- new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile());
- while (!mStopped && c.moveToNext()) {
- try {
- if (c.user == null) {
- // User has been deleted, remove the item.
- c.markDeleted("User has been deleted");
- continue;
- }
-
- boolean allowMissingTarget = false;
- switch (c.itemType) {
- case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
- case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
- case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- intent = c.parseIntent();
- if (intent == null) {
- c.markDeleted("Invalid or null intent");
- continue;
- }
-
- int disabledState = quietMode.get(c.serialNumber) ?
- ShortcutInfo.FLAG_DISABLED_QUIET_USER : 0;
- ComponentName cn = intent.getComponent();
- targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
-
- if (!Process.myUserHandle().equals(c.user)) {
- if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
- c.markDeleted("Legacy shortcuts are only allowed for default user");
- continue;
- } else if (c.restoreFlag != 0) {
- // Don't restore items for other profiles.
- c.markDeleted("Restore from managed profile not supported");
- continue;
- }
- }
- if (TextUtils.isEmpty(targetPkg) &&
- c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
- c.markDeleted("Only legacy shortcuts can have null package");
- continue;
- }
-
- // If there is no target package, its an implicit intent
- // (legacy shortcut) which is always valid
- boolean validTarget = TextUtils.isEmpty(targetPkg) ||
- 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 (mLauncherApps.isActivityEnabledForProfile(cn, c.user)) {
- // no special handling necessary for this item
- c.markRestored();
- } else {
- if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) {
- // We allow auto install apps to have their intent
- // updated after an install.
- intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
- if (intent != null) {
- c.restoreFlag = 0;
- c.updater().put(
- LauncherSettings.Favorites.INTENT,
- intent.toUri(0)).commit();
- cn = intent.getComponent();
- } else {
- c.markDeleted("Unable to find a launch target");
- continue;
- }
- } else {
- // The app is installed but the component is no
- // longer available.
- c.markDeleted("Invalid component removed: " + cn);
- continue;
- }
- }
- }
- // else if cn == null => can't infer much, leave it
- // else if !validPkg => could be restored icon or missing sd-card
-
- if (!TextUtils.isEmpty(targetPkg) && !validTarget) {
- // Points to a valid app (superset of cn != null) but the apk
- // is not available.
-
- if (c.restoreFlag != 0) {
- // Package is not yet available but might be
- // installed later.
- FileLog.d(TAG, "package not yet restored: " + targetPkg);
-
- if (c.hasRestoreFlag(ShortcutInfo.FLAG_RESTORE_STARTED)) {
- // Restore has started once.
- } else if (installingPkgs.containsKey(targetPkg)) {
- // App restore has started. Update the flag
- c.restoreFlag |= ShortcutInfo.FLAG_RESTORE_STARTED;
- c.updater().commit();
- } else {
- c.markDeleted("Unrestored app removed: " + targetPkg);
- continue;
- }
- } else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) {
- // Package is present but not available.
- disabledState |= ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
- // Add the icon on the workspace anyway.
- allowMissingTarget = true;
- } else if (!isSdCardReady) {
- // SdCard is not ready yet. Package might get available,
- // once it is ready.
- Log.d(TAG, "Missing pkg, will check later: " + targetPkg);
- pendingPackages.addToList(c.user, targetPkg);
- // Add the icon on the workspace anyway.
- allowMissingTarget = true;
- } else {
- // Do not wait for external media load anymore.
- c.markDeleted("Invalid package removed: " + targetPkg);
- continue;
- }
- }
-
- if (validTarget) {
- // The shortcut points to a valid target (either no target
- // or something which is ready to be used)
- c.markRestored();
- }
-
- boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() &&
- !verifier.isItemInPreview(c.getInt(rankIndex));
-
- if (c.restoreFlag != 0) {
- // Already verified above that user is same as default user
- info = c.getRestoredItemInfo(intent);
- } else if (c.itemType ==
- LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
- info = c.getAppShortcutInfo(
- intent, allowMissingTarget, useLowResIcon);
- } else if (c.itemType ==
- LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
-
- ShortcutKey key = ShortcutKey.fromIntent(intent, c.user);
- if (unlockedUsers.get(c.serialNumber)) {
- ShortcutInfoCompat pinnedShortcut =
- shortcutKeyToPinnedShortcuts.get(key);
- if (pinnedShortcut == null) {
- // The shortcut is no longer valid.
- c.markDeleted("Pinned shortcut not found");
- continue;
- }
- info = new ShortcutInfo(pinnedShortcut, context);
- info.iconBitmap = LauncherIcons
- .createShortcutIcon(pinnedShortcut, context);
- if (pmHelper.isAppSuspended(
- pinnedShortcut.getPackage(), info.user)) {
- info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
- }
- intent = info.intent;
- } else {
- // Create a shortcut info in disabled mode for now.
- info = c.loadSimpleShortcut();
- info.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER;
- }
- } else { // item type == ITEM_TYPE_SHORTCUT
- info = c.loadSimpleShortcut();
-
- // Shortcuts are only available on the primary profile
- if (!TextUtils.isEmpty(targetPkg)
- && pmHelper.isAppSuspended(targetPkg, c.user)) {
- disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
- }
-
- // App shortcuts that used to be automatically added to Launcher
- // didn't always have the correct intent flags set, so do that
- // here
- if (intent.getAction() != null &&
- intent.getCategories() != null &&
- intent.getAction().equals(Intent.ACTION_MAIN) &&
- intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
- intent.addFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- }
- }
-
- if (info != null) {
- c.applyCommonProperties(info);
-
- info.intent = intent;
- info.rank = c.getInt(rankIndex);
- info.spanX = 1;
- info.spanY = 1;
- info.isDisabled |= disabledState;
- if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
- info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
- }
-
- if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
- Integer progress = installingPkgs.get(targetPkg);
- if (progress != null) {
- info.setInstallProgress(progress);
- } else {
- info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
- }
- }
-
- c.checkAndAddItem(info, mBgDataModel);
- } else {
- throw new RuntimeException("Unexpected null ShortcutInfo");
- }
- break;
-
- case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
- FolderInfo folderInfo = mBgDataModel.findOrMakeFolder(c.id);
- c.applyCommonProperties(folderInfo);
-
- // Do not trim the folder label, as is was set by the user.
- folderInfo.title = c.getString(c.titleIndex);
- folderInfo.spanX = 1;
- folderInfo.spanY = 1;
- folderInfo.options = c.getInt(optionsIndex);
-
- // no special handling required for restored folders
- c.markRestored();
-
- c.checkAndAddItem(folderInfo, mBgDataModel);
- break;
-
- case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
- case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
- // Read all Launcher-specific widget details
- boolean customWidget = c.itemType ==
- LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
-
- int appWidgetId = c.getInt(appWidgetIdIndex);
- String savedProvider = c.getString(appWidgetProviderIndex);
-
- final ComponentName component =
- ComponentName.unflattenFromString(savedProvider);
-
- final boolean isIdValid = !c.hasRestoreFlag(
- LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
- final boolean wasProviderReady = !c.hasRestoreFlag(
- LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
-
- if (widgetProvidersMap == null) {
- widgetProvidersMap = mAppWidgetManager.getAllProvidersMap();
- }
- final AppWidgetProviderInfo provider = widgetProvidersMap.get(
- new ComponentKey(
- ComponentName.unflattenFromString(savedProvider),
- c.user));
-
- final boolean isProviderReady = isValidProvider(provider);
- if (!isSafeMode && !customWidget &&
- wasProviderReady && !isProviderReady) {
- c.markDeleted(
- "Deleting widget that isn't installed anymore: "
- + provider);
- } else {
- if (isProviderReady) {
- appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
- provider.provider);
-
- // The provider is available. So the widget is either
- // available or not available. We do not need to track
- // any future restore updates.
- int status = c.restoreFlag &
- ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
- if (!wasProviderReady) {
- // If provider was not previously ready, update the
- // status and UI flag.
-
- // Id would be valid only if the widget restore broadcast was received.
- if (isIdValid) {
- status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
- } else {
- status &= ~LauncherAppWidgetInfo
- .FLAG_PROVIDER_NOT_READY;
- }
- }
- appWidgetInfo.restoreStatus = status;
- } else {
- Log.v(TAG, "Widget restore pending id=" + c.id
- + " appWidgetId=" + appWidgetId
- + " status =" + c.restoreFlag);
- appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
- component);
- appWidgetInfo.restoreStatus = c.restoreFlag;
- Integer installProgress = installingPkgs.get(component.getPackageName());
-
- if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) {
- // Restore has started once.
- } else if (installProgress != null) {
- // App restore has started. Update the flag
- appWidgetInfo.restoreStatus |=
- LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
- } else if (!isSafeMode) {
- c.markDeleted("Unrestored widget removed: " + component);
- continue;
- }
-
- appWidgetInfo.installProgress =
- installProgress == null ? 0 : installProgress;
- }
- if (appWidgetInfo.hasRestoreFlag(
- LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
- appWidgetInfo.bindOptions = c.parseIntent();
- }
-
- c.applyCommonProperties(appWidgetInfo);
- appWidgetInfo.spanX = c.getInt(spanXIndex);
- appWidgetInfo.spanY = c.getInt(spanYIndex);
- appWidgetInfo.user = c.user;
-
- if (!c.isOnWorkspaceOrHotseat()) {
- c.markDeleted("Widget found where container != " +
- "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!");
- continue;
- }
-
- if (!customWidget) {
- String providerName =
- appWidgetInfo.providerName.flattenToString();
- if (!providerName.equals(savedProvider) ||
- (appWidgetInfo.restoreStatus != c.restoreFlag)) {
- c.updater()
- .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER,
- providerName)
- .put(LauncherSettings.Favorites.RESTORED,
- appWidgetInfo.restoreStatus)
- .commit();
- }
- }
-
- if (appWidgetInfo.restoreStatus !=
- LauncherAppWidgetInfo.RESTORE_COMPLETED) {
- String pkg = appWidgetInfo.providerName.getPackageName();
- appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg);
- appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user;
- mIconCache.getTitleAndIconForApp(
- appWidgetInfo.pendingItemInfo, false);
- }
-
- c.checkAndAddItem(appWidgetInfo, mBgDataModel);
- }
- break;
- }
- } catch (Exception e) {
- Log.e(TAG, "Desktop items loading interrupted", e);
- }
- }
- } finally {
- Utilities.closeSilently(c);
- }
-
- // Break early if we've stopped loading
- if (mStopped) {
- mBgDataModel.clear();
- return;
- }
-
- // Remove dead items
- if (c.commitDeleted()) {
- // Remove any empty folder
- ArrayList<Long> deletedFolderIds = (ArrayList<Long>) LauncherSettings.Settings
- .call(contentResolver,
- LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS)
- .getSerializable(LauncherSettings.Settings.EXTRA_VALUE);
- for (long folderId : deletedFolderIds) {
- mBgDataModel.workspaceItems.remove(mBgDataModel.folders.get(folderId));
- mBgDataModel.folders.remove(folderId);
- mBgDataModel.itemsIdMap.remove(folderId);
- }
-
- // Remove any ghost widgets
- LauncherSettings.Settings.call(contentResolver,
- LauncherSettings.Settings.METHOD_REMOVE_GHOST_WIDGETS);
- }
-
- // Unpin shortcuts that don't exist on the workspace.
- HashSet<ShortcutKey> pendingShortcuts =
- InstallShortcutReceiver.getPendingShortcuts(context);
- for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) {
- 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.
- 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 : mBgDataModel.folders) {
- Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
- verifier.setFolderInfo(folder);
-
- int numItemsInPreview = 0;
- for (ShortcutInfo info : folder.contents) {
- if (info.usingLowResIcon
- && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
- && verifier.isItemInPreview(info.rank)) {
- mIconCache.getTitleAndIcon(info, false);
- numItemsInPreview++;
- }
-
- if (numItemsInPreview >= FolderIcon.NUM_ITEMS_IN_PREVIEW) {
- break;
- }
- }
- }
-
- c.commitRestoredItems();
- if (!isSdCardReady && !pendingPackages.isEmpty()) {
- context.registerReceiver(
- new SdCardAvailableReceiver(mApp, pendingPackages),
- new IntentFilter(Intent.ACTION_BOOT_COMPLETED),
- null,
- sWorker);
- }
-
- // Remove any empty screens
- 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)) {
- unusedScreens.remove(screenId);
- }
- }
-
- // If there are any empty screens remove them, and update.
- if (unusedScreens.size() != 0) {
- mBgDataModel.workspaceScreens.removeAll(unusedScreens);
- updateWorkspaceScreenOrder(context, mBgDataModel.workspaceScreens);
- }
- }
- if (LauncherAppState.PROFILE_STARTUP) {
- Trace.endSection();
- }
- }
-
- private void updateIconCache() {
- // Ignore packages which have a promise icon.
- HashSet<String> packagesToIgnore = new HashSet<>();
- synchronized (mBgDataModel) {
- for (ItemInfo info : mBgDataModel.itemsIdMap) {
- if (info instanceof ShortcutInfo) {
- ShortcutInfo si = (ShortcutInfo) info;
- if (si.isPromise() && si.getTargetComponent() != null) {
- packagesToIgnore.add(si.getTargetComponent().getPackageName());
- }
- } else if (info instanceof LauncherAppWidgetInfo) {
- LauncherAppWidgetInfo lawi = (LauncherAppWidgetInfo) info;
- if (lawi.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) {
- packagesToIgnore.add(lawi.providerName.getPackageName());
- }
- }
- }
- }
- mIconCache.updateDbIcons(packagesToIgnore);
- }
-
- private void loadAllApps() {
- final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
-
- final List<UserHandle> profiles = mUserManager.getUserProfiles();
-
- // Clear the list of apps
- mBgAllAppsList.clear();
- for (UserHandle user : profiles) {
- // Query for the set of apps
- final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
- final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
- if (DEBUG_LOADERS) {
- Log.d(TAG, "getActivityList took "
- + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user);
- Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user);
- }
- // Fail if we don't have any apps
- // TODO: Fix this. Only fail for the current user.
- if (apps == null || apps.isEmpty()) {
- return;
- }
- boolean quietMode = mUserManager.isQuietModeEnabled(user);
- // Create the ApplicationInfos
- for (int i = 0; i < apps.size(); i++) {
- LauncherActivityInfo app = apps.get(i);
- // This builds the icon bitmaps.
- mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
- }
-
- 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
- for (PackageInstaller.SessionInfo info :
- mPackageInstaller.getAllVerifiedSessions()) {
- mBgAllAppsList.addPromiseApp(mApp.getContext(),
- PackageInstallInfo.fromInstallingState(info));
- }
- }
-
- mBgAllAppsList.added = new ArrayList<>();
- if (DEBUG_LOADERS) {
- Log.d(TAG, "All apps loaded in in "
- + (SystemClock.uptimeMillis() - loadTime) + "ms");
- }
- }
-
- private void loadDeepShortcuts() {
- mBgDataModel.deepShortcutMap.clear();
- mBgDataModel.hasShortcutHostPermission = mShortcutManager.hasHostPermission();
- if (mBgDataModel.hasShortcutHostPermission) {
- for (UserHandle user : mUserManager.getUserProfiles()) {
- if (mUserManager.isUserUnlocked(user)) {
- List<ShortcutInfoCompat> shortcuts =
- mShortcutManager.queryForAllShortcuts(user);
- mBgDataModel.updateDeepShortcutMap(null, user, shortcuts);
- }
- }
- }
- }
- }
-
- /**
* Refreshes the cached shortcuts if the shortcut permission has changed.
* Current implementation simply reloads the workspace, but it can be optimized to
* use partial updates similar to {@link UserManagerCompat}
@@ -1417,7 +638,7 @@
@Override
public final void run() {
if (!mModel.mModelLoaded) {
- if (DEBUG_LOADERS) {
+ if (DEBUG_TASKS) {
Log.d(TAG, "Ignoring model task since loader is pending=" + this);
}
// Loader has not yet run.
@@ -1489,11 +710,6 @@
});
}
- static boolean isValidProvider(AppWidgetProviderInfo provider) {
- return (provider != null) && (provider.provider != null)
- && (provider.provider.getPackageName() != null);
- }
-
public void dumpState(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
if (args.length > 0 && TextUtils.equals(args[0], "--all")) {
writer.println(prefix + "All apps list: size=" + mBgAllAppsList.data.size());