summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2013-07-08 17:17:08 -0700
committerWinson Chung <winsonc@google.com>2013-07-11 14:19:52 -0700
commit64359a53dc827797917a8d9a0697a91996789801 (patch)
tree03d0c25c961a960d2c6592bbc919f3a8cf5e233c
parentd6e7aa31546fd8c1d047a581c141c12fc23c047e (diff)
downloadandroid_packages_apps_Trebuchet-64359a53dc827797917a8d9a0697a91996789801.tar.gz
android_packages_apps_Trebuchet-64359a53dc827797917a8d9a0697a91996789801.tar.bz2
android_packages_apps_Trebuchet-64359a53dc827797917a8d9a0697a91996789801.zip
Ensuring that the db reflects all package added/removed/updated broadcasts.
- Also ensuring that newly added pages are added before the empty page Change-Id: I97a01f791c438aa5c5b1fd770d3536b449a871bc
-rw-r--r--res/values/config.xml4
-rw-r--r--src/com/android/launcher3/ApplicationInfo.java5
-rw-r--r--src/com/android/launcher3/AppsCustomizePagedView.java6
-rw-r--r--src/com/android/launcher3/FolderInfo.java8
-rw-r--r--src/com/android/launcher3/Hotseat.java3
-rw-r--r--src/com/android/launcher3/Launcher.java189
-rw-r--r--src/com/android/launcher3/LauncherModel.java400
-rw-r--r--src/com/android/launcher3/PagedView.java1
-rw-r--r--src/com/android/launcher3/Workspace.java238
9 files changed, 417 insertions, 437 deletions
diff --git a/res/values/config.xml b/res/values/config.xml
index e65818f15..6aaca1ad5 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -33,10 +33,6 @@
AppsCustomize (y / x * 100%) -->
<integer name="config_appsCustomizeDragSlopeThreshold">150</integer>
- <!-- Batch loading for loading in LauncherModel -->
- <integer name="config_allAppsBatchLoadDelay">0</integer>
- <integer name="config_allAppsBatchSize">0</integer>
-
<!-- Workspace -->
<!-- Whether or not the drop targets drop down as opposed to fade in -->
<bool name="config_useDropTargetDownTransition">true</bool>
diff --git a/src/com/android/launcher3/ApplicationInfo.java b/src/com/android/launcher3/ApplicationInfo.java
index 4659e7e85..53801d60c 100644
--- a/src/com/android/launcher3/ApplicationInfo.java
+++ b/src/com/android/launcher3/ApplicationInfo.java
@@ -114,7 +114,10 @@ class ApplicationInfo extends ItemInfo {
@Override
public String toString() {
- return "ApplicationInfo(title=" + title.toString() + ")";
+ return "ApplicationInfo(title=" + title.toString() + " id=" + this.id
+ + " type=" + this.itemType + " container=" + this.container
+ + " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY
+ + " spanX=" + spanX + " spanY=" + spanY + " dropPos=" + dropPos + ")";
}
public static void dumpApplicationInfoList(String tag, String label,
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index aa2d531cf..dafa9b490 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -1592,8 +1592,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
}
}
public void removeApps(ArrayList<ApplicationInfo> appInfos) {
- removeAppsWithoutInvalidate(appInfos);
- updatePageCountsAndInvalidateData();
+ if (!DISABLE_ALL_APPS) {
+ removeAppsWithoutInvalidate(appInfos);
+ updatePageCountsAndInvalidateData();
+ }
}
public void updateApps(ArrayList<ApplicationInfo> list) {
// We remove and re-add the updated applications list because it's properties may have
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index 6d45e59ce..bb5ae8200 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -108,4 +108,12 @@ class FolderInfo extends ItemInfo {
public void onTitleChanged(CharSequence title);
public void onItemsChanged();
}
+
+ @Override
+ public String toString() {
+ return "FolderInfo(id=" + this.id + " type=" + this.itemType
+ + " container=" + this.container + " screen=" + screenId
+ + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX
+ + " spanY=" + spanY + " dropPos=" + dropPos + ")";
+ }
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 93f39ff3b..054ef2fc1 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -24,6 +24,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
@@ -136,7 +137,7 @@ public class Hotseat extends FrameLayout {
for (ApplicationInfo info: allApps) {
ComponentName cn = info.intent.getComponent();
if (!onWorkspace.contains(cn)) {
- System.out.println("Adding to all apps: " + info.intent);
+ Log.d(TAG, "Adding to all apps: " + info.intent);
ShortcutInfo si = info.makeShortcut();
fi.add(si);
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index b8fce6def..95aefe674 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -193,6 +193,7 @@ public class Launcher extends Activity
// How long to wait before the new-shortcut animation automatically pans the workspace
private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 10;
+ private static int NEW_APPS_ANIMATION_DELAY = 500;
private final BroadcastReceiver mCloseSystemDialogsReceiver
= new CloseSystemDialogsIntentReceiver();
@@ -407,11 +408,6 @@ public class Launcher extends Activity
}
}
- if (!mModel.isAllAppsLoaded()) {
- ViewGroup appsCustomizeContentParent = (ViewGroup) mAppsCustomizeContent.getParent();
- mInflater.inflate(R.layout.apps_customize_progressbar, appsCustomizeContentParent);
- }
-
// For handling default keys
mDefaultKeySsb = new SpannableStringBuilder();
Selection.setSelection(mDefaultKeySsb, 0);
@@ -2479,17 +2475,10 @@ public class Launcher extends Activity
return mWorkspace;
}
- // Now a part of LauncherModel.Callbacks. Used to reorder loading steps.
- @Override
public boolean isAllAppsVisible() {
return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);
}
- @Override
- public boolean isAllAppsButtonRank(int rank) {
- return mHotseat.isAllAppsButtonRank(rank);
- }
-
/**
* Helper method for the cameraZoomIn/cameraZoomOut animations
* @param view The view being animated
@@ -3453,11 +3442,16 @@ public class Launcher extends Activity
@Override
public void bindScreens(ArrayList<Long> orderedScreenIds) {
+ bindAddScreens(orderedScreenIds);
+ mWorkspace.addExtraEmptyScreen();
+ }
+
+ @Override
+ public void bindAddScreens(ArrayList<Long> orderedScreenIds) {
int count = orderedScreenIds.size();
for (int i = 0; i < count; i++) {
- mWorkspace.insertNewWorkspaceScreenOnBind(orderedScreenIds.get(i));
+ mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i), false);
}
- mWorkspace.addExtraEmptyScreen();
}
/**
@@ -3465,10 +3459,11 @@ public class Launcher extends Activity
*
* Implementation of the method from LauncherModel.Callbacks.
*/
- public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end) {
+ public void bindItems(final ArrayList<ItemInfo> shortcuts, final int start, final int end,
+ final boolean forceAnimateIcons) {
if (waitUntilResume(new Runnable() {
public void run() {
- bindItems(shortcuts, start, end);
+ bindItems(shortcuts, start, end, forceAnimateIcons);
}
})) {
return;
@@ -3478,6 +3473,8 @@ public class Launcher extends Activity
Set<String> newApps = new HashSet<String>();
newApps = mSharedPrefs.getStringSet(InstallShortcutReceiver.NEW_APPS_LIST_KEY, newApps);
+ final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
+ final Collection<Animator> bounceAnims = new ArrayList<Animator>();
Workspace workspace = mWorkspace;
for (int i = start; i < end; i++) {
final ItemInfo item = shortcuts.get(i);
@@ -3495,6 +3492,14 @@ public class Launcher extends Activity
String uri = info.intent.toUri(0).toString();
View shortcut = createShortcut(info);
+ /*
+ * TODO: FIX collision case
+ */
+ CellLayout cl = mWorkspace.getScreenWithId(item.screenId);
+ if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {
+ throw new RuntimeException("OCCUPIED");
+ }
+
workspace.addInScreenFromBind(shortcut, item.container, item.screenId, item.cellX,
item.cellY, 1, 1);
boolean animateIconUp = false;
@@ -3503,7 +3508,13 @@ public class Launcher extends Activity
animateIconUp = newApps.remove(uri);
}
}
- if (animateIconUp) {
+ if (forceAnimateIcons) {
+ // Animate all the applications up now
+ shortcut.setAlpha(0f);
+ shortcut.setScaleX(0f);
+ shortcut.setScaleY(0f);
+ bounceAnims.add(createNewAppBounceAnimation(shortcut, i));
+ } else if (animateIconUp) {
// Prepare the view to be animated up
shortcut.setAlpha(0f);
shortcut.setScaleX(0f);
@@ -3524,6 +3535,16 @@ public class Launcher extends Activity
}
}
+ if (forceAnimateIcons) {
+ // We post the animation slightly delayed to prevent slowdowns when we are loading
+ // right after we return to launcher.
+ mWorkspace.postDelayed(new Runnable() {
+ public void run() {
+ anim.playTogether(bounceAnims);
+ anim.start();
+ }
+ }, NEW_APPS_ANIMATION_DELAY);
+ }
workspace.requestLayout();
}
@@ -3595,7 +3616,6 @@ public class Launcher extends Activity
* Implementation of the method from LauncherModel.Callbacks.
*/
public void finishBindingItems(final boolean upgradePath) {
-
if (waitUntilResume(new Runnable() {
public void run() {
finishBindingItems(upgradePath);
@@ -3753,119 +3773,10 @@ public class Launcher extends Activity
* Implementation of the method from LauncherModel.Callbacks.
*/
public void bindAllApplications(final ArrayList<ApplicationInfo> apps) {
- Runnable setAllAppsRunnable = new Runnable() {
- public void run() {
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.setApps(apps);
-
- if (mIntentsOnWorkspaceFromUpgradePath != null) {
- getHotseat().addAllAppsFolder(mIconCache, apps,
- mIntentsOnWorkspaceFromUpgradePath, Launcher.this);
- mIntentsOnWorkspaceFromUpgradePath = null;
- }
- }
- }
- };
-
- // Remove the progress bar entirely; we could also make it GONE
- // but better to remove it since we know it's not going to be used
- View progressBar = mAppsCustomizeTabHost.
- findViewById(R.id.apps_customize_progress_bar);
- if (progressBar != null) {
- ((ViewGroup)progressBar.getParent()).removeView(progressBar);
-
- // We just post the call to setApps so the user sees the progress bar
- // disappear-- otherwise, it just looks like the progress bar froze
- // which doesn't look great
- mAppsCustomizeTabHost.post(setAllAppsRunnable);
- } else {
- // If we did not initialize the spinner in onCreate, then we can directly set the
- // list of applications without waiting for any progress bars views to be hidden.
- setAllAppsRunnable.run();
- }
- }
-
- /**
- * A package was installed.
- *
- * Implementation of the method from LauncherModel.Callbacks.
- */
- public void bindAppsAdded(final ArrayList<ApplicationInfo> apps) {
- if (waitUntilResume(new Runnable() {
- public void run() {
- bindAppsAdded(apps);
- }
- })) {
- return;
- }
-
- final Launcher launcher = this;
- final Context context = this;
- final ArrayList<ApplicationInfo> appsCopy = new ArrayList<ApplicationInfo>();
- appsCopy.addAll(apps);
-
- // Process newly added apps
- mWorkspace.post(new Runnable() {
- @Override
- public void run() {
- // Process newly added apps
- LauncherModel model = getModel();
- Iterator<ApplicationInfo> iter = appsCopy.iterator();
- ArrayList<View> animatedShortcuts = new ArrayList<View>();
-
- while (iter.hasNext()) {
- ApplicationInfo a = iter.next();
- Pair<Long, int[]> coords = LauncherModel.findNextAvailableIconSpace(context,
- a.title.toString(), a.intent);
- if (coords == null) {
- // If we can't find a valid position, then just add a new screen.
- // This takes time so we need to re-queue the add until the new
- // page is added.
- long screenId = LauncherAppState.getInstance().getLauncherProvider()
- .generateNewScreenId();
- mWorkspace.insertNewWorkspaceScreen(screenId, false);
- model.updateWorkspaceScreenOrder(launcher, mWorkspace.getScreenOrder(),
- new Runnable() {
- @Override
- public void run() {
- bindAppsAdded(appsCopy);
- }
- });
- return;
- } else {
- final ShortcutInfo shortcutInfo = a.makeShortcut();
- final View shortcut = createShortcut(shortcutInfo);
- // Add the view to the screen
- mWorkspace.addInScreenFromBind(shortcut,
- LauncherSettings.Favorites.CONTAINER_DESKTOP,
- coords.first, coords.second[0], coords.second[1], 1, 1);
- // Add the shortcut to the db
- model.addItemToDatabase(context, shortcutInfo,
- LauncherSettings.Favorites.CONTAINER_DESKTOP,
- coords.first, coords.second[0], coords.second[1], false);
- // Animate the shortcut
- animatedShortcuts.add(shortcut);
- }
- iter.remove();
- }
-
- // Animate all the applications up
- AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
- Collection<Animator> bounceAnims = new ArrayList<Animator>();
- for (int i = 0; i < animatedShortcuts.size(); ++i) {
- View shortcut = animatedShortcuts.get(i);
- shortcut.setAlpha(0f);
- shortcut.setScaleX(0f);
- shortcut.setScaleY(0f);
- bounceAnims.add(createNewAppBounceAnimation(shortcut, i));
- }
- anim.playTogether(bounceAnims);
- anim.start();
- }
- });
-
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.addApps(apps);
+ if (mIntentsOnWorkspaceFromUpgradePath != null) {
+ getHotseat().addAllAppsFolder(mIconCache, apps,
+ mIntentsOnWorkspaceFromUpgradePath, Launcher.this);
+ mIntentsOnWorkspaceFromUpgradePath = null;
}
}
@@ -3886,10 +3797,6 @@ public class Launcher extends Activity
if (mWorkspace != null) {
mWorkspace.updateShortcuts(apps);
}
-
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.updateApps(apps);
- }
}
/**
@@ -3903,25 +3810,21 @@ public class Launcher extends Activity
*/
public void bindComponentsRemoved(final ArrayList<String> packageNames,
final ArrayList<ApplicationInfo> appInfos,
- final boolean matchPackageNamesOnly) {
+ final boolean packageRemoved) {
if (waitUntilResume(new Runnable() {
public void run() {
- bindComponentsRemoved(packageNames, appInfos, matchPackageNamesOnly);
+ bindComponentsRemoved(packageNames, appInfos, packageRemoved);
}
})) {
return;
}
- if (matchPackageNamesOnly) {
+ if (packageRemoved) {
mWorkspace.removeItemsByPackageName(packageNames);
} else {
mWorkspace.removeItemsByApplicationInfo(appInfos);
}
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.removeApps(appInfos);
- }
-
// Notify the drag controller
mDragController.onAppsRemoved(appInfos, this);
}
@@ -3929,7 +3832,6 @@ public class Launcher extends Activity
/**
* A number of packages were updated.
*/
-
private ArrayList<Object> mWidgetsAndShortcuts;
private Runnable mBindPackagesUpdatedRunnable = new Runnable() {
public void run() {
@@ -3944,6 +3846,7 @@ public class Launcher extends Activity
return;
}
+ // Update the widgets pane
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index d09880542..0b69a09c9 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -48,6 +48,7 @@ import java.net.URISyntaxException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -68,8 +69,6 @@ public class LauncherModel extends BroadcastReceiver {
private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons
private final boolean mAppsCanBeOnExternalStorage;
- private int mBatchSize; // 0 is all apps at once
- private int mAllAppsLoadDelay; // milliseconds between batches
private final LauncherAppState mApp;
private final Object mLock = new Object();
@@ -149,24 +148,27 @@ public class LauncherModel extends BroadcastReceiver {
public boolean setLoadOnResume();
public int getCurrentWorkspaceScreen();
public void startBinding();
- public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end);
+ public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end,
+ boolean forceAnimateIcons);
public void bindScreens(ArrayList<Long> orderedScreenIds);
+ public void bindAddScreens(ArrayList<Long> orderedScreenIds);
public void bindFolders(HashMap<Long,FolderInfo> folders);
public void finishBindingItems(boolean upgradePath);
public void bindAppWidget(LauncherAppWidgetInfo info);
public void bindAllApplications(ArrayList<ApplicationInfo> apps);
- public void bindAppsAdded(ArrayList<ApplicationInfo> apps);
public void bindAppsUpdated(ArrayList<ApplicationInfo> apps);
public void bindComponentsRemoved(ArrayList<String> packageNames,
ArrayList<ApplicationInfo> appInfos,
boolean matchPackageNamesOnly);
public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
- public boolean isAllAppsVisible();
- public boolean isAllAppsButtonRank(int rank);
public void bindSearchablesChanged();
public void onPageBoundSynchronously(int page);
}
+ public interface ItemInfoFilter {
+ public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn);
+ }
+
LauncherModel(LauncherAppState app, IconCache iconCache) {
final Context context = app.getContext();
@@ -179,8 +181,6 @@ public class LauncherModel extends BroadcastReceiver {
mIconCache.getFullResDefaultActivityIcon(), context);
final Resources res = context.getResources();
- mAllAppsLoadDelay = res.getInteger(R.integer.config_allAppsBatchLoadDelay);
- mBatchSize = res.getInteger(R.integer.config_allAppsBatchSize);
Configuration config = res.getConfiguration();
mPreviousConfigMcc = config.mcc;
}
@@ -243,12 +243,13 @@ public class LauncherModel extends BroadcastReceiver {
LauncherModel model = app.getModel();
boolean found = false;
synchronized (app) {
- // Flush the LauncherModel worker thread, so that if we just did another
- // processInstallShortcut, we give it time for its shortcut to get added to the
- // database (getItemsInLocalCoordinates reads the database)
- model.flushWorkerThread();
+ if (sWorkerThread.getThreadId() != Process.myTid()) {
+ // Flush the LauncherModel worker thread, so that if we just did another
+ // processInstallShortcut, we give it time for its shortcut to get added to the
+ // database (getItemsInLocalCoordinates reads the database)
+ model.flushWorkerThread();
+ }
final ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
- final boolean shortcutExists = LauncherModel.shortcutExists(context, name, launchIntent);
// Try adding to the workspace screens incrementally, starting at the default or center
// screen and alternating between +1, -1, +2, -2, etc. (using ~ ceil(i/2f)*(-1)^(i-1))
@@ -265,6 +266,74 @@ public class LauncherModel extends BroadcastReceiver {
return null;
}
+ public void addAndBindAddedApps(final Context context, final ArrayList<ApplicationInfo> added,
+ final Callbacks callbacks) {
+ // Process the newly added applications and add them to the database first
+ Runnable r = new Runnable() {
+ public void run() {
+ final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>();
+ final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
+
+ synchronized(sBgLock) {
+ Iterator<ApplicationInfo> iter = added.iterator();
+ while (iter.hasNext()) {
+ ApplicationInfo a = iter.next();
+ final String name = a.title.toString();
+ final Intent launchIntent = a.intent;
+
+ // Short-circuit this logic if the icon exists somewhere on the workspace
+ if (LauncherModel.shortcutExists(context, name, launchIntent)) {
+ continue;
+ }
+
+ // Add this icon to the db, creating a new page if necessary
+ Pair<Long, int[]> coords = LauncherModel.findNextAvailableIconSpace(context,
+ name, launchIntent);
+ if (coords == null) {
+ // If we can't find a valid position, then just add a new screen.
+ // This takes time so we need to re-queue the add until the new
+ // page is added.
+ LauncherAppState appState = LauncherAppState.getInstance();
+ LauncherProvider lp = appState.getLauncherProvider();
+ long screenId = lp.generateNewScreenId();
+ // Update the model
+ sBgWorkspaceScreens.add(screenId);
+ updateWorkspaceScreenOrder(context, sBgWorkspaceScreens);
+ // Save the screen id for binding in the workspace
+ addedWorkspaceScreensFinal.add(screenId);
+ // Find the coordinate again
+ coords = LauncherModel.findNextAvailableIconSpace(context,
+ a.title.toString(), a.intent);
+ }
+ if (coords == null) {
+ throw new RuntimeException("Coordinates should not be null");
+ }
+
+ final ShortcutInfo shortcutInfo = a.makeShortcut();
+ // Add the shortcut to the db
+ addItemToDatabase(context, shortcutInfo,
+ LauncherSettings.Favorites.CONTAINER_DESKTOP,
+ coords.first, coords.second[0], coords.second[1], false);
+ // Save the ShortcutInfo for binding in the workspace
+ addedShortcutsFinal.add(shortcutInfo);
+ }
+ }
+
+ runOnMainThread(new Runnable() {
+ public void run() {
+ Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+ if (callbacks == cb && cb != null) {
+ callbacks.bindAddScreens(addedWorkspaceScreensFinal);
+ callbacks.bindItems(addedShortcutsFinal, 0,
+ addedShortcutsFinal.size(), true);
+ }
+ }
+ });
+ }
+ };
+ runOnWorkerThread(r);
+ }
+
public Bitmap getFallbackIcon() {
return Bitmap.createBitmap(mDefaultIcon);
}
@@ -868,14 +937,12 @@ public class LauncherModel extends BroadcastReceiver {
* a list of screen ids in the order that they should appear.
*/
void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) {
- updateWorkspaceScreenOrder(context, screens, null);
- }
- void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens, final Runnable mainThreadCb) {
+ final ArrayList<Long> screensCopy = new ArrayList<Long>(screens);
final ContentResolver cr = context.getContentResolver();
final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
// Remove any negative screen ids -- these aren't persisted
- Iterator<Long> iter = screens.iterator();
+ Iterator<Long> iter = screensCopy.iterator();
while (iter.hasNext()) {
long id = iter.next();
if (id < 0) {
@@ -886,8 +953,6 @@ public class LauncherModel extends BroadcastReceiver {
Runnable r = new Runnable() {
@Override
public void run() {
- final ArrayList<Long> screensCopy = new ArrayList<Long>();
-
// Clear the table
cr.delete(uri, null, null);
int count = screens.size();
@@ -897,7 +962,6 @@ public class LauncherModel extends BroadcastReceiver {
long screenId = screens.get(i);
v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
- screensCopy.add(screenId);
values[i] = v;
}
cr.bulkInsert(uri, values);
@@ -906,14 +970,6 @@ public class LauncherModel extends BroadcastReceiver {
}
};
runOnWorkerThread(r);
- if (mainThreadCb != null) {
- runOnWorkerThread(new Runnable() {
- @Override
- public void run() {
- runOnMainThread(mainThreadCb);
- }
- });
- }
}
/**
@@ -1279,8 +1335,6 @@ public class LauncherModel extends BroadcastReceiver {
// All Apps interface in the foreground, load All Apps first. Otherwise, load the
// workspace first (default).
final Callbacks cbk = mCallbacks.get();
- final boolean loadWorkspaceFirst = cbk != null ? (!cbk.isAllAppsVisible()) : true;
-
keep_running: {
// Elevate priority when Home launches for the first time to avoid
// starving at boot time. Staring at a blank home is not cool.
@@ -1290,13 +1344,8 @@ public class LauncherModel extends BroadcastReceiver {
android.os.Process.setThreadPriority(mIsLaunching
? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND);
}
- if (loadWorkspaceFirst) {
- if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace");
- loadAndBindWorkspace();
- } else {
- if (DEBUG_LOADERS) Log.d(TAG, "step 1: special: loading all apps");
- loadAndBindAllApps();
- }
+ if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace");
+ loadAndBindWorkspace();
if (mStopped) {
break keep_running;
@@ -1313,13 +1362,8 @@ public class LauncherModel extends BroadcastReceiver {
waitForIdle();
// second step
- if (loadWorkspaceFirst) {
- if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps");
- loadAndBindAllApps();
- } else {
- if (DEBUG_LOADERS) Log.d(TAG, "step 2: special: loading workspace");
- loadAndBindWorkspace();
- }
+ if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps");
+ loadAndBindAllApps();
// Restore the default thread priority after we are done loading items
synchronized (mLock) {
@@ -1952,7 +1996,8 @@ public class LauncherModel extends BroadcastReceiver {
public void run() {
Callbacks callbacks = tryGetCallbacks(oldCallbacks);
if (callbacks != null) {
- callbacks.bindItems(workspaceItems, start, start+chunkSize);
+ callbacks.bindItems(workspaceItems, start, start+chunkSize,
+ false);
}
}
};
@@ -2119,7 +2164,7 @@ public class LauncherModel extends BroadcastReceiver {
Log.d(TAG, "loadAndBindAllApps mAllAppsLoaded=" + mAllAppsLoaded);
}
if (!mAllAppsLoaded) {
- loadAllAppsByBatch();
+ loadAllApps();
synchronized (LoaderTask.this) {
if (mStopped) {
return;
@@ -2157,124 +2202,84 @@ public class LauncherModel extends BroadcastReceiver {
}
};
boolean isRunningOnMainThread = !(sWorkerThread.getThreadId() == Process.myTid());
- if (oldCallbacks.isAllAppsVisible() && isRunningOnMainThread) {
+ if (isRunningOnMainThread) {
r.run();
} else {
mHandler.post(r);
}
}
- private void loadAllAppsByBatch() {
- final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
+ private void loadAllApps() {
+ final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
// Don't use these two variables in any of the callback runnables.
// Otherwise we hold a reference to them.
final Callbacks oldCallbacks = mCallbacks.get();
if (oldCallbacks == null) {
// This launcher has exited and nobody bothered to tell us. Just bail.
- Log.w(TAG, "LoaderTask running with no launcher (loadAllAppsByBatch)");
+ Log.w(TAG, "LoaderTask running with no launcher (loadAllApps)");
return;
}
+ final PackageManager packageManager = mContext.getPackageManager();
final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
- final PackageManager packageManager = mContext.getPackageManager();
- List<ResolveInfo> apps = null;
-
- int N = Integer.MAX_VALUE;
-
- int startIndex;
- int i=0;
- int batchSize = -1;
- while (i < N && !mStopped) {
- if (i == 0) {
- mBgAllAppsList.clear();
- final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
- apps = packageManager.queryIntentActivities(mainIntent, 0);
- if (DEBUG_LOADERS) {
- Log.d(TAG, "queryIntentActivities took "
- + (SystemClock.uptimeMillis()-qiaTime) + "ms");
- }
- if (apps == null) {
- return;
- }
- N = apps.size();
- if (DEBUG_LOADERS) {
- Log.d(TAG, "queryIntentActivities got " + N + " apps");
- }
- if (N == 0) {
- // There are no apps?!?
- return;
- }
- if (mBatchSize == 0) {
- batchSize = N;
- } else {
- batchSize = mBatchSize;
- }
+ // Clear the list of apps
+ mBgAllAppsList.clear();
- final long sortTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
- Collections.sort(apps,
- new LauncherModel.ShortcutNameComparator(packageManager, mLabelCache));
- if (DEBUG_LOADERS) {
- Log.d(TAG, "sort took "
- + (SystemClock.uptimeMillis()-sortTime) + "ms");
- }
- }
-
- final long t2 = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
-
- startIndex = i;
- for (int j=0; i<N && j<batchSize; j++) {
- // This builds the icon bitmaps.
- mBgAllAppsList.add(new ApplicationInfo(packageManager, apps.get(i),
- mIconCache, mLabelCache));
- i++;
- }
-
- final boolean first = i <= batchSize;
- final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
- final ArrayList<ApplicationInfo> added = mBgAllAppsList.added;
- mBgAllAppsList.added = new ArrayList<ApplicationInfo>();
+ // Query for the set of apps
+ final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
+ List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
+ if (DEBUG_LOADERS) {
+ Log.d(TAG, "queryIntentActivities took "
+ + (SystemClock.uptimeMillis()-qiaTime) + "ms");
+ Log.d(TAG, "queryIntentActivities got " + apps.size() + " apps");
+ }
+ // Fail if we don't have any apps
+ if (apps == null || apps.isEmpty()) {
+ return;
+ }
+ // Sort the applications by name
+ final long sortTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
+ Collections.sort(apps,
+ new LauncherModel.ShortcutNameComparator(packageManager, mLabelCache));
+ if (DEBUG_LOADERS) {
+ Log.d(TAG, "sort took "
+ + (SystemClock.uptimeMillis()-sortTime) + "ms");
+ }
- mHandler.post(new Runnable() {
- public void run() {
- final long t = SystemClock.uptimeMillis();
- if (callbacks != null) {
- if (first) {
- callbacks.bindAllApplications(added);
- } else {
- callbacks.bindAppsAdded(added);
- }
- if (DEBUG_LOADERS) {
- Log.d(TAG, "bound " + added.size() + " apps in "
- + (SystemClock.uptimeMillis() - t) + "ms");
- }
- } else {
- Log.i(TAG, "not binding apps: no Launcher activity");
- }
- }
- });
+ // Create the ApplicationInfos
+ final long addTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
+ for (int i = 0; i < apps.size(); i++) {
+ // This builds the icon bitmaps.
+ mBgAllAppsList.add(new ApplicationInfo(packageManager, apps.get(i),
+ mIconCache, mLabelCache));
+ }
- if (DEBUG_LOADERS) {
- Log.d(TAG, "batch of " + (i-startIndex) + " icons processed in "
- + (SystemClock.uptimeMillis()-t2) + "ms");
- }
+ final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
+ final ArrayList<ApplicationInfo> added = mBgAllAppsList.added;
+ mBgAllAppsList.added = new ArrayList<ApplicationInfo>();
- if (mAllAppsLoadDelay > 0 && i < N) {
- try {
+ // Post callback on main thread
+ mHandler.post(new Runnable() {
+ public void run() {
+ final long bindTime = SystemClock.uptimeMillis();
+ if (callbacks != null) {
+ callbacks.bindAllApplications(added);
if (DEBUG_LOADERS) {
- Log.d(TAG, "sleeping for " + mAllAppsLoadDelay + "ms");
+ Log.d(TAG, "bound " + added.size() + " apps in "
+ + (SystemClock.uptimeMillis() - bindTime) + "ms");
}
- Thread.sleep(mAllAppsLoadDelay);
- } catch (InterruptedException exc) { }
+ } else {
+ Log.i(TAG, "not binding apps: no Launcher activity");
+ }
}
- }
+ });
if (DEBUG_LOADERS) {
- Log.d(TAG, "cached all " + N + " apps in "
- + (SystemClock.uptimeMillis()-t) + "ms"
- + (mAllAppsLoadDelay > 0 ? " (including delay)" : ""));
+ Log.d(TAG, "Icons processed in "
+ + (SystemClock.uptimeMillis() - loadTime) + "ms");
}
}
@@ -2364,18 +2369,26 @@ public class LauncherModel extends BroadcastReceiver {
}
if (added != null) {
- final ArrayList<ApplicationInfo> addedFinal = added;
- mHandler.post(new Runnable() {
- public void run() {
- Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
- if (callbacks == cb && cb != null) {
- callbacks.bindAppsAdded(addedFinal);
- }
- }
- });
+ // Ensure that we add all the workspace applications to the db
+ Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+ addAndBindAddedApps(context, added, cb);
}
if (modified != null) {
final ArrayList<ApplicationInfo> modifiedFinal = modified;
+
+ // Update the launcher db to reflect the changes
+ for (ApplicationInfo a : modifiedFinal) {
+ ArrayList<ItemInfo> infos =
+ getItemInfoForComponentName(a.componentName);
+ for (ItemInfo i : infos) {
+ if (isShortcutInfoUpdateable(i)) {
+ ShortcutInfo info = (ShortcutInfo) i;
+ info.title = a.title.toString();
+ updateItemInDatabase(context, info);
+ }
+ }
+ }
+
mHandler.post(new Runnable() {
public void run() {
Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
@@ -2388,16 +2401,34 @@ public class LauncherModel extends BroadcastReceiver {
// 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 boolean packageRemoved = (mOp == OP_REMOVE);
final ArrayList<String> removedPackageNames =
new ArrayList<String>(Arrays.asList(packages));
+ // Update the launcher db to reflect the removal of apps
+ if (packageRemoved) {
+ for (String pn : removedPackageNames) {
+ ArrayList<ItemInfo> infos = getItemInfoForPackageName(pn);
+ for (ItemInfo i : infos) {
+ deleteItemFromDatabase(context, i);
+ }
+ }
+ } else {
+ for (ApplicationInfo a : removedApps) {
+ ArrayList<ItemInfo> infos =
+ getItemInfoForComponentName(a.componentName);
+ for (ItemInfo i : infos) {
+ deleteItemFromDatabase(context, i);
+ }
+ }
+ }
+
mHandler.post(new Runnable() {
public void run() {
Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
if (callbacks == cb && cb != null) {
callbacks.bindComponentsRemoved(removedPackageNames,
- removedApps, permanent);
+ removedApps, packageRemoved);
}
}
});
@@ -2532,22 +2563,71 @@ public class LauncherModel extends BroadcastReceiver {
return info;
}
- /**
- * Returns the set of workspace ShortcutInfos with the specified intent.
- */
- static ArrayList<ItemInfo> getWorkspaceShortcutItemInfosWithIntent(Intent intent) {
- ArrayList<ItemInfo> items = new ArrayList<ItemInfo>();
- synchronized (sBgLock) {
- for (ItemInfo info : sBgWorkspaceItems) {
- if (info instanceof ShortcutInfo) {
- ShortcutInfo shortcut = (ShortcutInfo) info;
- if (shortcut.intent.toUri(0).equals(intent.toUri(0))) {
- items.add(shortcut);
+ static ArrayList<ItemInfo> filterItemInfos(Collection<ItemInfo> infos,
+ ItemInfoFilter f) {
+ HashSet<ItemInfo> filtered = new HashSet<ItemInfo>();
+ for (ItemInfo i : infos) {
+ if (i instanceof ShortcutInfo) {
+ ShortcutInfo info = (ShortcutInfo) i;
+ ComponentName cn = info.intent.getComponent();
+ if (cn != null && f.filterItem(null, info, cn)) {
+ filtered.add(info);
+ }
+ } else if (i instanceof FolderInfo) {
+ FolderInfo info = (FolderInfo) i;
+ for (ShortcutInfo s : info.contents) {
+ ComponentName cn = s.intent.getComponent();
+ if (cn != null && f.filterItem(info, s, cn)) {
+ filtered.add(s);
}
}
+ } else if (i instanceof LauncherAppWidgetInfo) {
+ LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) i;
+ ComponentName cn = info.providerName;
+ if (cn != null && f.filterItem(null, info, cn)) {
+ filtered.add(info);
+ }
}
}
- return items;
+ return new ArrayList<ItemInfo>(filtered);
+ }
+
+ private ArrayList<ItemInfo> getItemInfoForPackageName(final String pn) {
+ HashSet<ItemInfo> infos = new HashSet<ItemInfo>();
+ ItemInfoFilter filter = new ItemInfoFilter() {
+ @Override
+ public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn) {
+ return cn.getPackageName().equals(pn);
+ }
+ };
+ return filterItemInfos(sBgItemsIdMap.values(), filter);
+ }
+
+ private ArrayList<ItemInfo> getItemInfoForComponentName(final ComponentName cname) {
+ HashSet<ItemInfo> infos = new HashSet<ItemInfo>();
+ ItemInfoFilter filter = new ItemInfoFilter() {
+ @Override
+ public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn) {
+ return cn.equals(cname);
+ }
+ };
+ return filterItemInfos(sBgItemsIdMap.values(), filter);
+ }
+
+ public static boolean isShortcutInfoUpdateable(ItemInfo i) {
+ if (i instanceof ShortcutInfo) {
+ ShortcutInfo info = (ShortcutInfo) i;
+ // 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.intent;
+ ComponentName name = intent.getComponent();
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
+ Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
+ return true;
+ }
+ }
+ return false;
}
/**
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 20d7e5e00..0a20724ee 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1680,7 +1680,6 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
break;
}
- System.out.println("onTouch, return true");
return true;
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 851cce591..37ef3c437 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -474,22 +474,31 @@ public class Workspace extends SmoothPagedView
}
public long insertNewWorkspaceScreen(long screenId) {
- return insertNewWorkspaceScreen(screenId, true);
+ return insertNewWorkspaceScreen(screenId, getChildCount(), true);
}
- public long insertNewWorkspaceScreenOnBind(long screenId) {
- return insertNewWorkspaceScreen(screenId, false);
+ public long insertNewWorkspaceScreenBeforeEmptyScreen(long screenId, boolean updateDb) {
+ // Find the index to insert this view into. If the empty screen exists, then
+ // insert it before that.
+ int insertIndex = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);
+ if (insertIndex < 0) {
+ insertIndex = mScreenOrder.size();
+ }
+ return insertNewWorkspaceScreen(screenId, insertIndex, updateDb);
}
public long insertNewWorkspaceScreen(long screenId, boolean updateDb) {
+ return insertNewWorkspaceScreen(screenId, getChildCount(), updateDb);
+ }
+
+ public long insertNewWorkspaceScreen(long screenId, int insertIndex, boolean updateDb) {
CellLayout newScreen = (CellLayout)
mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);
-
newScreen.setOnLongClickListener(mLongClickListener);
mWorkspaceScreens.put(screenId, newScreen);
- mScreenOrder.add(screenId);
- addView(newScreen, getChildCount());
+ mScreenOrder.add(insertIndex, screenId);
+ addView(newScreen, insertIndex);
if (updateDb) {
// On bind we don't need to update the screens in the database.
mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
@@ -533,6 +542,10 @@ public class Workspace extends SmoothPagedView
mScreenOrder.add(newId);
addExtraEmptyScreen();
+
+ // Update the model for the new screen
+ mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
+
return newId;
}
@@ -588,6 +601,11 @@ public class Workspace extends SmoothPagedView
removeView(cl);
}
setCurrentPage(mCurrentPage - pageShift);
+
+ if (!removeScreens.isEmpty()) {
+ // Update the model if we have changed any screens
+ mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
+ }
}
// See implementation for parameter definition.
@@ -3741,44 +3759,35 @@ public class Workspace extends SmoothPagedView
// 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>();
+ final 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>();
+ // Filter out all the ItemInfos that this is going to affect
+ final HashSet<ItemInfo> infos = new HashSet<ItemInfo>();
+ final 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 ((cn != null) && 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 ((cn != null) && packageNames.contains(cn.getPackageName())) {
- cns.add(cn);
- }
- }
- } else if (tag instanceof LauncherAppWidgetInfo) {
- LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag;
- ComponentName cn = info.providerName;
- if ((cn != null) && packageNames.contains(cn.getPackageName())) {
- cns.add(cn);
- }
- }
+ infos.add((ItemInfo) view.getTag());
}
}
+ LauncherModel.ItemInfoFilter filter = new LauncherModel.ItemInfoFilter() {
+ @Override
+ public boolean filterItem(ItemInfo parent, ItemInfo info,
+ ComponentName cn) {
+ if (packageNames.contains(cn.getPackageName())) {
+ cns.add(cn);
+ return true;
+ }
+ return false;
+ }
+ };
+ LauncherModel.filterItemInfos(infos, filter);
- // Remove all the things
+ // Remove the affected components
removeItemsByComponentName(cns);
}
@@ -3801,81 +3810,70 @@ public class Workspace extends SmoothPagedView
for (final CellLayout layoutParent: cellLayouts) {
final ViewGroup layout = layoutParent.getShortcutsAndWidgets();
- // Avoid ANRs by treating each screen separately
- post(new Runnable() {
- public void run() {
- final ArrayList<View> childrenToRemove = new ArrayList<View>();
- childrenToRemove.clear();
-
- int childCount = layout.getChildCount();
- for (int j = 0; j < childCount; j++) {
- final View view = layout.getChildAt(j);
- Object tag = view.getTag();
-
- if (tag instanceof ShortcutInfo) {
- final ShortcutInfo info = (ShortcutInfo) tag;
- final Intent intent = info.intent;
- final ComponentName name = intent.getComponent();
-
- if (name != null) {
- if (componentNames.contains(name)) {
- LauncherModel.deleteItemFromDatabase(mLauncher, info);
- childrenToRemove.add(view);
- }
- }
- } else if (tag instanceof FolderInfo) {
- final FolderInfo info = (FolderInfo) tag;
- final ArrayList<ShortcutInfo> contents = info.contents;
- final int contentsCount = contents.size();
- final ArrayList<ShortcutInfo> appsToRemoveFromFolder =
- new ArrayList<ShortcutInfo>();
-
- for (int k = 0; k < contentsCount; k++) {
- final ShortcutInfo appInfo = contents.get(k);
- final Intent intent = appInfo.intent;
- final ComponentName name = intent.getComponent();
-
- if (name != null) {
- if (componentNames.contains(name)) {
- appsToRemoveFromFolder.add(appInfo);
- }
- }
- }
- for (ShortcutInfo item: appsToRemoveFromFolder) {
- info.remove(item);
- LauncherModel.deleteItemFromDatabase(mLauncher, item);
- }
- } else if (tag instanceof LauncherAppWidgetInfo) {
- final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag;
- final ComponentName provider = info.providerName;
- if (provider != null) {
- if (componentNames.contains(provider)) {
- LauncherModel.deleteItemFromDatabase(mLauncher, info);
- childrenToRemove.add(view);
- }
+ final HashMap<ItemInfo, View> children = new HashMap<ItemInfo, View>();
+ for (int j = 0; j < layout.getChildCount(); j++) {
+ final View view = layout.getChildAt(j);
+ children.put((ItemInfo) view.getTag(), view);
+ }
+
+ final ArrayList<View> childrenToRemove = new ArrayList<View>();
+ final HashMap<FolderInfo, ArrayList<ShortcutInfo>> folderAppsToRemove =
+ new HashMap<FolderInfo, ArrayList<ShortcutInfo>>();
+ LauncherModel.ItemInfoFilter filter = new LauncherModel.ItemInfoFilter() {
+ @Override
+ public boolean filterItem(ItemInfo parent, ItemInfo info,
+ ComponentName cn) {
+ if (parent instanceof FolderInfo) {
+ if (componentNames.contains(cn)) {
+ FolderInfo folder = (FolderInfo) parent;
+ ArrayList<ShortcutInfo> appsToRemove;
+ if (folderAppsToRemove.containsKey(folder)) {
+ appsToRemove = folderAppsToRemove.get(folder);
+ } else {
+ appsToRemove = new ArrayList<ShortcutInfo>();
+ folderAppsToRemove.put(folder, appsToRemove);
}
+ appsToRemove.add((ShortcutInfo) info);
+ return true;
}
- }
-
- childCount = childrenToRemove.size();
- for (int j = 0; j < childCount; j++) {
- View child = childrenToRemove.get(j);
- // Note: We can not remove the view directly from CellLayoutChildren as this
- // does not re-mark the spaces as unoccupied.
- layoutParent.removeViewInLayout(child);
- if (child instanceof DropTarget) {
- mDragController.removeDropTarget((DropTarget)child);
+ } else {
+ if (componentNames.contains(cn)) {
+ childrenToRemove.add(children.get(info));
+ return true;
}
}
+ return false;
+ }
+ };
+ LauncherModel.filterItemInfos(children.keySet(), filter);
- if (childCount > 0) {
- layout.requestLayout();
- layout.invalidate();
- }
+ // Remove all the apps from their folders
+ for (FolderInfo folder : folderAppsToRemove.keySet()) {
+ ArrayList<ShortcutInfo> appsToRemove = folderAppsToRemove.get(folder);
+ for (ShortcutInfo info : appsToRemove) {
+ folder.remove(info);
+ }
+ }
+
+ // Remove all the other children
+ for (View child : childrenToRemove) {
+ // Note: We can not remove the view directly from CellLayoutChildren as this
+ // does not re-mark the spaces as unoccupied.
+ layoutParent.removeViewInLayout(child);
+ if (child instanceof DropTarget) {
+ mDragController.removeDropTarget((DropTarget) child);
}
- });
+ }
+
+ if (childrenToRemove.size() > 0) {
+ layout.requestLayout();
+ layout.invalidate();
+ }
}
+ // Strip all the empty screens
+ stripEmptyScreens();
+
// Clean up new-apps animation list
final Context context = getContext();
post(new Runnable() {
@@ -3897,15 +3895,6 @@ public class Workspace extends SmoothPagedView
if (componentNames.contains(intent.getComponent())) {
iter.remove();
}
-
- // It is possible that we've queued an item to be loaded, yet it has
- // not been added to the workspace, so remove those items as well.
- ArrayList<ItemInfo> shortcuts;
- shortcuts = LauncherModel.getWorkspaceShortcutItemInfosWithIntent(
- intent);
- for (ItemInfo info : shortcuts) {
- LauncherModel.deleteItemFromDatabase(context, info);
- }
} catch (URISyntaxException e) {}
}
}
@@ -3921,24 +3910,20 @@ public class Workspace extends SmoothPagedView
for (int j = 0; j < childCount; j++) {
final View view = layout.getChildAt(j);
Object tag = view.getTag();
- if (tag instanceof ShortcutInfo) {
+
+ if (LauncherModel.isShortcutInfoUpdateable((ItemInfo) tag)) {
ShortcutInfo info = (ShortcutInfo) tag;
- // We need to check for ACTION_MAIN otherwise getComponent() might
- // return null for some shortcuts (for instance, for shortcuts to
- // web pages.)
+
final Intent intent = info.intent;
final ComponentName name = intent.getComponent();
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
- Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
- final int appCount = apps.size();
- for (int k = 0; k < appCount; k++) {
- ApplicationInfo app = apps.get(k);
- if (app.componentName.equals(name)) {
- BubbleTextView shortcut = (BubbleTextView) view;
- info.updateIcon(mIconCache);
- info.title = app.title.toString();
- shortcut.applyFromShortcutInfo(info, mIconCache);
- }
+ final int appCount = apps.size();
+ for (int k = 0; k < appCount; k++) {
+ ApplicationInfo app = apps.get(k);
+ if (app.componentName.equals(name)) {
+ BubbleTextView shortcut = (BubbleTextView) view;
+ info.updateIcon(mIconCache);
+ info.title = app.title.toString();
+ shortcut.applyFromShortcutInfo(info, mIconCache);
}
}
}
@@ -3954,7 +3939,10 @@ public class Workspace extends SmoothPagedView
setCurrentPage(mDefaultPage);
}
}
- getChildAt(mDefaultPage).requestFocus();
+ View child = getChildAt(mDefaultPage);
+ if (child != null) {
+ child.requestFocus();
+ }
}
@Override