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;
}
/** 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.
* Sets {@link #itemType} to {@link LauncherSettings.BaseLauncherColumns#ITEM_TYPE_APPLICATION}.

View File

@ -1556,16 +1556,6 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
}
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) {
// loop through all the apps and remove apps that have the same component
int length = list.size();
@ -1577,18 +1567,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
}
}
}
private void removeAppsWithPackageNameWithoutInvalidate(ArrayList<String> packageNames) {
// loop through all the package names and remove apps that have the same package name
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);
public void removeApps(ArrayList<ApplicationInfo> appInfos) {
removeAppsWithoutInvalidate(appInfos);
updatePageCounts();
invalidateOnDataChange();
}

View File

@ -328,18 +328,19 @@ public class DragController {
}
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
if (mDragObject != null) {
Object rawDragInfo = mDragObject.dragInfo;
if (rawDragInfo instanceof ShortcutInfo) {
ShortcutInfo dragInfo = (ShortcutInfo) rawDragInfo;
for (String pn : packageNames) {
for (ApplicationInfo info : appInfos) {
// Added null checks to prevent NPE we've seen in the wild
if (dragInfo != null &&
dragInfo.intent != null) {
boolean isSamePackage = dragInfo.getPackageName().equals(pn);
if (isSamePackage) {
boolean isSameComponent =
dragInfo.intent.getComponent().equals(info.componentName);
if (isSameComponent) {
cancelDrag();
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.
*/
public void bindAppsRemoved(ArrayList<String> packageNames, boolean permanent) {
if (permanent) {
mWorkspace.removeItems(packageNames);
public void bindComponentsRemoved(final ArrayList<String> packageNames,
final ArrayList<ApplicationInfo> appInfos,
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) {
mAppsCustomizeContent.removeApps(packageNames);
mAppsCustomizeContent.removeApps(appInfos);
}
// Notify the drag controller
mDragController.onAppsRemoved(packageNames, this);
mDragController.onAppsRemoved(appInfos, this);
}
/**
* A number of packages were updated.
*/
public void bindPackagesUpdated() {
if (waitUntilResume(new Runnable() {
public void run() {
bindPackagesUpdated();
}
})) {
return;
}
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.onPackagesUpdated();
}

View File

@ -53,6 +53,7 @@ import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
import java.lang.ref.WeakReference;
import java.net.URISyntaxException;
import java.text.Collator;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@ -156,7 +157,9 @@ public class LauncherModel extends BroadcastReceiver {
public void bindAllApplications(ArrayList<ApplicationInfo> apps);
public void bindAppsAdded(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 boolean isAllAppsVisible();
public boolean isAllAppsButtonRank(int rank);
@ -2009,6 +2012,7 @@ public class LauncherModel extends BroadcastReceiver {
ArrayList<ApplicationInfo> added = null;
ArrayList<ApplicationInfo> modified = null;
final ArrayList<ApplicationInfo> removedApps = new ArrayList<ApplicationInfo>();
if (mBgAllAppsList.added.size() > 0) {
added = new ArrayList<ApplicationInfo>(mBgAllAppsList.added);
@ -2018,16 +2022,9 @@ public class LauncherModel extends BroadcastReceiver {
modified = new ArrayList<ApplicationInfo>(mBgAllAppsList.modified);
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) {
removedApps.addAll(mBgAllAppsList.removed);
mBgAllAppsList.removed.clear();
for (int i = 0; i < N; ++i) {
removedPackageNames.add(packages[i]);
}
}
final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
@ -2058,13 +2055,19 @@ public class LauncherModel extends BroadcastReceiver {
}
});
}
if (!removedPackageNames.isEmpty()) {
final boolean permanent = mOp != OP_UNAVAILABLE;
// If a package has been removed, or an app has been removed as a result of
// 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() {
public void run() {
Callbacks cb = mCallbacks != null ? mCallbacks.get() : 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;
}
/** 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) {
mIcon = iconCache.getIcon(intent);
usingFallbackIcon = iconCache.isDefaultIcon(mIcon);

View File

@ -3639,10 +3639,66 @@ public class Workspace extends SmoothPagedView
}
}
void removeItems(final ArrayList<String> packages) {
final HashSet<String> packageNames = new HashSet<String>();
// Removes ALL items that match a given package name, this is usually called when a package
// 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);
// 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();
for (final CellLayout layoutParent: cellLayouts) {
final ViewGroup layout = layoutParent.getShortcutsAndWidgets();
@ -3664,7 +3720,7 @@ public class Workspace extends SmoothPagedView
final ComponentName name = intent.getComponent();
if (name != null) {
if (packageNames.contains(name.getPackageName())) {
if (componentNames.contains(name)) {
LauncherModel.deleteItemFromDatabase(mLauncher, info);
childrenToRemove.add(view);
}
@ -3682,7 +3738,7 @@ public class Workspace extends SmoothPagedView
final ComponentName name = intent.getComponent();
if (name != null) {
if (packageNames.contains(name.getPackageName())) {
if (componentNames.contains(name)) {
appsToRemoveFromFolder.add(appInfo);
}
}
@ -3695,7 +3751,7 @@ public class Workspace extends SmoothPagedView
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag;
final ComponentName provider = info.providerName;
if (provider != null) {
if (packageNames.contains(provider.getPackageName())) {
if (componentNames.contains(provider)) {
LauncherModel.deleteItemFromDatabase(mLauncher, info);
childrenToRemove.add(view);
}
@ -3740,8 +3796,7 @@ public class Workspace extends SmoothPagedView
while (iter.hasNext()) {
try {
Intent intent = Intent.parseUri(iter.next(), 0);
String pn = ItemInfo.getPackageName(intent);
if (packageNames.contains(pn)) {
if (componentNames.contains(intent.getComponent())) {
iter.remove();
}