Merge "Updating ItemInfo objects in the worker thread" into ub-now-queens

This commit is contained in:
Sunny Goyal
2014-10-21 18:30:20 +00:00
committed by Android (Google) Code Review
5 changed files with 188 additions and 270 deletions
+11 -6
View File
@@ -26,10 +26,16 @@ import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.*;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.inputmethod.InputMethodManager;
import java.util.ArrayList;
import java.util.HashSet;
/**
* Class for initiating a drag within a view or across multiple views.
@@ -318,18 +324,17 @@ public class DragController {
}
endDrag();
}
public void onAppsRemoved(final ArrayList<String> packageNames, ArrayList<AppInfo> appInfos) {
public void onAppsRemoved(final ArrayList<String> packageNames, HashSet<ComponentName> cns) {
// Cancel the current drag if we are removing an app that we are dragging
if (mDragObject != null) {
Object rawDragInfo = mDragObject.dragInfo;
if (rawDragInfo instanceof ShortcutInfo) {
ShortcutInfo dragInfo = (ShortcutInfo) rawDragInfo;
for (AppInfo info : appInfos) {
for (ComponentName componentName : cns) {
// Added null checks to prevent NPE we've seen in the wild
if (dragInfo != null &&
dragInfo.intent != null && info != null) {
if (dragInfo != null && dragInfo.intent != null) {
ComponentName cn = dragInfo.intent.getComponent();
boolean isSameComponent = cn != null && (cn.equals(info.componentName) ||
boolean isSameComponent = cn != null && (cn.equals(componentName) ||
packageNames.contains(cn.getPackageName()));
if (isSameComponent) {
cancelDrag();
+39 -14
View File
@@ -125,6 +125,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@@ -2063,7 +2064,6 @@ public class Launcher extends Activity
mWorkspace = null;
mDragController = null;
PackageInstallerCompat.getInstance(this).onStop();
LauncherAnimUtils.onDestroyActivity();
if (mLauncherCallbacks != null) {
@@ -4858,33 +4858,54 @@ public class Launcher extends Activity
return;
}
if (mWorkspace != null) {
mWorkspace.updateShortcutsAndWidgets(apps);
}
if (!LauncherAppState.isDisableAllApps() &&
mAppsCustomizeContent != null) {
mAppsCustomizeContent.updateApps(apps);
}
}
@Override
public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {
Runnable r = new Runnable() {
public void run() {
bindWidgetsRestored(widgets);
}
};
if (waitUntilResume(r)) {
return;
}
mWorkspace.widgetsRestored(widgets);
}
/**
* Some shortcuts were updated in the background.
*
* Implementation of the method from LauncherModel.Callbacks.
*/
public void bindShortcutsUpdated(final ArrayList<ShortcutInfo> shortcuts) {
@Override
public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,
final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {
Runnable r = new Runnable() {
public void run() {
bindShortcutsUpdated(shortcuts);
bindShortcutsChanged(updated, removed, user);
}
};
if (waitUntilResume(r)) {
return;
}
if (mWorkspace != null) {
mWorkspace.updateShortcuts(shortcuts);
if (!updated.isEmpty()) {
mWorkspace.updateShortcuts(updated);
}
if (!removed.isEmpty()) {
HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();
for (ShortcutInfo si : removed) {
removedComponents.add(si.getTargetComponent());
}
mWorkspace.removeItemsByComponentName(removedComponents, user);
// Notify the drag controller
mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);
}
}
@@ -4935,19 +4956,23 @@ public class Launcher extends Activity
}
if (reason == 0) {
HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();
for (AppInfo info : appInfos) {
removedComponents.add(info.componentName);
}
if (!packageNames.isEmpty()) {
mWorkspace.removeItemsByPackageName(packageNames, user);
}
if (!appInfos.isEmpty()) {
mWorkspace.removeItemsByApplicationInfo(appInfos, user);
if (!removedComponents.isEmpty()) {
mWorkspace.removeItemsByComponentName(removedComponents, user);
}
// Notify the drag controller
mDragController.onAppsRemoved(packageNames, removedComponents);
} else {
mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);
}
// Notify the drag controller
mDragController.onAppsRemoved(packageNames, appInfos);
// Update AllApps
if (!LauncherAppState.isDisableAllApps() &&
mAppsCustomizeContent != null) {
@@ -29,6 +29,7 @@ import android.os.Handler;
import android.util.Log;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.PackageInstallerCompat;
import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import java.lang.ref.WeakReference;
@@ -134,6 +135,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
sContext.unregisterReceiver(mModel);
final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
launcherApps.removeOnAppsChangedCallback(mModel);
PackageInstallerCompat.getInstance(sContext).onStop();
ContentResolver resolver = sContext.getContentResolver();
resolver.unregisterContentObserver(mFavoritesObserver);
+114 -79
View File
@@ -198,7 +198,9 @@ public class LauncherModel extends BroadcastReceiver
ArrayList<ItemInfo> addAnimated,
ArrayList<AppInfo> addedApps);
public void bindAppsUpdated(ArrayList<AppInfo> apps);
public void bindShortcutsUpdated(ArrayList<ShortcutInfo> shortcuts);
public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated,
ArrayList<ShortcutInfo> removed, UserHandleCompat user);
public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
public void updatePackageState(ArrayList<PackageInstallInfo> installInfo);
public void updatePackageBadge(String packageName);
public void bindComponentsRemoved(ArrayList<String> packageNames,
@@ -373,15 +375,6 @@ public class LauncherModel extends BroadcastReceiver
return;
}
final ArrayList<AppInfo> restoredAppsFinal = new ArrayList<AppInfo>();
Iterator<AppInfo> iter = allAppsApps.iterator();
while (iter.hasNext()) {
ItemInfo a = iter.next();
if (LauncherModel.appWasPromise(ctx, a.getIntent(), a.user)) {
restoredAppsFinal.add((AppInfo) a);
}
}
// Process the newly added applications and add them to the database first
Runnable r = new Runnable() {
public void run() {
@@ -389,16 +382,6 @@ public class LauncherModel extends BroadcastReceiver
public void run() {
Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
if (callbacks == cb && cb != null) {
if (!restoredAppsFinal.isEmpty()) {
for (AppInfo info : restoredAppsFinal) {
final Intent intent = info.getIntent();
if (intent != null) {
mIconCache.deletePreloadedIcon(intent.getComponent(),
info.user);
}
}
callbacks.bindAppsUpdated(restoredAppsFinal);
}
callbacks.bindAppsAdded(null, null, null, allAppsApps);
}
}
@@ -423,7 +406,6 @@ public class LauncherModel extends BroadcastReceiver
public void run() {
final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>();
final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
final ArrayList<AppInfo> restoredAppsFinal = new ArrayList<AppInfo>();
// Get the list of workspace screens. We need to append to this list and
// can not use sBgWorkspaceScreens because loadWorkspace() may not have been
@@ -443,12 +425,7 @@ public class LauncherModel extends BroadcastReceiver
final Intent launchIntent = a.getIntent();
// Short-circuit this logic if the icon exists somewhere on the workspace
if (LauncherModel.shortcutExists(context, name, launchIntent)) {
// Only InstallShortcutReceiver sends us shortcutInfos, ignore them
if (a instanceof AppInfo &&
LauncherModel.appWasPromise(context, launchIntent, a.user)) {
restoredAppsFinal.add((AppInfo) a);
}
if (shortcutExists(context, name, launchIntent)) {
continue;
}
@@ -524,9 +501,6 @@ public class LauncherModel extends BroadcastReceiver
}
callbacks.bindAppsAdded(addedWorkspaceScreensFinal,
addNotAnimated, addAnimated, null);
if (!restoredAppsFinal.isEmpty()) {
callbacks.bindAppsUpdated(restoredAppsFinal);
}
}
}
});
@@ -901,17 +875,6 @@ public class LauncherModel extends BroadcastReceiver
return result;
}
/**
* Returns true if the promise shortcuts with the same package name exists on the workspace.
*/
static boolean appWasPromise(Context context, Intent intent, UserHandleCompat user) {
final ComponentName component = intent.getComponent();
if (component == null) {
return false;
}
return !getItemsByPackageName(component.getPackageName(), user).isEmpty();
}
/**
* Returns an ItemInfo array containing all the items in the LauncherModel.
* The ItemInfo.id is not set through this function.
@@ -1111,7 +1074,7 @@ public class LauncherModel extends BroadcastReceiver
* @param context
* @param item
*/
static void deleteItemsFromDatabase(Context context, final ArrayList<ItemInfo> items) {
static void deleteItemsFromDatabase(Context context, final ArrayList<? extends ItemInfo> items) {
final ContentResolver cr = context.getContentResolver();
Runnable r = new Runnable() {
@@ -3048,6 +3011,9 @@ public class LauncherModel extends BroadcastReceiver
return;
}
final HashMap<ComponentName, AppInfo> addedOrUpdatedApps =
new HashMap<ComponentName, AppInfo>();
if (added != null) {
// Ensure that we add all the workspace applications to the db
if (LauncherAppState.isDisableAllApps()) {
@@ -3056,23 +3022,15 @@ public class LauncherModel extends BroadcastReceiver
} else {
addAppsToAllApps(context, added);
}
for (AppInfo ai : added) {
addedOrUpdatedApps.put(ai.componentName, ai);
}
}
if (modified != null) {
final ArrayList<AppInfo> modifiedFinal = modified;
// Update the launcher db to reflect the changes
for (AppInfo a : modifiedFinal) {
ArrayList<ItemInfo> infos =
getItemInfoForComponentName(a.componentName, mUser);
for (ItemInfo i : infos) {
if (i instanceof ShortcutInfo && isShortcutAppTarget((ShortcutInfo) i)) {
ShortcutInfo info = (ShortcutInfo) i;
info.title = a.title.toString();
info.contentDescription = a.contentDescription;
updateItemInDatabase(context, info);
}
}
for (AppInfo ai : modified) {
addedOrUpdatedApps.put(ai.componentName, ai);
}
mHandler.post(new Runnable() {
@@ -3085,37 +3043,128 @@ public class LauncherModel extends BroadcastReceiver
});
}
// Update shortcuts which use an iconResource
// Update shortcut infos
if (mOp == OP_ADD || mOp == OP_UPDATE) {
final ArrayList<ShortcutInfo> iconsChanged = new ArrayList<ShortcutInfo>();
final ArrayList<ShortcutInfo> updatedShortcuts = new ArrayList<ShortcutInfo>();
final ArrayList<ShortcutInfo> removedShortcuts = new ArrayList<ShortcutInfo>();
final ArrayList<LauncherAppWidgetInfo> widgets = new ArrayList<LauncherAppWidgetInfo>();
HashSet<String> packageSet = new HashSet<String>(Arrays.asList(packages));
// We need to iterate over the items here, so that we can avoid new Bitmap
// creation on the UI thread.
synchronized (sBgLock) {
for (ItemInfo info : sBgWorkspaceItems) {
for (ItemInfo info : sBgItemsIdMap.values()) {
if (info instanceof ShortcutInfo && mUser.equals(info.user)) {
ShortcutInfo si = (ShortcutInfo) info;
boolean infoUpdated = false;
boolean shortcutUpdated = false;
// Update shortcuts which use iconResource.
if ((si.iconResource != null)
&& packageSet.contains(si.getTargetComponent().getPackageName())){
&& packageSet.contains(si.iconResource.packageName)) {
Bitmap icon = Utilities.createIconBitmap(si.iconResource.packageName,
si.iconResource.resourceName, mIconCache, context);
if (icon != null) {
si.setIcon(icon);
si.usingFallbackIcon = false;
iconsChanged.add(si);
updateItemInDatabase(context, si);
infoUpdated = true;
}
}
ComponentName cn = si.getTargetComponent();
if (cn != null && packageSet.contains(cn.getPackageName())) {
AppInfo appInfo = addedOrUpdatedApps.get(cn);
if (si.isPromise()) {
mIconCache.deletePreloadedIcon(cn, mUser);
if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
// Auto install icon
PackageManager pm = context.getPackageManager();
ResolveInfo matched = pm.resolveActivity(
new Intent(Intent.ACTION_MAIN)
.setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
PackageManager.MATCH_DEFAULT_ONLY);
if (matched == null) {
// Try to find the best match activity.
Intent intent = pm.getLaunchIntentForPackage(
cn.getPackageName());
if (intent != null) {
cn = intent.getComponent();
appInfo = addedOrUpdatedApps.get(cn);
}
if ((intent == null) || (appInfo == null)) {
removedShortcuts.add(si);
continue;
}
si.promisedIntent = intent;
}
}
// Restore the shortcut.
si.intent = si.promisedIntent;
si.promisedIntent = null;
si.status &= ~ShortcutInfo.FLAG_RESTORED_ICON
& ~ShortcutInfo.FLAG_AUTOINTALL_ICON
& ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
infoUpdated = true;
si.updateIcon(mIconCache);
}
if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction())
&& si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
si.updateIcon(mIconCache);
si.title = appInfo.title.toString();
si.contentDescription = appInfo.contentDescription;
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;
shortcutUpdated = true;
}
}
if (infoUpdated || shortcutUpdated) {
updatedShortcuts.add(si);
}
if (infoUpdated) {
updateItemInDatabase(context, si);
}
} else if (info instanceof LauncherAppWidgetInfo) {
LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info;
if (mUser.equals(widgetInfo.user)
&& widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
&& packageSet.contains(widgetInfo.providerName.getPackageName())) {
widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
widgets.add(widgetInfo);
updateItemInDatabase(context, widgetInfo);
}
}
}
}
if (!iconsChanged.isEmpty()) {
if (!updatedShortcuts.isEmpty() || !removedShortcuts.isEmpty()) {
mHandler.post(new Runnable() {
public void run() {
Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
if (callbacks == cb && cb != null) {
callbacks.bindShortcutsChanged(
updatedShortcuts, removedShortcuts, mUser);
}
}
});
if (!removedShortcuts.isEmpty()) {
deleteItemsFromDatabase(context, removedShortcuts);
}
}
if (!widgets.isEmpty()) {
mHandler.post(new Runnable() {
public void run() {
Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
if (callbacks == cb && cb != null) {
callbacks.bindShortcutsUpdated(iconsChanged);
callbacks.bindWidgetsRestored(widgets);
}
}
});
@@ -3414,20 +3463,6 @@ public class LauncherModel extends BroadcastReceiver
return filterItemInfos(sBgItemsIdMap.values(), filter);
}
/**
* @return true if the ShortcutInfo points to an app shortcut target, i.e. it has been added by
* dragging from AllApps list.
*/
public static boolean isShortcutAppTarget(ShortcutInfo info) {
// We need to check for ACTION_MAIN otherwise getComponent() might
// return null for some shortcuts (for instance, for shortcuts to
// web pages.)
Intent intent = info.promisedIntent != null ? info.promisedIntent : info.intent;
ComponentName name = intent.getComponent();
return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
Intent.ACTION_MAIN.equals(intent.getAction()) && name != null;
}
/**
* Make an ShortcutInfo object for a shortcut that isn't an application.
*/
+22 -171
View File
@@ -4693,20 +4693,11 @@ public class Workspace extends SmoothPagedView
removeItemsByComponentName(cns, user);
}
// Removes items that match the application info specified, when applications are removed
// as a part of an update, this is called to ensure that other widgets and application
// shortcuts are not removed.
void removeItemsByApplicationInfo(final ArrayList<AppInfo> appInfos, UserHandleCompat user) {
// Just create a hash table of all the specific components that this will affect
HashSet<ComponentName> cns = new HashSet<ComponentName>();
for (AppInfo info : appInfos) {
cns.add(info.componentName);
}
// Remove all the things
removeItemsByComponentName(cns, user);
}
/**
* Removes items that match the item info specified. When applications are removed
* as a part of an update, this is called to ensure that other widgets and application
* shortcuts are not removed.
*/
void removeItemsByComponentName(final HashSet<ComponentName> componentNames,
final UserHandleCompat user) {
ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts();
@@ -4827,7 +4818,6 @@ public class Workspace extends SmoothPagedView
}
}
void updateShortcuts(ArrayList<ShortcutInfo> shortcuts) {
final HashSet<ShortcutInfo> updates = new HashSet<ShortcutInfo>(shortcuts);
mapOverItems(MAP_RECURSE, new ItemOperator() {
@@ -4835,9 +4825,12 @@ public class Workspace extends SmoothPagedView
public boolean evaluate(ItemInfo info, View v, View parent) {
if (info instanceof ShortcutInfo && v instanceof BubbleTextView &&
updates.contains(info)) {
ShortcutInfo shortcutInfo = (ShortcutInfo) info;
ShortcutInfo si = (ShortcutInfo) info;
BubbleTextView shortcut = (BubbleTextView) v;
shortcut.applyFromShortcutInfo(shortcutInfo, mIconCache, true, false);
boolean oldPromiseState = shortcut.getCompoundDrawables()[1]
instanceof PreloadIconDrawable;
shortcut.applyFromShortcutInfo(si, mIconCache, true,
si.isPromise() != oldPromiseState);
if (parent != null) {
parent.invalidate();
@@ -4849,125 +4842,6 @@ public class Workspace extends SmoothPagedView
});
}
void updateShortcutsAndWidgets(ArrayList<AppInfo> apps) {
// Break the appinfo list per user
final HashMap<UserHandleCompat, ArrayList<AppInfo>> appsPerUser =
new HashMap<UserHandleCompat, ArrayList<AppInfo>>();
for (AppInfo info : apps) {
ArrayList<AppInfo> filtered = appsPerUser.get(info.user);
if (filtered == null) {
filtered = new ArrayList<AppInfo>();
appsPerUser.put(info.user, filtered);
}
filtered.add(info);
}
for (Map.Entry<UserHandleCompat, ArrayList<AppInfo>> entry : appsPerUser.entrySet()) {
updateShortcutsAndWidgetsPerUser(entry.getValue(), entry.getKey());
}
}
private void updateShortcutsAndWidgetsPerUser(ArrayList<AppInfo> apps,
final UserHandleCompat user) {
// Create a map of the apps to test against
final HashMap<ComponentName, AppInfo> appsMap = new HashMap<ComponentName, AppInfo>();
final HashSet<String> pkgNames = new HashSet<String>();
for (AppInfo ai : apps) {
appsMap.put(ai.componentName, ai);
pkgNames.add(ai.componentName.getPackageName());
}
final HashSet<ComponentName> iconsToRemove = new HashSet<ComponentName>();
mapOverItems(MAP_RECURSE, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View v, View parent) {
if (info instanceof ShortcutInfo && v instanceof BubbleTextView) {
ShortcutInfo shortcutInfo = (ShortcutInfo) info;
ComponentName cn = shortcutInfo.getTargetComponent();
AppInfo appInfo = appsMap.get(cn);
if (user.equals(shortcutInfo.user) && cn != null
&& pkgNames.contains(cn.getPackageName())) {
boolean promiseStateChanged = false;
boolean infoUpdated = false;
if (shortcutInfo.isPromise()) {
if (shortcutInfo.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
// Auto install icon
PackageManager pm = getContext().getPackageManager();
ResolveInfo matched = pm.resolveActivity(
new Intent(Intent.ACTION_MAIN)
.setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
PackageManager.MATCH_DEFAULT_ONLY);
if (matched == null) {
// Try to find the best match activity.
Intent intent = pm.getLaunchIntentForPackage(
cn.getPackageName());
if (intent != null) {
cn = intent.getComponent();
appInfo = appsMap.get(cn);
}
if ((intent == null) || (appsMap == null)) {
// Could not find a default activity. Remove this item.
iconsToRemove.add(shortcutInfo.getTargetComponent());
// process next shortcut.
return false;
}
shortcutInfo.promisedIntent = intent;
}
}
// Restore the shortcut.
shortcutInfo.intent = shortcutInfo.promisedIntent;
shortcutInfo.promisedIntent = null;
shortcutInfo.status &= ~ShortcutInfo.FLAG_RESTORED_ICON
& ~ShortcutInfo.FLAG_AUTOINTALL_ICON
& ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
promiseStateChanged = true;
infoUpdated = true;
shortcutInfo.updateIcon(mIconCache);
LauncherModel.updateItemInDatabase(getContext(), shortcutInfo);
}
if ((shortcutInfo.isDisabled & ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE) != 0) {
// Since package was just updated, the target must be available now.
shortcutInfo.isDisabled &= ~ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
infoUpdated = true;
}
// Only update the icon and labels if the shortcuts points to an app target
if ((appInfo != null) && LauncherModel.isShortcutAppTarget(shortcutInfo)) {
shortcutInfo.updateIcon(mIconCache);
shortcutInfo.title = appInfo.title.toString();
shortcutInfo.contentDescription = appInfo.contentDescription;
infoUpdated = true;
}
if (infoUpdated) {
BubbleTextView shortcut = (BubbleTextView) v;
shortcut.applyFromShortcutInfo(shortcutInfo,
mIconCache, true, promiseStateChanged);
if (parent != null) {
parent.invalidate();
}
}
}
}
// process all the shortcuts
return false;
}
});
if (!iconsToRemove.isEmpty()) {
removeItemsByComponentName(iconsToRemove, user);
}
if (user.equals(UserHandleCompat.myUserHandle())) {
restorePendingWidgets(pkgNames);
}
}
public void removeAbandonedPromise(String packageName, UserHandleCompat user) {
ArrayList<String> packages = new ArrayList<String>(1);
packages.add(packageName);
@@ -5008,9 +4882,11 @@ public class Workspace extends SmoothPagedView
}
public void updatePackageState(ArrayList<PackageInstallInfo> installInfos) {
HashSet<String> completedPackages = new HashSet<String>();
for (final PackageInstallInfo installInfo : installInfos) {
if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
continue;
}
mapOverItems(MAP_RECURSE, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View v, View parent) {
@@ -5038,42 +4914,10 @@ public class Workspace extends SmoothPagedView
return false;
}
});
if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
completedPackages.add(installInfo.packageName);
}
}
// Note that package states are sent only for myUser
if (!completedPackages.isEmpty()) {
restorePendingWidgets(completedPackages);
}
}
private void restorePendingWidgets(final Set<String> installedPackaged) {
final ArrayList<LauncherAppWidgetInfo> changedInfo = new ArrayList<LauncherAppWidgetInfo>();
// Iterate non recursively as widgets can't be inside a folder.
mapOverItems(MAP_NO_RECURSE, new ItemOperator() {
@Override
public boolean evaluate(ItemInfo info, View v, View parent) {
if (info instanceof LauncherAppWidgetInfo) {
LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info;
if (widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
&& installedPackaged.contains(widgetInfo.providerName.getPackageName())) {
changedInfo.add(widgetInfo);
// Remove the provider not ready flag
widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
LauncherModel.updateItemInDatabase(getContext(), widgetInfo);
}
}
// process all the widget
return false;
}
});
void widgetsRestored(ArrayList<LauncherAppWidgetInfo> changedInfo) {
if (!changedInfo.isEmpty()) {
DeferredWidgetRefresh widgetRefresh = new DeferredWidgetRefresh(changedInfo,
mLauncher.getAppWidgetHost());
@@ -5083,6 +4927,13 @@ public class Workspace extends SmoothPagedView
widgetRefresh.run();
} else {
// widgetRefresh will automatically run when the packages are updated.
// For now just update the progress bars
for (LauncherAppWidgetInfo info : changedInfo) {
if (info.hostView instanceof PendingAppWidgetHostView) {
info.installProgress = 100;
((PendingAppWidgetHostView) info.hostView).applyState();
}
}
}
}
}