From c402cd9992d431b6beacdf3c75e31cf103e230cb Mon Sep 17 00:00:00 2001 From: Michael Jurka Date: Mon, 20 May 2013 15:49:32 +0200 Subject: Fixing slow binding when returning to Launcher Bug: 8978842 Bug: 8660324 Change-Id: Idfa37c05ed299faa465ea66de4b43d30da77ecbc --- .../android/launcher2/AppsCustomizePagedView.java | 82 +++++++++++++--------- src/com/android/launcher2/Launcher.java | 66 +++++++++++------ .../android/launcher2/LauncherAppWidgetHost.java | 2 +- src/com/android/launcher2/LauncherModel.java | 18 ++++- 4 files changed, 112 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java index 901b661db..95ce33752 100644 --- a/src/com/android/launcher2/AppsCustomizePagedView.java +++ b/src/com/android/launcher2/AppsCustomizePagedView.java @@ -240,6 +240,9 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen WidgetPreviewLoader mWidgetPreviewLoader; + private boolean mInBulkBind; + private boolean mNeedToUpdatePageCountsAndInvalidateData; + public AppsCustomizePagedView(Context context, AttributeSet attrs) { super(context, attrs); mLayoutInflater = LayoutInflater.from(context); @@ -440,38 +443,57 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen super.onMeasure(widthMeasureSpec, heightMeasureSpec); } - public void onPackagesUpdated() { + public void onPackagesUpdated(ArrayList widgetsAndShortcuts) { // Get the list of widgets and shortcuts mWidgets.clear(); - List widgets = - AppWidgetManager.getInstance(mLauncher).getInstalledProviders(); - Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); - List shortcuts = mPackageManager.queryIntentActivities(shortcutsIntent, 0); - for (AppWidgetProviderInfo widget : widgets) { - widget.label = widget.label.trim(); - if (widget.minWidth > 0 && widget.minHeight > 0) { - // Ensure that all widgets we show can be added on a workspace of this size - int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget); - int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget); - int minSpanX = Math.min(spanXY[0], minSpanXY[0]); - int minSpanY = Math.min(spanXY[1], minSpanXY[1]); - if (minSpanX <= LauncherModel.getCellCountX() && + for (Object o : widgetsAndShortcuts) { + if (o instanceof AppWidgetProviderInfo) { + AppWidgetProviderInfo widget = (AppWidgetProviderInfo) o; + widget.label = widget.label.trim(); + if (widget.minWidth > 0 && widget.minHeight > 0) { + // Ensure that all widgets we show can be added on a workspace of this size + int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget); + int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget); + int minSpanX = Math.min(spanXY[0], minSpanXY[0]); + int minSpanY = Math.min(spanXY[1], minSpanXY[1]); + if (minSpanX <= LauncherModel.getCellCountX() && minSpanY <= LauncherModel.getCellCountY()) { - mWidgets.add(widget); + mWidgets.add(widget); + } else { + Log.e(TAG, "Widget " + widget.provider + " can not fit on this device (" + + widget.minWidth + ", " + widget.minHeight + ")"); + } } else { - Log.e(TAG, "Widget " + widget.provider + " can not fit on this device (" + - widget.minWidth + ", " + widget.minHeight + ")"); + Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" + + widget.minWidth + ", " + widget.minHeight + ")"); } } else { - Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" + - widget.minWidth + ", " + widget.minHeight + ")"); + // just add shortcuts + mWidgets.add(o); + } + } + updatePageCountsAndInvalidateData(); + } + + public void setBulkBind(boolean bulkBind) { + if (bulkBind) { + mInBulkBind = true; + } else { + mInBulkBind = false; + if (mNeedToUpdatePageCountsAndInvalidateData) { + updatePageCountsAndInvalidateData(); } } - mWidgets.addAll(shortcuts); - Collections.sort(mWidgets, - new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager)); - updatePageCounts(); - invalidateOnDataChange(); + } + + private void updatePageCountsAndInvalidateData() { + if (mInBulkBind) { + mNeedToUpdatePageCountsAndInvalidateData = true; + } else { + updatePageCounts(); + invalidateOnDataChange(); + mNeedToUpdatePageCountsAndInvalidateData = false; + } } @Override @@ -1526,8 +1548,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen public void setApps(ArrayList list) { mApps = list; Collections.sort(mApps, LauncherModel.getAppNameComparator()); - updatePageCounts(); - invalidateOnDataChange(); + updatePageCountsAndInvalidateData(); } private void addAppsWithoutInvalidate(ArrayList list) { // We add it in place, in alphabetical order @@ -1542,8 +1563,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen } public void addApps(ArrayList list) { addAppsWithoutInvalidate(list); - updatePageCounts(); - invalidateOnDataChange(); + updatePageCountsAndInvalidateData(); } private int findAppByComponent(List list, ApplicationInfo item) { ComponentName removeComponent = item.intent.getComponent(); @@ -1569,8 +1589,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen } public void removeApps(ArrayList appInfos) { removeAppsWithoutInvalidate(appInfos); - updatePageCounts(); - invalidateOnDataChange(); + updatePageCountsAndInvalidateData(); } public void updateApps(ArrayList list) { // We remove and re-add the updated applications list because it's properties may have @@ -1578,8 +1597,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen // place in the list. removeAppsWithoutInvalidate(list); addAppsWithoutInvalidate(list); - updatePageCounts(); - invalidateOnDataChange(); + updatePageCountsAndInvalidateData(); } public void reset() { diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 473a3d158..94a0bca26 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -126,7 +126,7 @@ public final class Launcher extends Activity static final boolean PROFILE_STARTUP = false; static final boolean DEBUG_WIDGETS = false; static final boolean DEBUG_STRICT_MODE = false; - static final boolean DEBUG_RESUME_TIME = true; + static final boolean DEBUG_RESUME_TIME = false; private static final int MENU_GROUP_WALLPAPER = 1; private static final int MENU_WALLPAPER_SETTINGS = Menu.FIRST + 1; @@ -392,7 +392,8 @@ public final class Launcher extends Activity // Update customization drawer _after_ restoring the states if (mAppsCustomizeContent != null) { - mAppsCustomizeContent.onPackagesUpdated(); + mAppsCustomizeContent.onPackagesUpdated( + LauncherModel.getSortedWidgetsAndShortcuts(this)); } if (PROFILE_STARTUP) { @@ -759,19 +760,28 @@ public final class Launcher extends Activity mRestoring = false; mOnResumeNeedsLoad = false; } - // We might have postponed some bind calls until onResume (see waitUntilResume) -- - // execute them here - long startTimeCallbacks = 0; - if (DEBUG_RESUME_TIME) { - startTimeCallbacks = System.currentTimeMillis(); - } - for (int i = 0; i < mOnResumeCallbacks.size(); i++) { - mOnResumeCallbacks.get(i).run(); - } - mOnResumeCallbacks.clear(); - if (DEBUG_RESUME_TIME) { - Log.d(TAG, "Time spent processing callbacks in onResume: " + - (System.currentTimeMillis() - startTimeCallbacks)); + if (mOnResumeCallbacks.size() > 0) { + // We might have postponed some bind calls until onResume (see waitUntilResume) -- + // execute them here + long startTimeCallbacks = 0; + if (DEBUG_RESUME_TIME) { + startTimeCallbacks = System.currentTimeMillis(); + } + + if (mAppsCustomizeContent != null) { + mAppsCustomizeContent.setBulkBind(true); + } + for (int i = 0; i < mOnResumeCallbacks.size(); i++) { + mOnResumeCallbacks.get(i).run(); + } + if (mAppsCustomizeContent != null) { + mAppsCustomizeContent.setBulkBind(false); + } + mOnResumeCallbacks.clear(); + if (DEBUG_RESUME_TIME) { + Log.d(TAG, "Time spent processing callbacks in onResume: " + + (System.currentTimeMillis() - startTimeCallbacks)); + } } // Reset the pressed state of icons that were locked in the press state while activities @@ -3308,9 +3318,13 @@ public final class Launcher extends Activity * @return true if we are currently paused. The caller might be able to * skip some work in that case since we will come back again. */ - private boolean waitUntilResume(Runnable run) { + private boolean waitUntilResume(Runnable run, boolean deletePreviousRunnables) { if (mPaused) { Log.i(TAG, "Deferring update until onResume"); + if (deletePreviousRunnables) { + while (mOnResumeCallbacks.remove(run)) { + } + } mOnResumeCallbacks.add(run); return true; } else { @@ -3318,6 +3332,10 @@ public final class Launcher extends Activity } } + private boolean waitUntilResume(Runnable run) { + return waitUntilResume(run, false); + } + /** * If the activity is currently paused, signal that we need to re-run the loader * in onResume. @@ -3761,17 +3779,23 @@ public final class Launcher extends Activity /** * A number of packages were updated. */ - public void bindPackagesUpdated() { - if (waitUntilResume(new Runnable() { + + private ArrayList mWidgetsAndShortcuts; + private Runnable mBindPackagesUpdatedRunnable = new Runnable() { public void run() { - bindPackagesUpdated(); + bindPackagesUpdated(mWidgetsAndShortcuts); + mWidgetsAndShortcuts = null; } - })) { + }; + + public void bindPackagesUpdated(final ArrayList widgetsAndShortcuts) { + if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) { + mWidgetsAndShortcuts = widgetsAndShortcuts; return; } if (mAppsCustomizeContent != null) { - mAppsCustomizeContent.onPackagesUpdated(); + mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts); } } diff --git a/src/com/android/launcher2/LauncherAppWidgetHost.java b/src/com/android/launcher2/LauncherAppWidgetHost.java index 45c1d2311..4d52ea864 100644 --- a/src/com/android/launcher2/LauncherAppWidgetHost.java +++ b/src/com/android/launcher2/LauncherAppWidgetHost.java @@ -50,6 +50,6 @@ public class LauncherAppWidgetHost extends AppWidgetHost { protected void onProvidersChanged() { // Once we get the message that widget packages are updated, we need to rebind items // in AppsCustomize accordingly. - mLauncher.bindPackagesUpdated(); + mLauncher.bindPackagesUpdated(LauncherModel.getSortedWidgetsAndShortcuts(mLauncher)); } } diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 99ebd962e..1d562beae 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -161,7 +161,7 @@ public class LauncherModel extends BroadcastReceiver { public void bindComponentsRemoved(ArrayList packageNames, ArrayList appInfos, boolean matchPackageNamesOnly); - public void bindPackagesUpdated(); + public void bindPackagesUpdated(ArrayList widgetsAndShortcuts); public boolean isAllAppsVisible(); public boolean isAllAppsButtonRank(int rank); public void bindSearchablesChanged(); @@ -2105,18 +2105,32 @@ public class LauncherModel extends BroadcastReceiver { }); } + final ArrayList widgetsAndShortcuts = + getSortedWidgetsAndShortcuts(context); mHandler.post(new Runnable() { @Override public void run() { Callbacks cb = mCallbacks != null ? mCallbacks.get() : null; if (callbacks == cb && cb != null) { - callbacks.bindPackagesUpdated(); + callbacks.bindPackagesUpdated(widgetsAndShortcuts); } } }); } } + // Returns a list of ResolveInfos/AppWindowInfos in sorted order + public static ArrayList getSortedWidgetsAndShortcuts(Context context) { + PackageManager packageManager = context.getPackageManager(); + final ArrayList widgetsAndShortcuts = new ArrayList(); + widgetsAndShortcuts.addAll(AppWidgetManager.getInstance(context).getInstalledProviders()); + Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); + widgetsAndShortcuts.addAll(packageManager.queryIntentActivities(shortcutsIntent, 0)); + Collections.sort(widgetsAndShortcuts, + new LauncherModel.WidgetAndShortcutNameComparator(packageManager)); + return widgetsAndShortcuts; + } + /** * This is called from the code that adds shortcuts from the intent receiver. This * doesn't have a Cursor, but -- cgit v1.2.3