diff options
author | Hyunyoung Song <hyunyoungs@google.com> | 2015-05-21 13:04:53 -0700 |
---|---|---|
committer | Hyunyoung Song <hyunyoungs@google.com> | 2015-05-21 13:04:53 -0700 |
commit | 2bd3d7d1cb5e4d8d826982d11b456739fed6b817 (patch) | |
tree | 4e0ecf47c9b3ced1116d896b3b9e8487792201fb /src/com/android/launcher3/model | |
parent | 3e4d5f20ba9128fcbe77b220380129be773887b3 (diff) | |
download | android_packages_apps_Trebuchet-2bd3d7d1cb5e4d8d826982d11b456739fed6b817.tar.gz android_packages_apps_Trebuchet-2bd3d7d1cb5e4d8d826982d11b456739fed6b817.tar.bz2 android_packages_apps_Trebuchet-2bd3d7d1cb5e4d8d826982d11b456739fed6b817.zip |
Load PackageItemInfo in background thread to prevent ANR
- Decoupled widget model from widget view, and placed the
creation to LauncherModel.
- As a result packagemanager operation, iconcache retrieval is all done inside
LauncherModel on background thread
b/21311085
b/21325319
Change-Id: I294698527db58b89f3da558090a367530c058776
Diffstat (limited to 'src/com/android/launcher3/model')
-rw-r--r-- | src/com/android/launcher3/model/PackageItemInfo.java | 58 | ||||
-rw-r--r-- | src/com/android/launcher3/model/WidgetsModel.java | 125 |
2 files changed, 183 insertions, 0 deletions
diff --git a/src/com/android/launcher3/model/PackageItemInfo.java b/src/com/android/launcher3/model/PackageItemInfo.java new file mode 100644 index 000000000..0f0134ae3 --- /dev/null +++ b/src/com/android/launcher3/model/PackageItemInfo.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.model; + +import android.content.ComponentName; +import android.graphics.Bitmap; + +import com.android.launcher3.ItemInfo; + +import java.util.Arrays; + +/** + * Represents a {@link Package} in the widget tray section. + */ +public class PackageItemInfo extends ItemInfo { + private static final String TAG = "PackageInfo"; + + /** + * A bitmap version of the application icon. + */ + public Bitmap iconBitmap; + + /** + * Indicates whether we're using a low res icon + */ + public boolean usingLowResIcon; + + public String packageName; + + int flags = 0; + + PackageItemInfo(String packageName) { + this.packageName = packageName; + } + + @Override + public String toString() { + return "PackageItemInfo(title=" + title + " id=" + this.id + + " type=" + this.itemType + " container=" + this.container + + " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY + + " spanX=" + spanX + " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos) + + " user=" + user + ")"; + } +} diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java new file mode 100644 index 000000000..b72b98126 --- /dev/null +++ b/src/com/android/launcher3/model/WidgetsModel.java @@ -0,0 +1,125 @@ + +package com.android.launcher3.model; + +import android.content.Context; +import android.content.pm.ResolveInfo; +import android.os.Handler; +import android.os.Process; +import android.util.Log; + +import com.android.launcher3.IconCache; +import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherAppWidgetProviderInfo; + +import com.android.launcher3.LauncherModel; +import com.android.launcher3.Utilities; +import com.android.launcher3.compat.UserHandleCompat; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Widgets data model that is used by the adapters of the widget views and controllers. + * + * <p> The widgets and shortcuts are organized using package name as its index. + */ +public class WidgetsModel { + + private static final String TAG = "WidgetsModel"; + private static final boolean DEBUG = false; + + /* List of packages that is tracked by this model. */ + private List<PackageItemInfo> mPackageItemInfos = new ArrayList<>(); + + /* Map of widgets and shortcuts that are tracked per package. */ + private Map<PackageItemInfo, ArrayList<Object>> mWidgetsList = new HashMap<>(); + + private ArrayList<Object> mRawList; + + private final Comparator mWidgetAndShortcutNameComparator; + private final Comparator mAppNameComparator; + + private final IconCache mIconCache; + private final Handler mWorkerHandler; + + public WidgetsModel(Context context) { + mWidgetAndShortcutNameComparator = new WidgetsAndShortcutNameComparator(context); + mAppNameComparator = (new AppNameComparator(context)).getAppInfoComparator(); + mIconCache = LauncherAppState.getInstance().getIconCache(); + mWorkerHandler = new Handler(LauncherModel.getWorkerLooper()); + } + + // Access methods that may be deleted if the private fields are made package-private. + public int getPackageSize() { + return mPackageItemInfos.size(); + } + + // Access methods that may be deleted if the private fields are made package-private. + public PackageItemInfo getPackageItemInfo(int pos) { + return mPackageItemInfos.get(pos); + } + + public List<Object> getSortedWidgets(int pos) { + return mWidgetsList.get(mPackageItemInfos.get(pos)); + } + + public ArrayList<Object> getRawList() { + return mRawList; + } + + public void addWidgetsAndShortcuts(ArrayList<Object> rawWidgetsShortcuts) { + Utilities.assertWorkerThread(); + mRawList = rawWidgetsShortcuts; + if (DEBUG) { + Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size()); + } + + // Temporary list for {@link PackageItemInfos} to avoid having to go through + // {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList} + HashMap<String, PackageItemInfo> tmpPackageItemInfos = new HashMap<>(); + + // clear the lists. + mWidgetsList.clear(); + mPackageItemInfos.clear(); + + // add and update. + for (Object o: rawWidgetsShortcuts) { + String packageName = ""; + if (o instanceof LauncherAppWidgetProviderInfo) { + LauncherAppWidgetProviderInfo widgetInfo = (LauncherAppWidgetProviderInfo) o; + packageName = widgetInfo.provider.getPackageName(); + } else if (o instanceof ResolveInfo) { + ResolveInfo resolveInfo = (ResolveInfo) o; + packageName = resolveInfo.activityInfo.packageName; + } else { + Log.e(TAG, String.format("addWidgetsAndShortcuts, nothing added for class=%s", + o.getClass().toString())); + } + + PackageItemInfo pInfo = tmpPackageItemInfos.get(packageName); + ArrayList<Object> widgetsShortcutsList = mWidgetsList.get(pInfo); + if (widgetsShortcutsList != null) { + widgetsShortcutsList.add(o); + } else { + widgetsShortcutsList = new ArrayList<Object>(); + widgetsShortcutsList.add(o); + pInfo = new PackageItemInfo(packageName); + mIconCache.getTitleAndIconForApp(packageName, UserHandleCompat.myUserHandle(), + true /* userLowResIcon */, pInfo); + mWidgetsList.put(pInfo, widgetsShortcutsList); + tmpPackageItemInfos.put(packageName, pInfo); + mPackageItemInfos.add(pInfo); + } + } + + // sort. + Collections.sort(mPackageItemInfos, mAppNameComparator); + for (PackageItemInfo p: mPackageItemInfos) { + Collections.sort(mWidgetsList.get(p), mWidgetAndShortcutNameComparator); + } + } +}
\ No newline at end of file |