Merge "Fixing issue where updating the visibility of one application can trigger all icons to disappear. (Bug 8757421)" into jb-mr2-dev

This commit is contained in:
Winson Chung 2013-05-08 18:55:45 +00:00 committed by Android (Google) Code Review
commit 56d796a9b0
7 changed files with 114 additions and 63 deletions

View File

@ -97,12 +97,6 @@ class ApplicationInfo extends ItemInfo {
firstInstallTime = info.firstInstallTime; firstInstallTime = info.firstInstallTime;
} }
/** Returns the package name that the shortcut's intent will resolve to, or an empty string if
* none exists. */
String getPackageName() {
return super.getPackageName(intent);
}
/** /**
* Creates the application intent based on a component name and various launch flags. * Creates the application intent based on a component name and various launch flags.
* Sets {@link #itemType} to {@link LauncherSettings.BaseLauncherColumns#ITEM_TYPE_APPLICATION}. * Sets {@link #itemType} to {@link LauncherSettings.BaseLauncherColumns#ITEM_TYPE_APPLICATION}.

View File

@ -1556,16 +1556,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
} }
return -1; return -1;
} }
private int findAppByPackage(List<ApplicationInfo> list, String packageName) {
int length = list.size();
for (int i = 0; i < length; ++i) {
ApplicationInfo info = list.get(i);
if (ItemInfo.getPackageName(info.intent).equals(packageName)) {
return i;
}
}
return -1;
}
private void removeAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) { private void removeAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
// loop through all the apps and remove apps that have the same component // loop through all the apps and remove apps that have the same component
int length = list.size(); int length = list.size();
@ -1577,18 +1567,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
} }
} }
} }
private void removeAppsWithPackageNameWithoutInvalidate(ArrayList<String> packageNames) { public void removeApps(ArrayList<ApplicationInfo> appInfos) {
// loop through all the package names and remove apps that have the same package name removeAppsWithoutInvalidate(appInfos);
for (String pn : packageNames) {
int removeIndex = findAppByPackage(mApps, pn);
while (removeIndex > -1) {
mApps.remove(removeIndex);
removeIndex = findAppByPackage(mApps, pn);
}
}
}
public void removeApps(ArrayList<String> packageNames) {
removeAppsWithPackageNameWithoutInvalidate(packageNames);
updatePageCounts(); updatePageCounts();
invalidateOnDataChange(); invalidateOnDataChange();
} }

View File

@ -328,18 +328,19 @@ public class DragController {
} }
endDrag(); endDrag();
} }
public void onAppsRemoved(ArrayList<String> packageNames, Context context) { public void onAppsRemoved(ArrayList<ApplicationInfo> appInfos, Context context) {
// Cancel the current drag if we are removing an app that we are dragging // Cancel the current drag if we are removing an app that we are dragging
if (mDragObject != null) { if (mDragObject != null) {
Object rawDragInfo = mDragObject.dragInfo; Object rawDragInfo = mDragObject.dragInfo;
if (rawDragInfo instanceof ShortcutInfo) { if (rawDragInfo instanceof ShortcutInfo) {
ShortcutInfo dragInfo = (ShortcutInfo) rawDragInfo; ShortcutInfo dragInfo = (ShortcutInfo) rawDragInfo;
for (String pn : packageNames) { for (ApplicationInfo info : appInfos) {
// Added null checks to prevent NPE we've seen in the wild // Added null checks to prevent NPE we've seen in the wild
if (dragInfo != null && if (dragInfo != null &&
dragInfo.intent != null) { dragInfo.intent != null) {
boolean isSamePackage = dragInfo.getPackageName().equals(pn); boolean isSameComponent =
if (isSamePackage) { dragInfo.intent.getComponent().equals(info.componentName);
if (isSameComponent) {
cancelDrag(); cancelDrag();
return; return;
} }

View File

@ -3702,27 +3702,51 @@ public final class Launcher extends Activity
} }
/** /**
* A package was uninstalled. * A package was uninstalled. We take both the super set of packageNames
* in addition to specific applications to remove, the reason being that
* this can be called when a package is updated as well. In that scenario,
* we only remove specific components from the workspace, where as
* package-removal should clear all items by package name.
* *
* Implementation of the method from LauncherModel.Callbacks. * Implementation of the method from LauncherModel.Callbacks.
*/ */
public void bindAppsRemoved(ArrayList<String> packageNames, boolean permanent) { public void bindComponentsRemoved(final ArrayList<String> packageNames,
if (permanent) { final ArrayList<ApplicationInfo> appInfos,
mWorkspace.removeItems(packageNames); final boolean matchPackageNamesOnly) {
if (waitUntilResume(new Runnable() {
public void run() {
bindComponentsRemoved(packageNames, appInfos, matchPackageNamesOnly);
}
})) {
return;
}
if (matchPackageNamesOnly) {
mWorkspace.removeItemsByPackageName(packageNames);
} else {
mWorkspace.removeItemsByApplicationInfo(appInfos);
} }
if (mAppsCustomizeContent != null) { if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.removeApps(packageNames); mAppsCustomizeContent.removeApps(appInfos);
} }
// Notify the drag controller // Notify the drag controller
mDragController.onAppsRemoved(packageNames, this); mDragController.onAppsRemoved(appInfos, this);
} }
/** /**
* A number of packages were updated. * A number of packages were updated.
*/ */
public void bindPackagesUpdated() { public void bindPackagesUpdated() {
if (waitUntilResume(new Runnable() {
public void run() {
bindPackagesUpdated();
}
})) {
return;
}
if (mAppsCustomizeContent != null) { if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.onPackagesUpdated(); mAppsCustomizeContent.onPackagesUpdated();
} }

View File

@ -53,6 +53,7 @@ import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.text.Collator; import java.text.Collator;
import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -156,7 +157,9 @@ public class LauncherModel extends BroadcastReceiver {
public void bindAllApplications(ArrayList<ApplicationInfo> apps); public void bindAllApplications(ArrayList<ApplicationInfo> apps);
public void bindAppsAdded(ArrayList<ApplicationInfo> apps); public void bindAppsAdded(ArrayList<ApplicationInfo> apps);
public void bindAppsUpdated(ArrayList<ApplicationInfo> apps); public void bindAppsUpdated(ArrayList<ApplicationInfo> apps);
public void bindAppsRemoved(ArrayList<String> packageNames, boolean permanent); public void bindComponentsRemoved(ArrayList<String> packageNames,
ArrayList<ApplicationInfo> appInfos,
boolean matchPackageNamesOnly);
public void bindPackagesUpdated(); public void bindPackagesUpdated();
public boolean isAllAppsVisible(); public boolean isAllAppsVisible();
public boolean isAllAppsButtonRank(int rank); public boolean isAllAppsButtonRank(int rank);
@ -2009,6 +2012,7 @@ public class LauncherModel extends BroadcastReceiver {
ArrayList<ApplicationInfo> added = null; ArrayList<ApplicationInfo> added = null;
ArrayList<ApplicationInfo> modified = null; ArrayList<ApplicationInfo> modified = null;
final ArrayList<ApplicationInfo> removedApps = new ArrayList<ApplicationInfo>();
if (mBgAllAppsList.added.size() > 0) { if (mBgAllAppsList.added.size() > 0) {
added = new ArrayList<ApplicationInfo>(mBgAllAppsList.added); added = new ArrayList<ApplicationInfo>(mBgAllAppsList.added);
@ -2018,16 +2022,9 @@ public class LauncherModel extends BroadcastReceiver {
modified = new ArrayList<ApplicationInfo>(mBgAllAppsList.modified); modified = new ArrayList<ApplicationInfo>(mBgAllAppsList.modified);
mBgAllAppsList.modified.clear(); mBgAllAppsList.modified.clear();
} }
// We may be removing packages that have no associated launcher application, so we
// pass through the removed package names directly.
// NOTE: We flush the icon cache aggressively in removePackage() above.
final ArrayList<String> removedPackageNames = new ArrayList<String>();
if (mBgAllAppsList.removed.size() > 0) { if (mBgAllAppsList.removed.size() > 0) {
removedApps.addAll(mBgAllAppsList.removed);
mBgAllAppsList.removed.clear(); mBgAllAppsList.removed.clear();
for (int i = 0; i < N; ++i) {
removedPackageNames.add(packages[i]);
}
} }
final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null; final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
@ -2058,13 +2055,19 @@ public class LauncherModel extends BroadcastReceiver {
} }
}); });
} }
if (!removedPackageNames.isEmpty()) { // If a package has been removed, or an app has been removed as a result of
final boolean permanent = mOp != OP_UNAVAILABLE; // an update (for example), make the removed callback.
if (mOp == OP_REMOVE || !removedApps.isEmpty()) {
final boolean permanent = (mOp == OP_REMOVE);
final ArrayList<String> removedPackageNames =
new ArrayList<String>(Arrays.asList(packages));
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
public void run() { public void run() {
Callbacks cb = mCallbacks != null ? mCallbacks.get() : null; Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
if (callbacks == cb && cb != null) { if (callbacks == cb && cb != null) {
callbacks.bindAppsRemoved(removedPackageNames, permanent); callbacks.bindComponentsRemoved(removedPackageNames,
removedApps, permanent);
} }
} }
}); });

