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;
|
WidgetPreviewLoader mWidgetPreviewLoader;
|
||||||
|
|
||||||
|
private boolean mInBulkBind;
|
||||||
|
private boolean mNeedToUpdatePageCountsAndInvalidateData;
|
||||||
|
|
||||||
public AppsCustomizePagedView(Context context, AttributeSet attrs) {
|
public AppsCustomizePagedView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
mLayoutInflater = LayoutInflater.from(context);
|
mLayoutInflater = LayoutInflater.from(context);
|
||||||
@@ -440,38 +443,57 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
|
|||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPackagesUpdated() {
|
public void onPackagesUpdated(ArrayList<Object> widgetsAndShortcuts) {
|
||||||
// Get the list of widgets and shortcuts
|
// Get the list of widgets and shortcuts
|
||||||
mWidgets.clear();
|
mWidgets.clear();
|
||||||
List<AppWidgetProviderInfo> widgets =
|
for (Object o : widgetsAndShortcuts) {
|
||||||
AppWidgetManager.getInstance(mLauncher).getInstalledProviders();
|
if (o instanceof AppWidgetProviderInfo) {
|
||||||
Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
|
AppWidgetProviderInfo widget = (AppWidgetProviderInfo) o;
|
||||||
List<ResolveInfo> shortcuts = mPackageManager.queryIntentActivities(shortcutsIntent, 0);
|
widget.label = widget.label.trim();
|
||||||
for (AppWidgetProviderInfo widget : widgets) {
|
if (widget.minWidth > 0 && widget.minHeight > 0) {
|
||||||
widget.label = widget.label.trim();
|
// Ensure that all widgets we show can be added on a workspace of this size
|
||||||
if (widget.minWidth > 0 && widget.minHeight > 0) {
|
int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget);
|
||||||
// Ensure that all widgets we show can be added on a workspace of this size
|
int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget);
|
||||||
int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget);
|
int minSpanX = Math.min(spanXY[0], minSpanXY[0]);
|
||||||
int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget);
|
int minSpanY = Math.min(spanXY[1], minSpanXY[1]);
|
||||||
int minSpanX = Math.min(spanXY[0], minSpanXY[0]);
|
if (minSpanX <= LauncherModel.getCellCountX() &&
|
||||||
int minSpanY = Math.min(spanXY[1], minSpanXY[1]);
|
|
||||||
if (minSpanX <= LauncherModel.getCellCountX() &&
|
|
||||||
minSpanY <= LauncherModel.getCellCountY()) {
|
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 {
|
} else {
|
||||||
Log.e(TAG, "Widget " + widget.provider + " can not fit on this device (" +
|
Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" +
|
||||||
widget.minWidth + ", " + widget.minHeight + ")");
|
widget.minWidth + ", " + widget.minHeight + ")");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" +
|
// just add shortcuts
|
||||||
widget.minWidth + ", " + widget.minHeight + ")");
|
mWidgets.add(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mWidgets.addAll(shortcuts);
|
updatePageCountsAndInvalidateData();
|
||||||
Collections.sort(mWidgets,
|
}
|
||||||
new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager));
|
|
||||||
updatePageCounts();
|
public void setBulkBind(boolean bulkBind) {
|
||||||
invalidateOnDataChange();
|
if (bulkBind) {
|
||||||
|
mInBulkBind = true;
|
||||||
|
} else {
|
||||||
|
mInBulkBind = false;
|
||||||
|
if (mNeedToUpdatePageCountsAndInvalidateData) {
|
||||||
|
updatePageCountsAndInvalidateData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePageCountsAndInvalidateData() {
|
||||||
|
if (mInBulkBind) {
|
||||||
|
mNeedToUpdatePageCountsAndInvalidateData = true;
|
||||||
|
} else {
|
||||||
|
updatePageCounts();
|
||||||
|
invalidateOnDataChange();
|
||||||
|
mNeedToUpdatePageCountsAndInvalidateData = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1526,8 +1548,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
|
|||||||
public void setApps(ArrayList<ApplicationInfo> list) {
|
public void setApps(ArrayList<ApplicationInfo> list) {
|
||||||
mApps = list;
|
mApps = list;
|
||||||
Collections.sort(mApps, LauncherModel.getAppNameComparator());
|
Collections.sort(mApps, LauncherModel.getAppNameComparator());
|
||||||
updatePageCounts();
|
updatePageCountsAndInvalidateData();
|
||||||
invalidateOnDataChange();
|
|
||||||
}
|
}
|
||||||
private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
|
private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
|
||||||
// We add it in place, in alphabetical order
|
// We add it in place, in alphabetical order
|
||||||
@@ -1542,8 +1563,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
|
|||||||
}
|
}
|
||||||
public void addApps(ArrayList<ApplicationInfo> list) {
|
public void addApps(ArrayList<ApplicationInfo> list) {
|
||||||
addAppsWithoutInvalidate(list);
|
addAppsWithoutInvalidate(list);
|
||||||
updatePageCounts();
|
updatePageCountsAndInvalidateData();
|
||||||
invalidateOnDataChange();
|
|
||||||
}
|
}
|
||||||
private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) {
|
private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) {
|
||||||
ComponentName removeComponent = item.intent.getComponent();
|
ComponentName removeComponent = item.intent.getComponent();
|
||||||
@@ -1569,8 +1589,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
|
|||||||
}
|
}
|
||||||
public void removeApps(ArrayList<ApplicationInfo> appInfos) {
|
public void removeApps(ArrayList<ApplicationInfo> appInfos) {
|
||||||
removeAppsWithoutInvalidate(appInfos);
|
removeAppsWithoutInvalidate(appInfos);
|
||||||
updatePageCounts();
|
updatePageCountsAndInvalidateData();
|
||||||
invalidateOnDataChange();
|
|
||||||
}
|
}
|
||||||
public void updateApps(ArrayList<ApplicationInfo> list) {
|
public void updateApps(ArrayList<ApplicationInfo> list) {
|
||||||
// We remove and re-add the updated applications list because it's properties may have
|
// 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.
|
// place in the list.
|
||||||
removeAppsWithoutInvalidate(list);
|
removeAppsWithoutInvalidate(list);
|
||||||
addAppsWithoutInvalidate(list);
|
addAppsWithoutInvalidate(list);
|
||||||
updatePageCounts();
|
updatePageCountsAndInvalidateData();
|
||||||
invalidateOnDataChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public final class Launcher extends Activity
|
|||||||
static final boolean PROFILE_STARTUP = false;
|
static final boolean PROFILE_STARTUP = false;
|
||||||
static final boolean DEBUG_WIDGETS = false;
|
static final boolean DEBUG_WIDGETS = false;
|
||||||
static final boolean DEBUG_STRICT_MODE = 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_GROUP_WALLPAPER = 1;
|
||||||
private static final int MENU_WALLPAPER_SETTINGS = Menu.FIRST + 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
|
// Update customization drawer _after_ restoring the states
|
||||||
if (mAppsCustomizeContent != null) {
|
if (mAppsCustomizeContent != null) {
|
||||||
mAppsCustomizeContent.onPackagesUpdated();
|
mAppsCustomizeContent.onPackagesUpdated(
|
||||||
|
LauncherModel.getSortedWidgetsAndShortcuts(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PROFILE_STARTUP) {
|
if (PROFILE_STARTUP) {
|
||||||
@@ -759,19 +760,28 @@ public final class Launcher extends Activity
|
|||||||
mRestoring = false;
|
mRestoring = false;
|
||||||
mOnResumeNeedsLoad = false;
|
mOnResumeNeedsLoad = false;
|
||||||
}
|
}
|
||||||
// We might have postponed some bind calls until onResume (see waitUntilResume) --
|
if (mOnResumeCallbacks.size() > 0) {
|
||||||
// execute them here
|
// We might have postponed some bind calls until onResume (see waitUntilResume) --
|
||||||
long startTimeCallbacks = 0;
|
// execute them here
|
||||||
if (DEBUG_RESUME_TIME) {
|
long startTimeCallbacks = 0;
|
||||||
startTimeCallbacks = System.currentTimeMillis();
|
if (DEBUG_RESUME_TIME) {
|
||||||
}
|
startTimeCallbacks = System.currentTimeMillis();
|
||||||
for (int i = 0; i < mOnResumeCallbacks.size(); i++) {
|
}
|
||||||
mOnResumeCallbacks.get(i).run();
|
|
||||||
}
|
if (mAppsCustomizeContent != null) {
|
||||||
mOnResumeCallbacks.clear();
|
mAppsCustomizeContent.setBulkBind(true);
|
||||||
if (DEBUG_RESUME_TIME) {
|
}
|
||||||
Log.d(TAG, "Time spent processing callbacks in onResume: " +
|
for (int i = 0; i < mOnResumeCallbacks.size(); i++) {
|
||||||
(System.currentTimeMillis() - startTimeCallbacks));
|
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
|
// 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
|
* @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.
|
* 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) {
|
if (mPaused) {
|
||||||
Log.i(TAG, "Deferring update until onResume");
|
Log.i(TAG, "Deferring update until onResume");
|
||||||
|
if (deletePreviousRunnables) {
|
||||||
|
while (mOnResumeCallbacks.remove(run)) {
|
||||||
|
}
|
||||||
|
}
|
||||||
mOnResumeCallbacks.add(run);
|
mOnResumeCallbacks.add(run);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} 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
|
* If the activity is currently paused, signal that we need to re-run the loader
|
||||||
* in onResume.
|
* in onResume.
|
||||||
@@ -3761,17 +3779,23 @@ public final class Launcher extends Activity
|
|||||||
/**
|
/**
|
||||||
* A number of packages were updated.
|
* 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() {
|
public void run() {
|
||||||
bindPackagesUpdated();
|
bindPackagesUpdated(mWidgetsAndShortcuts);
|
||||||
|
mWidgetsAndShortcuts = null;
|
||||||
}
|
}
|
||||||
})) {
|
};
|
||||||
|
|
||||||
|
public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {
|
||||||
|
if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {
|
||||||
|
mWidgetsAndShortcuts = widgetsAndShortcuts;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mAppsCustomizeContent != null) {
|
if (mAppsCustomizeContent != null) {
|
||||||
mAppsCustomizeContent.onPackagesUpdated();
|
mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,6 @@ public class LauncherAppWidgetHost extends AppWidgetHost {
|
|||||||
protected void onProvidersChanged() {
|
protected void onProvidersChanged() {
|
||||||
// Once we get the message that widget packages are updated, we need to rebind items
|
// Once we get the message that widget packages are updated, we need to rebind items
|
||||||
// in AppsCustomize accordingly.
|
// 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,
|
public void bindComponentsRemoved(ArrayList<String> packageNames,
|
||||||
ArrayList<ApplicationInfo> appInfos,
|
ArrayList<ApplicationInfo> appInfos,
|
||||||
boolean matchPackageNamesOnly);
|
boolean matchPackageNamesOnly);
|
||||||
public void bindPackagesUpdated();
|
public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
|
||||||
public boolean isAllAppsVisible();
|
public boolean isAllAppsVisible();
|
||||||
public boolean isAllAppsButtonRank(int rank);
|
public boolean isAllAppsButtonRank(int rank);
|
||||||
public void bindSearchablesChanged();
|
public void bindSearchablesChanged();
|
||||||
@@ -2105,18 +2105,32 @@ public class LauncherModel extends BroadcastReceiver {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final ArrayList<Object> widgetsAndShortcuts =
|
||||||
|
getSortedWidgetsAndShortcuts(context);
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
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.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
|
* This is called from the code that adds shortcuts from the intent receiver. This
|
||||||
* doesn't have a Cursor, but
|
* doesn't have a Cursor, but
|
||||||
|
|||||||
Reference in New Issue
Block a user