Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4ddc4013 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Creating WidgetCellItem to wrap LauncherAppWidgetProviderInfo and resolveInfo

In PackageItemInfo,, using the user of the first item in the sub-list

Bug: 27585511
Change-Id: I8243f0e5c831af65661ae815489e53e9fcade837
parent 1bc8fc3d
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -410,7 +410,7 @@ public class IconCache {
                            st.user, false);
                } else if (info instanceof PackageItemInfo) {
                    PackageItemInfo pti = (PackageItemInfo) info;
                    getTitleAndIconForApp(pti.packageName, pti.user, false, pti);
                    getTitleAndIconForApp(pti, false);
                }
                mMainThreadExecutor.execute(new Runnable() {

@@ -507,16 +507,16 @@ public class IconCache {
    }

    /**
     * Fill in {@param appInfo} with the icon and label for {@param packageName}
     * Fill in {@param infoInOut} with the corresponding icon and label.
     */
    public synchronized void getTitleAndIconForApp(
            String packageName, UserHandleCompat user, boolean useLowResIcon,
            PackageItemInfo infoOut) {
        CacheEntry entry = getEntryForPackageLocked(packageName, user, useLowResIcon);
        infoOut.iconBitmap = getNonNullIcon(entry, user);
        infoOut.title = Utilities.trim(entry.title);
        infoOut.usingLowResIcon = entry.isLowResIcon;
        infoOut.contentDescription = entry.contentDescription;
            PackageItemInfo infoInOut, boolean useLowResIcon) {
        CacheEntry entry = getEntryForPackageLocked(
                infoInOut.packageName, infoInOut.user, useLowResIcon);
        infoInOut.iconBitmap = getNonNullIcon(entry, infoInOut.user);
        infoInOut.title = Utilities.trim(entry.title);
        infoInOut.usingLowResIcon = entry.isLowResIcon;
        infoInOut.contentDescription = entry.contentDescription;
    }

    public synchronized Bitmap getDefaultIcon(UserHandleCompat user) {
+21 −43
Original line number Diff line number Diff line
@@ -3,9 +3,10 @@ package com.android.launcher3;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
@@ -30,6 +31,7 @@ import android.util.LongSparseArray;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.SQLiteCacheHelper;
import com.android.launcher3.util.Thunk;
@@ -87,15 +89,14 @@ public class WidgetPreviewLoader {
     * Generates the widget preview on {@link AsyncTask#THREAD_POOL_EXECUTOR}. Must be
     * called on UI thread
     *
     * @param o either {@link LauncherAppWidgetProviderInfo} or {@link ResolveInfo}
     * @return a request id which can be used to cancel the request.
     */
    public PreviewLoadRequest getPreview(final Object o, int previewWidth,
    public PreviewLoadRequest getPreview(WidgetItem item, int previewWidth,
            int previewHeight, WidgetCell caller) {
        String size = previewWidth + "x" + previewHeight;
        WidgetCacheKey key = getObjectKey(o, size);
        WidgetCacheKey key = new WidgetCacheKey(item.componentName, item.user, size);

        PreviewLoadTask task = new PreviewLoadTask(key, o, previewWidth, previewHeight, caller);
        PreviewLoadTask task = new PreviewLoadTask(key, item, previewWidth, previewHeight, caller);
        task.executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR);
        return new PreviewLoadRequest(task);
    }
@@ -135,19 +136,6 @@ public class WidgetPreviewLoader {
        }
    }

    private WidgetCacheKey getObjectKey(Object o, String size) {
        // should cache the string builder
        if (o instanceof LauncherAppWidgetProviderInfo) {
            LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo) o;
            return new WidgetCacheKey(info.provider, mWidgetManager.getUser(info), size);
        } else {
            ResolveInfo info = (ResolveInfo) o;
            return new WidgetCacheKey(
                    new ComponentName(info.activityInfo.packageName, info.activityInfo.name),
                    UserHandleCompat.myUserHandle(), size);
        }
    }

    @Thunk void writeToDb(WidgetCacheKey key, long[] versions, Bitmap preview) {
        ContentValues values = new ContentValues();
        values.put(CacheDb.COLUMN_COMPONENT, key.componentName.flattenToShortString());
@@ -180,30 +168,19 @@ public class WidgetPreviewLoader {
     *   2. Any preview for an absent package is removed
     * This ensures that we remove entries for packages which changed while the launcher was dead.
     */
    public void removeObsoletePreviews(ArrayList<Object> list) {
    public void removeObsoletePreviews(ArrayList<? extends ComponentKey> list) {
        Utilities.assertWorkerThread();

        LongSparseArray<HashSet<String>> validPackages = new LongSparseArray<>();

        for (Object obj : list) {
            final UserHandleCompat user;
            final String pkg;
            if (obj instanceof ResolveInfo) {
                user = UserHandleCompat.myUserHandle();
                pkg = ((ResolveInfo) obj).activityInfo.packageName;
            } else {
                LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo) obj;
                user = mWidgetManager.getUser(info);
                pkg = info.provider.getPackageName();
            }

            final long userId = mUserManager.getSerialNumberForUser(user);
        for (ComponentKey key : list) {
            final long userId = mUserManager.getSerialNumberForUser(key.user);
            HashSet<String> packages = validPackages.get(userId);
            if (packages == null) {
                packages = new HashSet<>();
                validPackages.put(userId, packages);
            }
            packages.add(pkg);
            packages.add(key.componentName.getPackageName());
        }

        LongSparseArray<HashSet<String>> packagesToDelete = new LongSparseArray<>();
@@ -294,14 +271,14 @@ public class WidgetPreviewLoader {
        return null;
    }

    @Thunk Bitmap generatePreview(Launcher launcher, Object info, Bitmap recycle,
    private Bitmap generatePreview(Launcher launcher, WidgetItem item, Bitmap recycle,
            int previewWidth, int previewHeight) {
        if (info instanceof LauncherAppWidgetProviderInfo) {
            return generateWidgetPreview(launcher, (LauncherAppWidgetProviderInfo) info,
        if (item.widgetInfo != null) {
            return generateWidgetPreview(launcher, item.widgetInfo,
                    previewWidth, recycle, null);
        } else {
            return generateShortcutPreview(launcher,
                    (ResolveInfo) info, previewWidth, previewHeight, recycle);
            return generateShortcutPreview(launcher, item.activityInfo,
                    previewWidth, previewHeight, recycle);
        }
    }

@@ -430,7 +407,7 @@ public class WidgetPreviewLoader {
    }

    private Bitmap generateShortcutPreview(
            Launcher launcher, ResolveInfo info, int maxWidth, int maxHeight, Bitmap preview) {
            Launcher launcher, ActivityInfo info, int maxWidth, int maxHeight, Bitmap preview) {
        final Canvas c = new Canvas();
        if (preview == null) {
            preview = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888);
@@ -443,7 +420,7 @@ public class WidgetPreviewLoader {
            c.drawColor(0, PorterDuff.Mode.CLEAR);
        }

        Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info.activityInfo));
        Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info));
        icon.setFilterBitmap(true);

        // Draw a desaturated/scaled version of the icon in the background as a watermark
@@ -499,7 +476,8 @@ public class WidgetPreviewLoader {
            if (versions == null) {
                versions = new long[2];
                try {
                    PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName, 0);
                    PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName,
                            PackageManager.GET_UNINSTALLED_PACKAGES);
                    versions[0] = info.versionCode;
                    versions[1] = info.lastUpdateTime;
                } catch (NameNotFoundException e) {
@@ -548,14 +526,14 @@ public class WidgetPreviewLoader {

    public class PreviewLoadTask extends AsyncTask<Void, Void, Bitmap> {
        @Thunk final WidgetCacheKey mKey;
        private final Object mInfo;
        private final WidgetItem mInfo;
        private final int mPreviewHeight;
        private final int mPreviewWidth;
        private final WidgetCell mCaller;
        @Thunk long[] mVersions;
        @Thunk Bitmap mBitmapToRecycle;

        PreviewLoadTask(WidgetCacheKey key, Object info, int previewWidth,
        PreviewLoadTask(WidgetCacheKey key, WidgetItem info, int previewWidth,
                int previewHeight, WidgetCell caller) {
            mKey = key;
            mInfo = info;
+73 −0
Original line number Diff line number Diff line
package com.android.launcher3.model;

import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;

import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.util.ComponentKey;

import java.text.Collator;

/**
 * An wrapper over various items displayed in a widget picker,
 * {@link LauncherAppWidgetProviderInfo} & {@link ActivityInfo}. This provides easier access to
 * common attributes like spanX and spanY.
 */
public class WidgetItem extends ComponentKey implements Comparable<WidgetItem> {

    private static UserHandleCompat sMyUserHandle;
    private static Collator sCollator;

    public final LauncherAppWidgetProviderInfo widgetInfo;
    public final ActivityInfo activityInfo;

    public final String label;
    public final int spanX, spanY;

    public WidgetItem(LauncherAppWidgetProviderInfo info, AppWidgetManagerCompat widgetManager) {
        super(info.provider, widgetManager.getUser(info));

        label = Utilities.trim(widgetManager.loadLabel(info));
        widgetInfo = info;
        activityInfo = null;

        InvariantDeviceProfile idv = LauncherAppState.getInstance().getInvariantDeviceProfile();
        spanX = Math.min(info.spanX, idv.numColumns);
        spanY = Math.min(info.spanY, idv.numRows);
    }

    public WidgetItem(ResolveInfo info, PackageManager pm) {
        super(new ComponentName(info.activityInfo.packageName, info.activityInfo.name),
                UserHandleCompat.myUserHandle());
        label = Utilities.trim(info.loadLabel(pm));
        widgetInfo = null;
        activityInfo = info.activityInfo;
        spanX = spanY = 1;
    }

    @Override
    public int compareTo(WidgetItem another) {
        if (sMyUserHandle == null) {
            // Delay these object creation until required.
            sMyUserHandle = UserHandleCompat.myUserHandle();
            sCollator = Collator.getInstance();
        }

        // Independent of how the labels compare, if only one of the two widget info belongs to
        // work profile, put that one in the back.
        boolean thisWorkProfile = !sMyUserHandle.equals(user);
        boolean otherWorkProfile = !sMyUserHandle.equals(another.user);
        if (thisWorkProfile ^ otherWorkProfile) {
            return thisWorkProfile ? 1 : -1;
        }

        return sCollator.compare(label, another.label);
    }
}
+0 −97
Original line number Diff line number Diff line
package com.android.launcher3.model;

import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.util.ComponentKey;

import java.text.Collator;
import java.util.Comparator;
import java.util.HashMap;

public class WidgetsAndShortcutNameComparator implements Comparator<Object> {
    private final AppWidgetManagerCompat mManager;
    private final PackageManager mPackageManager;
    private final HashMap<ComponentKey, String> mLabelCache;
    private final Collator mCollator;
    private final UserHandleCompat mMainHandle;

    public WidgetsAndShortcutNameComparator(Context context) {
        mManager = AppWidgetManagerCompat.getInstance(context);
        mPackageManager = context.getPackageManager();
        mLabelCache = new HashMap<>();
        mCollator = Collator.getInstance();
        mMainHandle = UserHandleCompat.myUserHandle();
    }

    /**
     * Resets any stored state.
     */
    public void reset() {
        mLabelCache.clear();
    }

    @Override
    public final int compare(Object objA, Object objB) {
        ComponentKey keyA = getComponentKey(objA);
        ComponentKey keyB = getComponentKey(objB);

        // Independent of how the labels compare, if only one of the two widget info belongs to
        // work profile, put that one in the back.
        boolean aWorkProfile = !mMainHandle.equals(keyA.user);
        boolean bWorkProfile = !mMainHandle.equals(keyB.user);
        if (aWorkProfile && !bWorkProfile) {
            return 1;
        }
        if (!aWorkProfile && bWorkProfile) {
            return -1;
        }

        // Get the labels for comparison
        String labelA = mLabelCache.get(keyA);
        String labelB = mLabelCache.get(keyB);
        if (labelA == null) {
            labelA = getLabel(objA);
            mLabelCache.put(keyA, labelA);
        }
        if (labelB == null) {
            labelB = getLabel(objB);
            mLabelCache.put(keyB, labelB);
        }
        return mCollator.compare(labelA, labelB);
    }

    /**
     * @return a component key for the given widget or shortcut info.
     */
    private ComponentKey getComponentKey(Object o) {
        if (o instanceof LauncherAppWidgetProviderInfo) {
            LauncherAppWidgetProviderInfo widgetInfo = (LauncherAppWidgetProviderInfo) o;
            return new ComponentKey(widgetInfo.provider, mManager.getUser(widgetInfo));
        } else {
            ResolveInfo shortcutInfo = (ResolveInfo) o;
            ComponentName cn = new ComponentName(shortcutInfo.activityInfo.packageName,
                    shortcutInfo.activityInfo.name);
            // Currently, there are no work profile shortcuts
            return new ComponentKey(cn, UserHandleCompat.myUserHandle());
        }
    }

    /**
     * @return the label for the given widget or shortcut info.  This may be an expensive call.
     */
    private String getLabel(Object o) {
        if (o instanceof LauncherAppWidgetProviderInfo) {
            LauncherAppWidgetProviderInfo widgetInfo = (LauncherAppWidgetProviderInfo) o;
            return Utilities.trim(mManager.loadLabel(widgetInfo));
        } else {
            ResolveInfo shortcutInfo = (ResolveInfo) o;
            return Utilities.trim(shortcutInfo.loadLabel(mPackageManager));
        }
    }
};
+49 −61
Original line number Diff line number Diff line
@@ -2,9 +2,9 @@
package com.android.launcher3.model;

import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.DeadObjectException;
import android.os.TransactionTooLargeException;
@@ -19,7 +19,6 @@ import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.config.ProviderConfig;

import java.util.ArrayList;
@@ -42,20 +41,18 @@ public class WidgetsModel {
    private final ArrayList<PackageItemInfo> mPackageItemInfos;

    /* Map of widgets and shortcuts that are tracked per package. */
    private final HashMap<PackageItemInfo, ArrayList<Object>> mWidgetsList;
    private final HashMap<PackageItemInfo, ArrayList<WidgetItem>> mWidgetsList;

    private final AppWidgetManagerCompat mAppWidgetMgr;
    private final WidgetsAndShortcutNameComparator mWidgetAndShortcutNameComparator;
    private final Comparator<ItemInfo> mAppNameComparator;
    private final IconCache mIconCache;
    private final AppFilter mAppFilter;
    private final AlphabeticIndexCompat mIndexer;

    private ArrayList<Object> mRawList;
    private ArrayList<WidgetItem> mRawList;

    public WidgetsModel(Context context,  IconCache iconCache, AppFilter appFilter) {
        mAppWidgetMgr = AppWidgetManagerCompat.getInstance(context);
        mWidgetAndShortcutNameComparator = new WidgetsAndShortcutNameComparator(context);
        mAppNameComparator = (new AppNameComparator(context)).getAppInfoComparator();
        mIconCache = iconCache;
        mAppFilter = appFilter;
@@ -70,13 +67,12 @@ public class WidgetsModel {
    private WidgetsModel(WidgetsModel model) {
        mAppWidgetMgr = model.mAppWidgetMgr;
        mPackageItemInfos = (ArrayList<PackageItemInfo>) model.mPackageItemInfos.clone();
        mWidgetsList = (HashMap<PackageItemInfo, ArrayList<Object>>) model.mWidgetsList.clone();
        mWidgetAndShortcutNameComparator = model.mWidgetAndShortcutNameComparator;
        mWidgetsList = (HashMap<PackageItemInfo, ArrayList<WidgetItem>>) model.mWidgetsList.clone();
        mAppNameComparator = model.mAppNameComparator;
        mIconCache = model.mIconCache;
        mAppFilter = model.mAppFilter;
        mIndexer = model.mIndexer;
        mRawList = (ArrayList<Object>) model.mRawList.clone();
        mRawList = (ArrayList<WidgetItem>) model.mRawList.clone();
    }

    // Access methods that may be deleted if the private fields are made package-private.
@@ -92,11 +88,11 @@ public class WidgetsModel {
        return mPackageItemInfos.get(pos);
    }

    public List<Object> getSortedWidgets(int pos) {
    public List<WidgetItem> getSortedWidgets(int pos) {
        return mWidgetsList.get(mPackageItemInfos.get(pos));
    }

    public ArrayList<Object> getRawList() {
    public ArrayList<WidgetItem> getRawList() {
        return mRawList;
    }

@@ -108,16 +104,21 @@ public class WidgetsModel {
        Utilities.assertWorkerThread();

        try {
            final ArrayList<Object> widgetsAndShortcuts = new ArrayList<>();
            final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
            // Widgets
            for (AppWidgetProviderInfo widgetInfo :
                    AppWidgetManagerCompat.getInstance(context).getAllProviders()) {
                widgetsAndShortcuts.add(LauncherAppWidgetProviderInfo
                        .fromProviderInfo(context, widgetInfo));
            AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(context);
            for (AppWidgetProviderInfo widgetInfo : widgetManager.getAllProviders()) {
                widgetsAndShortcuts.add(new WidgetItem(
                        LauncherAppWidgetProviderInfo.fromProviderInfo(context, widgetInfo),
                        widgetManager));
            }

            // Shortcuts
            widgetsAndShortcuts.addAll(context.getPackageManager().queryIntentActivities(
                    new Intent(Intent.ACTION_CREATE_SHORTCUT), 0));
            PackageManager pm = context.getPackageManager();
            for (ResolveInfo info :
                    pm.queryIntentActivities(new Intent(Intent.ACTION_CREATE_SHORTCUT), 0)) {
                widgetsAndShortcuts.add(new WidgetItem(info, pm));
            }
            setWidgetsAndShortcuts(widgetsAndShortcuts);
        } catch (Exception e) {
            if (!ProviderConfig.IS_DOGFOOD_BUILD &&
@@ -134,7 +135,7 @@ public class WidgetsModel {
        return clone();
    }

    private void setWidgetsAndShortcuts(ArrayList<Object> rawWidgetsShortcuts) {
    private void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts) {
        mRawList = rawWidgetsShortcuts;
        if (DEBUG) {
            Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
@@ -147,76 +148,63 @@ public class WidgetsModel {
        // clear the lists.
        mWidgetsList.clear();
        mPackageItemInfos.clear();
        mWidgetAndShortcutNameComparator.reset();

        InvariantDeviceProfile idp = LauncherAppState.getInstance().getInvariantDeviceProfile();

        // add and update.
        for (Object o: rawWidgetsShortcuts) {
            String packageName = "";
            UserHandleCompat userHandle = null;
            ComponentName componentName = null;
            if (o instanceof LauncherAppWidgetProviderInfo) {
                LauncherAppWidgetProviderInfo widgetInfo = (LauncherAppWidgetProviderInfo) o;

        for (WidgetItem item: rawWidgetsShortcuts) {
            if (item.widgetInfo != null) {
                // Ensure that all widgets we show can be added on a workspace of this size
                int minSpanX = Math.min(widgetInfo.spanX, widgetInfo.minSpanX);
                int minSpanY = Math.min(widgetInfo.spanY, widgetInfo.minSpanY);
                if (minSpanX <= (int) idp.numColumns &&
                    minSpanY <= (int) idp.numRows) {
                    componentName = widgetInfo.provider;
                    packageName = widgetInfo.provider.getPackageName();
                    userHandle = mAppWidgetMgr.getUser(widgetInfo);
                } else {
                int minSpanX = Math.min(item.widgetInfo.spanX, item.widgetInfo.minSpanX);
                int minSpanY = Math.min(item.widgetInfo.spanY, item.widgetInfo.minSpanY);
                if (minSpanX > idp.numColumns || minSpanY > idp.numRows) {
                    if (DEBUG) {
                        Log.d(TAG, String.format(
                                "Widget %s : (%d X %d) can't fit on this device",
                                widgetInfo.provider, minSpanX, minSpanY));
                                item.componentName, minSpanX, minSpanY));
                    }
                    continue;
                }
            } else if (o instanceof ResolveInfo) {
                ResolveInfo resolveInfo = (ResolveInfo) o;
                componentName = new ComponentName(resolveInfo.activityInfo.packageName,
                        resolveInfo.activityInfo.name);
                packageName = resolveInfo.activityInfo.packageName;
                userHandle = UserHandleCompat.myUserHandle();
            }

            if (componentName == null || userHandle == null) {
                Log.e(TAG, String.format("Widget cannot be set for %s.", o.getClass().toString()));
                continue;
            }
            if (mAppFilter != null && !mAppFilter.shouldShowApp(componentName)) {
            if (mAppFilter != null && !mAppFilter.shouldShowApp(item.componentName)) {
                if (DEBUG) {
                    Log.d(TAG, String.format("%s is filtered and not added to the widget tray.",
                        packageName));
                            item.componentName));
                }
                continue;
            }

            String packageName = item.componentName.getPackageName();
            PackageItemInfo pInfo = tmpPackageItemInfos.get(packageName);
            ArrayList<Object> widgetsShortcutsList = mWidgetsList.get(pInfo);
            if (widgetsShortcutsList != null) {
                widgetsShortcutsList.add(o);
            } else {
            ArrayList<WidgetItem> widgetsShortcutsList = mWidgetsList.get(pInfo);

            if (widgetsShortcutsList == null) {
                widgetsShortcutsList = new ArrayList<>();
                widgetsShortcutsList.add(o);

                pInfo = new PackageItemInfo(packageName);
                mIconCache.getTitleAndIconForApp(packageName, userHandle,
                        true /* userLowResIcon */, pInfo);
                pInfo.titleSectionName = mIndexer.computeSectionName(pInfo.title);
                mWidgetsList.put(pInfo, widgetsShortcutsList);
                tmpPackageItemInfos.put(packageName,  pInfo);

                mPackageItemInfos.add(pInfo);
                mWidgetsList.put(pInfo, widgetsShortcutsList);
            }

            widgetsShortcutsList.add(item);
        }

        // sort.
        Collections.sort(mPackageItemInfos, mAppNameComparator);
        // Update each package entry
        for (PackageItemInfo p : mPackageItemInfos) {
            Collections.sort(mWidgetsList.get(p), mWidgetAndShortcutNameComparator);
            ArrayList<WidgetItem> widgetsShortcutsList = mWidgetsList.get(p);
            Collections.sort(widgetsShortcutsList);

            // Update the package entry based on the first item.
            p.user = widgetsShortcutsList.get(0).user;
            mIconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
            p.titleSectionName = mIndexer.computeSectionName(p.title);
        }

        // sort the package entries.
        Collections.sort(mPackageItemInfos, mAppNameComparator);
    }

    /**
Loading