From 3bbbabc54ac73a4451b0a862a3faac6426b1b7b4 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 15 Mar 2016 09:16:30 -0700 Subject: Fixing model being updated on UI thread > When package gets unavailable or suspended, the disabled flag was getting updated on the UI thread. This could lead to inconsistent model if launcher activity didn't exist. > Fixing: When unsuspending one work profile apps, all work profile apps get unsuspended Bug: 27673573,27673373,27403236 Change-Id: I7fde3f79c36204e73ca66ccf8431fa0f0cce3d08 --- src/com/android/launcher3/LauncherModel.java | 112 +++++++++++++++------------ 1 file changed, 62 insertions(+), 50 deletions(-) (limited to 'src/com/android/launcher3/LauncherModel.java') diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index 3877b9496..4c2dec592 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -60,6 +60,7 @@ import com.android.launcher3.model.GridSizeMigrationTask; import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.CursorIconInfo; +import com.android.launcher3.util.FlagOp; import com.android.launcher3.util.LongArrayMap; import com.android.launcher3.util.ManagedProfileHeuristic; import com.android.launcher3.util.Thunk; @@ -195,8 +196,10 @@ public class LauncherModel extends BroadcastReceiver ArrayList removed, UserHandleCompat user); public void bindWidgetsRestored(ArrayList widgets); public void bindRestoreItemsChange(HashSet updates); - public void bindComponentsRemoved(ArrayList packageNames, - ArrayList appInfos, UserHandleCompat user, int reason); + public void bindWorkspaceComponentsRemoved( + HashSet packageNames, HashSet components, + UserHandleCompat user); + public void bindAppInfosRemoved(ArrayList appInfos); public void notifyWidgetProvidersChanged(); public void bindWidgetsModel(WidgetsModel model); public void bindSearchProviderChanged(); @@ -2928,6 +2931,7 @@ public class LauncherModel extends BroadcastReceiver final String[] packages = mPackages; final int N = packages.length; + FlagOp flagOp = FlagOp.NO_OP; switch (mOp) { case OP_ADD: { for (int i=0; i removedApps = new ArrayList(); if (mBgAllAppsList.added.size() > 0) { - added = new ArrayList(mBgAllAppsList.added); + added = new ArrayList<>(mBgAllAppsList.added); mBgAllAppsList.added.clear(); } if (mBgAllAppsList.modified.size() > 0) { - modified = new ArrayList(mBgAllAppsList.modified); + modified = new ArrayList<>(mBgAllAppsList.modified); mBgAllAppsList.modified.clear(); } if (mBgAllAppsList.removed.size() > 0) { @@ -2996,14 +3004,7 @@ public class LauncherModel extends BroadcastReceiver mBgAllAppsList.removed.clear(); } - final Callbacks callbacks = getCallback(); - if (callbacks == null) { - Log.w(TAG, "Nobody to tell about the new app. Launcher is probably loading."); - return; - } - - final HashMap addedOrUpdatedApps = - new HashMap(); + final HashMap addedOrUpdatedApps = new HashMap<>(); if (added != null) { addAppsToAllApps(context, added); @@ -3013,6 +3014,7 @@ public class LauncherModel extends BroadcastReceiver } if (modified != null) { + final Callbacks callbacks = getCallback(); final ArrayList modifiedFinal = modified; for (AppInfo ai : modified) { addedOrUpdatedApps.put(ai.componentName, ai); @@ -3029,7 +3031,7 @@ public class LauncherModel extends BroadcastReceiver } // Update shortcut infos - if (mOp == OP_ADD || mOp == OP_UPDATE || mOp == OP_UNSUSPEND) { + if (mOp == OP_ADD || flagOp != FlagOp.NO_OP) { final ArrayList updatedShortcuts = new ArrayList(); final ArrayList removedShortcuts = new ArrayList(); final ArrayList widgets = new ArrayList(); @@ -3042,11 +3044,6 @@ public class LauncherModel extends BroadcastReceiver boolean infoUpdated = false; boolean shortcutUpdated = false; - if (mOp == OP_UNSUSPEND) { - si.isDisabled &= ~ ShortcutInfo.FLAG_DISABLED_SUSPENDED; - infoUpdated = true; - } - // Update shortcuts which use iconResource. if ((si.iconResource != null) && packageSet.contains(si.iconResource.packageName)) { @@ -3109,9 +3106,9 @@ public class LauncherModel extends BroadcastReceiver infoUpdated = true; } - if ((si.isDisabled & ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE) != 0) { - // Since package was just updated, the target must be available now. - si.isDisabled &= ~ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; + int oldDisabledFlags = si.isDisabled; + si.isDisabled = flagOp.apply(si.isDisabled); + if (si.isDisabled != oldDisabledFlags) { shortcutUpdated = true; } } @@ -3144,6 +3141,7 @@ public class LauncherModel extends BroadcastReceiver } if (!updatedShortcuts.isEmpty() || !removedShortcuts.isEmpty()) { + final Callbacks callbacks = getCallback(); mHandler.post(new Runnable() { public void run() { @@ -3159,6 +3157,7 @@ public class LauncherModel extends BroadcastReceiver } } if (!widgets.isEmpty()) { + final Callbacks callbacks = getCallback(); mHandler.post(new Runnable() { public void run() { Callbacks cb = getCallback(); @@ -3170,48 +3169,60 @@ public class LauncherModel extends BroadcastReceiver } } - final ArrayList removedPackageNames = - new ArrayList(); - if (mOp == OP_REMOVE || mOp == OP_UNAVAILABLE || mOp == OP_SUSPEND) { + final HashSet removedPackages = new HashSet<>(); + final HashSet removedComponents = new HashSet<>(); + if (mOp == OP_REMOVE) { // Mark all packages in the broadcast to be removed - removedPackageNames.addAll(Arrays.asList(packages)); + Collections.addAll(removedPackages, packages); + + // No need to update the removedComponents as + // removedPackages is a super-set of removedComponents } else if (mOp == OP_UPDATE) { // Mark disabled packages in the broadcast to be removed for (int i=0; i infos = getItemInfoForComponentName(a.componentName, mUser); - deleteItemsFromDatabase(context, infos); - } - removeReason = 0; + if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) { + for (String pn : removedPackages) { + deletePackageFromDatabase(context, pn, mUser); + } + for (ComponentName cn : removedComponents) { + deleteItemsFromDatabase(context, getItemInfoForComponentName(cn, mUser)); } // Remove any queued items from the install queue - InstallShortcutReceiver.removeFromInstallQueue(context, removedPackageNames, mUser); + InstallShortcutReceiver.removeFromInstallQueue(context, removedPackages, mUser); + // Call the components-removed callback + final Callbacks callbacks = getCallback(); + mHandler.post(new Runnable() { + public void run() { + Callbacks cb = getCallback(); + if (callbacks == cb && cb != null) { + callbacks.bindWorkspaceComponentsRemoved( + removedPackages, removedComponents, mUser); + } + } + }); + } + + if (!removedApps.isEmpty()) { + // Remove corresponding apps from All-Apps + final Callbacks callbacks = getCallback(); mHandler.post(new Runnable() { public void run() { Callbacks cb = getCallback(); if (callbacks == cb && cb != null) { - callbacks.bindComponentsRemoved( - removedPackageNames, removedApps, mUser, removeReason); + callbacks.bindAppInfosRemoved(removedApps); } } }); @@ -3221,6 +3232,7 @@ public class LauncherModel extends BroadcastReceiver // get widget update signals. if (!Utilities.ATLEAST_MARSHMALLOW && (mOp == OP_ADD || mOp == OP_REMOVE || mOp == OP_UPDATE)) { + final Callbacks callbacks = getCallback(); mHandler.post(new Runnable() { public void run() { Callbacks cb = getCallback(); -- cgit v1.2.3