Fixing slow binding when returning to Launcher
Bug: 8978842 Bug: 8660324 Change-Id: Idfa37c05ed299faa465ea66de4b43d30da77ecbc
This commit is contained in:
@@ -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<Object> widgetsAndShortcuts) {
|
||||
// Get the list of widgets and shortcuts
|
||||
mWidgets.clear();
|
||||
List<AppWidgetProviderInfo> widgets =
|
||||
AppWidgetManager.getInstance(mLauncher).getInstalledProviders();
|
||||
Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
|
||||
List<ResolveInfo> 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);
|
||||
}
|
||||
}
|
||||
mWidgets.addAll(shortcuts);
|
||||
Collections.sort(mWidgets,
|
||||
new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager));
|
||||
updatePageCounts();
|
||||
invalidateOnDataChange();
|
||||
updatePageCountsAndInvalidateData();
|
||||
}
|
||||
|
||||
public void setBulkBind(boolean bulkBind) {
|
||||
if (bulkBind) {
|
||||
mInBulkBind = true;
|
||||
} else {
|
||||
mInBulkBind = false;
|
||||
if (mNeedToUpdatePageCountsAndInvalidateData) {
|
||||
updatePageCountsAndInvalidateData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<ApplicationInfo> list) {
|
||||
mApps = list;
|
||||
Collections.sort(mApps, LauncherModel.getAppNameComparator());
|
||||
updatePageCounts();
|
||||
invalidateOnDataChange();
|
||||
updatePageCountsAndInvalidateData();
|
||||
}
|
||||
private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
|
||||
// We add it in place, in alphabetical order
|
||||
@@ -1542,8 +1563,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
|
||||
}
|
||||
public void addApps(ArrayList<ApplicationInfo> list) {
|
||||
addAppsWithoutInvalidate(list);
|
||||
updatePageCounts();
|
||||
invalidateOnDataChange();
|
||||
updatePageCountsAndInvalidateData();
|
||||
}
|
||||
private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) {
|
||||
ComponentName removeComponent = item.intent.getComponent();
|
||||
@@ -1569,8 +1589,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
|
||||
}
|
||||
public void removeApps(ArrayList<ApplicationInfo> appInfos) {
|
||||
removeAppsWithoutInvalidate(appInfos);
|
||||
updatePageCounts();
|
||||
invalidateOnDataChange();
|
||||
updatePageCountsAndInvalidateData();
|
||||
}
|
||||
public void updateApps(ArrayList<ApplicationInfo> 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() {
|
||||
|
||||
@@ -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<Object> mWidgetsAndShortcuts;
|
||||
private Runnable mBindPackagesUpdatedRunnable = new Runnable() {
|
||||
public void run() {
|
||||
bindPackagesUpdated();
|
||||
bindPackagesUpdated(mWidgetsAndShortcuts);
|
||||
mWidgetsAndShortcuts = null;
|
||||
}
|
||||
})) {
|
||||
};
|
||||
|
||||
public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {
|
||||
if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {
|
||||
mWidgetsAndShortcuts = widgetsAndShortcuts;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mAppsCustomizeContent != null) {
|
||||
mAppsCustomizeContent.onPackagesUpdated();
|
||||
mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
public void bindComponentsRemoved(ArrayList<String> packageNames,
|
||||
ArrayList<ApplicationInfo> appInfos,
|
||||
boolean matchPackageNamesOnly);
|
||||
public void bindPackagesUpdated();
|
||||
public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
|
||||
public boolean isAllAppsVisible();
|
||||
public boolean isAllAppsButtonRank(int rank);
|
||||
public void bindSearchablesChanged();
|
||||
@@ -2105,18 +2105,32 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
});
|
||||
}
|
||||
|
||||
final ArrayList<Object> 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<Object> getSortedWidgetsAndShortcuts(Context context) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
final ArrayList<Object> widgetsAndShortcuts = new ArrayList<Object>();
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user