View File

@ -93,12 +93,6 @@ class ShortcutInfo extends ItemInfo {
return mIcon; return mIcon;
} }
/** Returns the package name that the shortcut's intent will resolve to, or an empty string if
* none exists. */
String getPackageName() {
return super.getPackageName(intent);
}
public void updateIcon(IconCache iconCache) { public void updateIcon(IconCache iconCache) {
mIcon = iconCache.getIcon(intent); mIcon = iconCache.getIcon(intent);
usingFallbackIcon = iconCache.isDefaultIcon(mIcon); usingFallbackIcon = iconCache.isDefaultIcon(mIcon);

View File

@ -3639,10 +3639,66 @@ public class Workspace extends SmoothPagedView
} }
} }
void removeItems(final ArrayList<String> packages) { // Removes ALL items that match a given package name, this is usually called when a package
final HashSet<String> packageNames = new HashSet<String>(); // has been removed and we want to remove all components (widgets, shortcuts, apps) that
// belong to that package.
void removeItemsByPackageName(final ArrayList<String> packages) {
HashSet<String> packageNames = new HashSet<String>();
packageNames.addAll(packages); packageNames.addAll(packages);
// Just create a hash table of all the specific components that this will affect
HashSet<ComponentName> cns = new HashSet<ComponentName>();
ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts();
for (CellLayout layoutParent : cellLayouts) {
ViewGroup layout = layoutParent.getShortcutsAndWidgets();
int childCount = layout.getChildCount();
for (int i = 0; i < childCount; ++i) {
View view = layout.getChildAt(i);
Object tag = view.getTag();
if (tag instanceof ShortcutInfo) {
ShortcutInfo info = (ShortcutInfo) tag;
ComponentName cn = info.intent.getComponent();
if (packageNames.contains(cn.getPackageName())) {
cns.add(cn);
}
} else if (tag instanceof FolderInfo) {
FolderInfo info = (FolderInfo) tag;
for (ShortcutInfo s : info.contents) {
ComponentName cn = s.intent.getComponent();
if (packageNames.contains(cn.getPackageName())) {
cns.add(cn);
}
}
} else if (tag instanceof LauncherAppWidgetInfo) {
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag;
ComponentName cn = info.providerName;
if (packageNames.contains(cn.getPackageName())) {
cns.add(cn);
}
}
}
}
// Remove all the things
removeItemsByComponentName(cns);
}
// 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<ApplicationInfo> appInfos) {
// Just create a hash table of all the specific components that this will affect
HashSet<ComponentName> cns = new HashSet<ComponentName>();
for (ApplicationInfo info : appInfos) {
cns.add(info.componentName);
}
// Remove all the things
removeItemsByComponentName(cns);
}
void removeItemsByComponentName(final HashSet<ComponentName> componentNames) {
ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts(); ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts();
for (final CellLayout layoutParent: cellLayouts) { for (final CellLayout layoutParent: cellLayouts) {
final ViewGroup layout = layoutParent.getShortcutsAndWidgets(); final ViewGroup layout = layoutParent.getShortcutsAndWidgets();
@ -3664,7 +3720,7 @@ public class Workspace extends SmoothPagedView
final ComponentName name = intent.getComponent(); final ComponentName name = intent.getComponent();
if (name != null) { if (name != null) {
if (packageNames.contains(name.getPackageName())) { if (componentNames.contains(name)) {
LauncherModel.deleteItemFromDatabase(mLauncher, info); LauncherModel.deleteItemFromDatabase(mLauncher, info);
childrenToRemove.add(view); childrenToRemove.add(view);
} }
@ -3682,7 +3738,7 @@ public class Workspace extends SmoothPagedView
final ComponentName name = intent.getComponent(); final ComponentName name = intent.getComponent();
if (name != null) { if (name != null) {
if (packageNames.contains(name.getPackageName())) { if (componentNames.contains(name)) {
appsToRemoveFromFolder.add(appInfo); appsToRemoveFromFolder.add(appInfo);
} }
} }
@ -3695,7 +3751,7 @@ public class Workspace extends SmoothPagedView
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag; final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag;
final ComponentName provider = info.providerName; final ComponentName provider = info.providerName;
if (provider != null) { if (provider != null) {
if (packageNames.contains(provider.getPackageName())) { if (componentNames.contains(provider)) {
LauncherModel.deleteItemFromDatabase(mLauncher, info); LauncherModel.deleteItemFromDatabase(mLauncher, info);
childrenToRemove.add(view); childrenToRemove.add(view);
} }
@ -3740,8 +3796,7 @@ public class Workspace extends SmoothPagedView
while (iter.hasNext()) { while (iter.hasNext()) {
try { try {
Intent intent = Intent.parseUri(iter.next(), 0); Intent intent = Intent.parseUri(iter.next(), 0);
String pn = ItemInfo.getPackageName(intent); if (componentNames.contains(intent.getComponent())) {
if (packageNames.contains(pn)) {
iter.remove(); iter.remove();
} }