LauncherModel.java revision f96811cdf564469a7a654a0c876288c9fd14f35e
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/*
231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License.
631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at
731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and
1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License.
1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpackage com.android.launcher;
1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ComponentName;
2031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ContentResolver;
2131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ContentValues;
2231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Intent;
2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context;
2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ActivityInfo;
2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.PackageManager;
2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ResolveInfo;
2731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.Resources;
2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.database.Cursor;
2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap;
3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.BitmapFactory;
31f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.graphics.drawable.Drawable;
3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.net.Uri;
33f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport static android.util.Log.*;
3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Process;
3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.ArrayList;
3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.HashMap;
3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.List;
3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.Comparator;
4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.lang.ref.WeakReference;
4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.text.Collator;
4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.net.URISyntaxException;
4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Maintains in-memory state of the Launcher. It is expected that there should be only one
4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * LauncherModel object held in a static. Also provide APIs for updating the database state
47bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project * for the Launcher.
4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpublic class LauncherModel {
50f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    static final boolean DEBUG_LOADERS = false;
51f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    static final String LOG_TAG = "HomeLoaders";
52f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
5331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static final int UI_NOTIFICATION_RATE = 4;
5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static final int DEFAULT_APPLICATIONS_NUMBER = 42;
5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static final long APPLICATION_NOT_RESPONDING_TIMEOUT = 5000;
56bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
5731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
587376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project    private static final Collator sCollator = Collator.getInstance();
5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
6031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private boolean mApplicationsLoaded;
6131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private boolean mDesktopItemsLoaded;
6231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private ArrayList<ItemInfo> mDesktopItems;
647376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project    private ArrayList<LauncherAppWidgetInfo> mDesktopAppWidgets;
6531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private HashMap<Long, FolderInfo> mFolders;
6631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
6731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private ArrayList<ApplicationInfo> mApplications;
6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private ApplicationsAdapter mApplicationsAdapter;
6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private ApplicationsLoader mApplicationsLoader;
7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private DesktopItemsLoader mDesktopItemsLoader;
71ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    private Thread mApplicationsLoaderThread;
72ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    private Thread mDesktopLoaderThread;
7331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
74bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    private final HashMap<ComponentName, ApplicationInfo> mAppInfoCache =
75bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            new HashMap<ComponentName, ApplicationInfo>(INITIAL_ICON_CACHE_CAPACITY);
76bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
77ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    synchronized void abortLoaders() {
7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mApplicationsLoader.stop();
8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mApplicationsLoaded = false;
8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
82ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopItemsLoader.stop();
8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopItemsLoaded = false;
8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
90bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * Drop our cache of components to their lables & icons.  We do
91bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * this from Launcher when applications are added/removed.  It's a
92bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * bit overkill, but it's a rare operation anyway.
93bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     */
94bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    synchronized void dropApplicationCache() {
95bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        mAppInfoCache.clear();
96bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    }
97bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
98bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    /**
9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Loads the list of installed applications in mApplications.
100ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project     *
101ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project     * @return true if the applications loader must be started
102ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project     *         (see startApplicationsLoader()), false otherwise.
10331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
104ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    synchronized boolean loadApplications(boolean isLaunching, Launcher launcher,
105bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            boolean localeChanged) {
106f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
107f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (DEBUG_LOADERS) d(LOG_TAG, "load applications");
108f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (isLaunching && mApplicationsLoaded && !localeChanged) {
11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
111f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (DEBUG_LOADERS) d(LOG_TAG, "  --> applications loaded, return");
112ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            return false;
11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
11431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
115f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        stopAndWaitForApplicationsLoader();
116ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
117ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        if (localeChanged) {
118ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            dropApplicationCache();
119ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        }
120ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mApplicationsAdapter == null || isLaunching || localeChanged) {
122bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            mApplications = new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER);
123bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
126ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        mApplicationsLoaded = false;
127ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
128ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        if (!isLaunching) {
129ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            startApplicationsLoader(launcher);
130ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            return false;
131ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        }
132ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
133ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        return true;
134ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    }
135ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
136f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private synchronized void stopAndWaitForApplicationsLoader() {
13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
138f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (DEBUG_LOADERS) d(LOG_TAG, "  --> wait for applications loader");
139ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mApplicationsLoader.stop();
14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // Wait for the currently running thread to finish, this can take a little
14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // time but it should be well below the timeout limit
14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            try {
144ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                mApplicationsLoaderThread.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            } catch (InterruptedException e) {
146ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                // EMpty
14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
14831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
14931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
151ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    private synchronized void startApplicationsLoader(Launcher launcher) {
152f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (DEBUG_LOADERS) d(LOG_TAG, "  --> starting applications loader");
153f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
154f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        stopAndWaitForApplicationsLoader();
155ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mApplicationsLoader = new ApplicationsLoader(launcher);
157ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        mApplicationsLoaderThread = new Thread(mApplicationsLoader, "Applications Loader");
158ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        mApplicationsLoaderThread.start();
15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
161f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    synchronized void addPackage(Launcher launcher, String packageName) {
162f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
163f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            startApplicationsLoader(launcher);
164f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            return;
165f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
166f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
167f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (packageName != null && packageName.length() > 0) {
168f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final PackageManager packageManager = launcher.getPackageManager();
169f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
170f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
171f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (matches.size() > 0) {
172f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final ApplicationsAdapter adapter = mApplicationsAdapter;
173f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
174f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
175f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                for (ResolveInfo info : matches) {
176f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    adapter.setNotifyOnChange(false);
177f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    adapter.add(makeAndCacheApplicationInfo(packageManager, cache, info));
178f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
179f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
180f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                adapter.sort(new ApplicationInfoComparator());
181f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                adapter.notifyDataSetChanged();
182f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
183f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
184f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
185f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
186f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    synchronized void removePackage(Launcher launcher, String packageName) {
187f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
188f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            dropApplicationCache(); // TODO: this could be optimized
189f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            startApplicationsLoader(launcher);
190f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            return;
191f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
192f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
193f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (packageName != null && packageName.length() > 0) {
194f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ApplicationsAdapter adapter = mApplicationsAdapter;
195f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
196f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
197f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final int count = adapter.getCount();
198f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
199f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            for (int i = 0; i < count; i++) {
200f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final ApplicationInfo applicationInfo = adapter.getItem(i);
201f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final Intent intent = applicationInfo.intent;
202f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final ComponentName component = intent.getComponent();
203f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                if (packageName.equals(component.getPackageName())) {
204f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    toRemove.add(applicationInfo);
205f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
206f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
207f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
208f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
209f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            for (ApplicationInfo info : toRemove) {
210f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                adapter.setNotifyOnChange(false);
211f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                adapter.remove(info);
212f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                cache.remove(info.intent.getComponent());
213f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
214f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
215f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (toRemove.size() > 0) {
216f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                adapter.sort(new ApplicationInfoComparator());
217f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                adapter.notifyDataSetChanged();
218f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
219f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
220f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
221f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
222f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    synchronized void updatePackage(Launcher launcher, String packageName) {
223f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
224f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            startApplicationsLoader(launcher);
225f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            return;
226f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
227f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
228f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (packageName != null && packageName.length() > 0) {
229f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final PackageManager packageManager = launcher.getPackageManager();
230f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ApplicationsAdapter adapter = mApplicationsAdapter;
231f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
232f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
233f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final int count = matches.size();
234f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
235f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            boolean changed = false;
236f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
237f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            for (int i = 0; i < count; i++) {
238f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final ResolveInfo info = matches.get(i);
239f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final ApplicationInfo applicationInfo = findIntent(adapter,
240f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                        info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
241f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                if (applicationInfo != null) {
242f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    updateAndCacheApplicationInfo(packageManager, info, applicationInfo);
243f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    changed = true;
244f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
245f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
246f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
247f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (changed) {
248f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                adapter.sort(new ApplicationInfoComparator());
249f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                adapter.notifyDataSetChanged();
250f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
251f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
252f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
253f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
254f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private void updateAndCacheApplicationInfo(PackageManager packageManager, ResolveInfo info,
255f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            ApplicationInfo applicationInfo) {
256f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
257f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        updateApplicationInfoTitleAndIcon(packageManager, info, applicationInfo);
258f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
259f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        ComponentName componentName = new ComponentName(
260f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
261f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        mAppInfoCache.put(componentName, applicationInfo);
262f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
263f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
264f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    synchronized void syncPackage(Launcher launcher, String packageName) {
265f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
266f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            startApplicationsLoader(launcher);
267f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            return;
268f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
269f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
270f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (packageName != null && packageName.length() > 0) {
271f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final PackageManager packageManager = launcher.getPackageManager();
272f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final List<ResolveInfo> matches = findActivitiesForPackage(packageManager, packageName);
273f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
274f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (matches.size() > 0) {
275f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final ApplicationsAdapter adapter = mApplicationsAdapter;
276f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
277f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                // Find disabled activities and remove them from the adapter
278f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                boolean removed = removeDisabledActivities(packageName, matches, adapter);
279f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                // Find enable activities and add them to the adapter
280f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                // Also updates existing activities with new labels/icons
281f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                boolean added = addEnabledAndUpdateActivities(matches, adapter, launcher);
282f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
283f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                if (added || removed) {
284f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    adapter.sort(new ApplicationInfoComparator());
285f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    adapter.notifyDataSetChanged();
286f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
287f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
288f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
289f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
290f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
291f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private static List<ResolveInfo> findActivitiesForPackage(PackageManager packageManager,
292f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            String packageName) {
293f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
294f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
295f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
296f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
297f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final List<ResolveInfo> apps = packageManager.queryIntentActivities(mainIntent, 0);
298f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final List<ResolveInfo> matches = new ArrayList<ResolveInfo>();
299f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
300f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (apps != null) {
301f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            // Find all activities that match the packageName
302f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            int count = apps.size();
303f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            for (int i = 0; i < count; i++) {
304f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final ResolveInfo info = apps.get(i);
305f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final ActivityInfo activityInfo = info.activityInfo;
306f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                if (packageName.equals(activityInfo.packageName)) {
307f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    matches.add(info);
308f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
309f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
310f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
311f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
312f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        return matches;
313f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
314f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
315f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private boolean addEnabledAndUpdateActivities(List<ResolveInfo> matches,
316f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            ApplicationsAdapter adapter, Launcher launcher) {
317f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
318f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final List<ApplicationInfo> toAdd = new ArrayList<ApplicationInfo>();
319f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final int count = matches.size();
320f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
321f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        boolean changed = false;
322f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
323f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        for (int i = 0; i < count; i++) {
324f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ResolveInfo info = matches.get(i);
325f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ApplicationInfo applicationInfo = findIntent(adapter,
326f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    info.activityInfo.applicationInfo.packageName, info.activityInfo.name);
327f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (applicationInfo == null) {
328f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                toAdd.add(makeAndCacheApplicationInfo(launcher.getPackageManager(),
329f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                        mAppInfoCache, info));
330f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                changed = true;
331f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            } else {
332f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                updateAndCacheApplicationInfo(launcher.getPackageManager(), info, applicationInfo);
333f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                changed = true;
334f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
335f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
336f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
337f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        for (ApplicationInfo info : toAdd) {
338f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            adapter.setNotifyOnChange(false);
339f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            adapter.add(info);
340f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
341f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
342f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        return changed;
343f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
344f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
345f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private boolean removeDisabledActivities(String packageName, List<ResolveInfo> matches,
346f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            ApplicationsAdapter adapter) {
347f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
348f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final List<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>();
349f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final int count = adapter.getCount();
350f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
351f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        boolean changed = false;
352f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
353f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        for (int i = 0; i < count; i++) {
354f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ApplicationInfo applicationInfo = adapter.getItem(i);
355f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final Intent intent = applicationInfo.intent;
356f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ComponentName component = intent.getComponent();
357f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (packageName.equals(component.getPackageName())) {
358f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                if (!findIntent(matches, component)) {
359f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    toRemove.add(applicationInfo);
360f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    changed = true;
361f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
362f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
363f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
364f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
365f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final HashMap<ComponentName, ApplicationInfo> cache = mAppInfoCache;
366f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        for (ApplicationInfo info : toRemove) {
367f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            adapter.setNotifyOnChange(false);
368f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            adapter.remove(info);
369f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            cache.remove(info.intent.getComponent());
370f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
371f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
372f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        return changed;
373f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
374f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
375f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private static ApplicationInfo findIntent(ApplicationsAdapter adapter, String packageName,
376f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            String name) {
377f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
378f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final int count = adapter.getCount();
379f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        for (int i = 0; i < count; i++) {
380f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ApplicationInfo applicationInfo = adapter.getItem(i);
381f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final Intent intent = applicationInfo.intent;
382f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ComponentName component = intent.getComponent();
383f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (packageName.equals(component.getPackageName()) &&
384f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    name.equals(component.getClassName())) {
385f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                return applicationInfo;
386f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
387f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
388f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
389f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        return null;
390f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
391f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
392f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private static boolean findIntent(List<ResolveInfo> apps, ComponentName component) {
393f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final String className = component.getClassName();
394f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        for (ResolveInfo info : apps) {
395f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final ActivityInfo activityInfo = info.activityInfo;
396f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (activityInfo.name.equals(className)) {
397f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                return true;
398f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
399f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
400f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        return false;
401f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
402f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
403f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    Drawable getApplicationInfoIcon(PackageManager manager, ApplicationInfo info) {
404f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        final ResolveInfo resolveInfo = manager.resolveActivity(info.intent, 0);
405f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (resolveInfo == null) {
406f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            return null;
407f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
408f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
409f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        ComponentName componentName = new ComponentName(
410f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                resolveInfo.activityInfo.applicationInfo.packageName,
411f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                resolveInfo.activityInfo.name);
412f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        ApplicationInfo application = mAppInfoCache.get(componentName);
413f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
414f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (application == null) {
415f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            return resolveInfo.activityInfo.loadIcon(manager);
416f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
417f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
418f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        return application.icon;
419f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
420f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
421f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private static ApplicationInfo makeAndCacheApplicationInfo(PackageManager manager,
422f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            HashMap<ComponentName, ApplicationInfo> appInfoCache, ResolveInfo info) {
423f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
424f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        ComponentName componentName = new ComponentName(
425f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                info.activityInfo.applicationInfo.packageName,
426f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                info.activityInfo.name);
427f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        ApplicationInfo application = appInfoCache.get(componentName);
428f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
429f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (application == null) {
430f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            application = new ApplicationInfo();
431f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            application.container = ItemInfo.NO_ID;
432f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
433f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            updateApplicationInfoTitleAndIcon(manager, info, application);
434f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
435f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            application.setActivity(componentName,
436f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
437f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
438f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            appInfoCache.put(componentName, application);
439f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
440f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
441f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        return application;
442f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
443f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
444f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private static void updateApplicationInfoTitleAndIcon(PackageManager manager, ResolveInfo info,
445f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            ApplicationInfo application) {
446f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
447f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        application.title = info.loadLabel(manager);
448f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (application.title == null) {
449f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            application.title = info.activityInfo.name;
450f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
451f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
452f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        application.icon = info.activityInfo.loadIcon(manager);
453f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        application.filtered = false;
454f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
455f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
45631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private class ApplicationsLoader implements Runnable {
45731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final WeakReference<Launcher> mLauncher;
45831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
45931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private volatile boolean mStopped;
46031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private volatile boolean mRunning;
46131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
46231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        ApplicationsLoader(Launcher launcher) {
46331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mLauncher = new WeakReference<Launcher>(launcher);
46431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
46531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
46631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void stop() {
46731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mStopped = true;
46831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
46931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
47031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        boolean isRunning() {
47131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return mRunning;
47231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
47331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
47431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        public void run() {
47531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mRunning = true;
47631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
47731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
47831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
479f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
48031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
48131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
48231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final Launcher launcher = mLauncher.get();
48331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final PackageManager manager = launcher.getPackageManager();
48431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
48531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
48631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (apps != null && !mStopped) {
48731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int count = apps.size();
488f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                // Can be set to null on the UI thread by the unbind() method
489f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                // Do not access without checking for null first
49031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final ApplicationsAdapter applicationList = mApplicationsAdapter;
49131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
492ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                ChangeNotifier action = new ChangeNotifier(applicationList, true);
4937376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                final HashMap<ComponentName, ApplicationInfo> appInfoCache = mAppInfoCache;
49431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
49531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                for (int i = 0; i < count && !mStopped; i++) {
49631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    ResolveInfo info = apps.get(i);
497f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    ApplicationInfo application =
498f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                            makeAndCacheApplicationInfo(manager, appInfoCache, info);
49931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
500f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    if (action.add(application) && !mStopped) {
501ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                        launcher.runOnUiThread(action);
502ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                        action = new ChangeNotifier(applicationList, false);
503ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                    }
50431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
505ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
506ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                launcher.runOnUiThread(action);
50731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
50831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
50931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (!mStopped) {
51031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                mApplicationsLoaded = true;
51131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
51231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mRunning = false;
51331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
51431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
51531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
516f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private static class ChangeNotifier implements Runnable {
51731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final ApplicationsAdapter mApplicationList;
518bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        private final ArrayList<ApplicationInfo> mBuffer;
5197376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project
5207376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project        private boolean mFirst = true;
52131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
522ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        ChangeNotifier(ApplicationsAdapter applicationList, boolean first) {
52331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mApplicationList = applicationList;
524ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            mFirst = first;
52531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mBuffer = new ArrayList<ApplicationInfo>(UI_NOTIFICATION_RATE);
52631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
52731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
52831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        public void run() {
52931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final ApplicationsAdapter applicationList = mApplicationList;
530f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            // Can be set to null on the UI thread by the unbind() method
531f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (applicationList == null) return;
53231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
5337376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project            if (mFirst) {
53431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                applicationList.setNotifyOnChange(false);
5357376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                applicationList.clear();
5367376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                mFirst = false;
53731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
53831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
539ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            final ArrayList<ApplicationInfo> buffer = mBuffer;
540ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            final int count = buffer.size();
5417376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project
542ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            for (int i = 0; i < count; i++) {
543ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                applicationList.setNotifyOnChange(false);
544ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                applicationList.add(buffer.get(i));
5457376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project            }
5467376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project
547ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            buffer.clear();
548ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project
549f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            applicationList.sort(new ApplicationInfoComparator());
55031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            applicationList.notifyDataSetChanged();
55131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
55231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
553ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        boolean add(ApplicationInfo application) {
554ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            final ArrayList<ApplicationInfo> buffer = mBuffer;
555ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            buffer.add(application);
556ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project            return buffer.size() >= UI_NOTIFICATION_RATE;
55731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
558f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
55931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
560f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    private static class ApplicationInfoComparator implements Comparator<ApplicationInfo> {
5617376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project        public final int compare(ApplicationInfo a, ApplicationInfo b) {
5627376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project            return sCollator.compare(a.title.toString(), b.title.toString());
56331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
56431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
56531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
56631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    boolean isDesktopLoaded() {
5677376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project        return mDesktopItems != null && mDesktopAppWidgets != null && mDesktopItemsLoaded;
56831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
569bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
57031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
57131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Loads all of the items on the desktop, in folders, or in the dock.
57231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * These can be apps, shortcuts or widgets
57331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
57431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged,
57531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            boolean loadApplications) {
576f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (DEBUG_LOADERS) d(LOG_TAG, "loading user items");
57731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
57831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (isLaunching && isDesktopLoaded()) {
579f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            if (DEBUG_LOADERS) d(LOG_TAG, "  --> items loaded, return");
58031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (loadApplications) startApplicationsLoader(launcher);
58131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // We have already loaded our data from the DB
58231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            launcher.onDesktopItemsLoaded();
58331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return;
58431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
58531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
58631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
58731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopItemsLoader.stop();
58831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // Wait for the currently running thread to finish, this can take a little
58931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // time but it should be well below the timeout limit
59031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            try {
591ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project                mDesktopLoaderThread.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
59231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            } catch (InterruptedException e) {
59331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                // Empty
59431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
59531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
59631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
597f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        if (DEBUG_LOADERS) d(LOG_TAG, "  --> starting workspace loader");
59831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopItemsLoaded = false;
59931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications);
600ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        mDesktopLoaderThread = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
601ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project        mDesktopLoaderThread.start();
60231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
60331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
60431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static void updateShortcutLabels(ContentResolver resolver, PackageManager manager) {
60531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final Cursor c = resolver.query(LauncherSettings.Favorites.CONTENT_URI,
60631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                new String[] { LauncherSettings.Favorites.ID, LauncherSettings.Favorites.TITLE,
60731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        LauncherSettings.Favorites.INTENT, LauncherSettings.Favorites.ITEM_TYPE },
60831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                null, null, null);
60931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
61031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
61131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
61231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
61331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
61431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
61531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // boolean changed = false;
61631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
61731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        try {
61831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            while (c.moveToNext()) {
61931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                try {
62031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    if (c.getInt(itemTypeIndex) !=
62131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
62231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        continue;
62331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
62431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
62531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    final String intentUri = c.getString(intentIndex);
62631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    if (intentUri != null) {
62731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        final Intent shortcut = Intent.getIntent(intentUri);
62831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        if (Intent.ACTION_MAIN.equals(shortcut.getAction())) {
62931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            final ComponentName name = shortcut.getComponent();
63031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (name != null) {
63131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                final ActivityInfo activityInfo = manager.getActivityInfo(name, 0);
63231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                final String title = c.getString(titleIndex);
63331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                String label = getLabel(manager, activityInfo);
63431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
63531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                if (title == null || !title.equals(label)) {
63631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    final ContentValues values = new ContentValues();
63731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    values.put(LauncherSettings.Favorites.TITLE, label);
63831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
63931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    resolver.update(LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION,
64031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                            values, "_id=?",
64131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                            new String[] { String.valueOf(c.getLong(idIndex)) });
64231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
64331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    // changed = true;
64431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                }
64531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
64631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        }
64731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
64831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (URISyntaxException e) {
64931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    // Ignore
65031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (PackageManager.NameNotFoundException e) {
65131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    // Ignore
65231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
65331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
65431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } finally {
65531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            c.close();
65631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
65731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
65831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // if (changed) resolver.notifyChange(Settings.Favorites.CONTENT_URI, null);
65931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
66031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
66131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
66231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        String label = activityInfo.loadLabel(manager).toString();
66331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (label == null) {
66431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
66531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (label == null) {
66631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                label = activityInfo.name;
66731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
66831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
66931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return label;
67031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
67131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
67231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private class DesktopItemsLoader implements Runnable {
67331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private volatile boolean mStopped;
67431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private volatile boolean mRunning;
67531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
67631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final WeakReference<Launcher> mLauncher;
67731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final boolean mLocaleChanged;
67831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final boolean mLoadApplications;
67931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
68031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        DesktopItemsLoader(Launcher launcher, boolean localeChanged, boolean loadApplications) {
68131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mLoadApplications = loadApplications;
68231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mLauncher = new WeakReference<Launcher>(launcher);
68331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mLocaleChanged = localeChanged;
68431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
68531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
68631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void stop() {
68731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mStopped = true;
68831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
68931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
69031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        boolean isRunning() {
69131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return mRunning;
69231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
69331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
69431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        public void run() {
69531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mRunning = true;
69631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
69731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final Launcher launcher = mLauncher.get();
69831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final ContentResolver contentResolver = launcher.getContentResolver();
69931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final PackageManager manager = launcher.getPackageManager();
70031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
70131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (mLocaleChanged) {
70231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                updateShortcutLabels(contentResolver, manager);
70331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
70431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
70531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopItems = new ArrayList<ItemInfo>();
7067376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project            mDesktopAppWidgets = new ArrayList<LauncherAppWidgetInfo>();
70731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mFolders = new HashMap<Long, FolderInfo>();
70831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
70931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final ArrayList<ItemInfo> desktopItems = mDesktopItems;
7107376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project            final ArrayList<LauncherAppWidgetInfo> desktopAppWidgets = mDesktopAppWidgets;
71131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
71231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final Cursor c = contentResolver.query(
71331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
71431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
71531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            try {
71631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
71731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
71831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
71931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
72031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
72131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
72231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
72331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
72431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
7257376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                final int appWidgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.APPWIDGET_ID);
72631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
72731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
72831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
72931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
73031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
73131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
73231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
73331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
73431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                ApplicationInfo info;
73531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String intentDescription;
73631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                Widget widgetInfo;
7377376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                LauncherAppWidgetInfo appWidgetInfo;
73831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                int container;
73931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                long id;
74031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                Intent intent;
74131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
74231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final HashMap<Long, FolderInfo> folders = mFolders;
74331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
74431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                while (!mStopped && c.moveToNext()) {
74531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    try {
74631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        int itemType = c.getInt(itemTypeIndex);
74731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
74831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        switch (itemType) {
74931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
75031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
75131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            intentDescription = c.getString(intentIndex);
75231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            try {
75331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                intent = Intent.getIntent(intentDescription);
75431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            } catch (java.net.URISyntaxException e) {
75531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                continue;
75631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
75731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
75831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
75931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info = getApplicationInfo(manager, intent);
76031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            } else {
76131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info = getApplicationInfoShortcut(c, launcher, iconTypeIndex,
76231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                        iconPackageIndex, iconResourceIndex, iconIndex);
76331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
76431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
76531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (info == null) {
76631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info = new ApplicationInfo();
76731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.icon = manager.getDefaultActivityIcon();
76831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
76931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
77031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (info != null) {
77131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.title = c.getString(titleIndex);
77231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.intent = intent;
77331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
77431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.id = c.getLong(idIndex);
77531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                container = c.getInt(containerIndex);
77631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.container = container;
77731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.screen = c.getInt(screenIndex);
77831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.cellX = c.getInt(cellXIndex);
77931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.cellY = c.getInt(cellYIndex);
78031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
78131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                switch (container) {
78231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
78331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    desktopItems.add(info);
78431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    break;
78531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                default:
78631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    // Item is in a user folder
78731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    UserFolderInfo folderInfo =
78831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                            findOrMakeUserFolder(folders, container);
78931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    folderInfo.add(info);
79031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    break;
79131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                }
79231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
79331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
79431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
79531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
79631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            id = c.getLong(idIndex);
79731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            UserFolderInfo folderInfo = findOrMakeUserFolder(folders, id);
79831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
79931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.title = c.getString(titleIndex);
80031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
80131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.id = id;
80231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            container = c.getInt(containerIndex);
80331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.container = container;
80431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.screen = c.getInt(screenIndex);
80531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.cellX = c.getInt(cellXIndex);
80631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.cellY = c.getInt(cellYIndex);
80731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
80831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            switch (container) {
80931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
81031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    desktopItems.add(folderInfo);
81131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    break;
81231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
81331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
81431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
81531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
81631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            id = c.getLong(idIndex);
81731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(folders, id);
81831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
81931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            intentDescription = c.getString(intentIndex);
82031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            intent = null;
82131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (intentDescription != null) {
82231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                try {
82331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    intent = Intent.getIntent(intentDescription);
82431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                } catch (java.net.URISyntaxException e) {
82531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    // Ignore, a live folder might not have a base intent
82631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                }
82731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
82831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
82931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.title = c.getString(titleIndex);
83031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.id = id;
83131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            container = c.getInt(containerIndex);
83231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.container = container;
83331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.screen = c.getInt(screenIndex);
83431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.cellX = c.getInt(cellXIndex);
83531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.cellY = c.getInt(cellYIndex);
83631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.uri = Uri.parse(c.getString(uriIndex));
83731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.baseIntent = intent;
83831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.displayMode = c.getInt(displayModeIndex);
83931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
84031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            loadLiveFolderIcon(launcher, c, iconTypeIndex, iconPackageIndex,
84131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    iconResourceIndex, liveFolderInfo);
84231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
84331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            switch (container) {
84431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
84531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    desktopItems.add(liveFolderInfo);
84631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    break;
84731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
84831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
84931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
85031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo = Widget.makeSearch();
85131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
85231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            container = c.getInt(containerIndex);
85331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
854f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                                e(Launcher.LOG_TAG, "Widget found where container "
85531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                        + "!= CONTAINER_DESKTOP  ignoring!");
85631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                continue;
85731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
858bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
85931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.id = c.getLong(idIndex);
86031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.screen = c.getInt(screenIndex);
86131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.container = container;
86231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.cellX = c.getInt(cellXIndex);
86331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.cellY = c.getInt(cellYIndex);
86431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
86531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            desktopItems.add(widgetInfo);
86631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
8677376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
8687376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            // Read all Launcher-specific widget details
8697376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            int appWidgetId = c.getInt(appWidgetIdIndex);
8707376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId);
8717376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            appWidgetInfo.id = c.getLong(idIndex);
8727376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            appWidgetInfo.screen = c.getInt(screenIndex);
8737376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            appWidgetInfo.cellX = c.getInt(cellXIndex);
8747376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            appWidgetInfo.cellY = c.getInt(cellYIndex);
8757376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            appWidgetInfo.spanX = c.getInt(spanXIndex);
8767376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            appWidgetInfo.spanY = c.getInt(spanYIndex);
87731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
87831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            container = c.getInt(containerIndex);
87931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
880f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                                e(Launcher.LOG_TAG, "Widget found where container "
88131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                        + "!= CONTAINER_DESKTOP -- ignoring!");
88231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                continue;
88331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
8847376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            appWidgetInfo.container = c.getInt(containerIndex);
885bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
8867376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                            desktopAppWidgets.add(appWidgetInfo);
88731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
88831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        }
88931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    } catch (Exception e) {
890f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                        w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e);
89131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
89231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
89331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            } finally {
89431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                c.close();
89531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
89631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
89731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (!mStopped) {
89831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                launcher.runOnUiThread(new Runnable() {
89931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    public void run() {
90031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        launcher.onDesktopItemsLoaded();
90131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
90231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                });
90331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                if (mLoadApplications) startApplicationsLoader(launcher);
90431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
90531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
90631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (!mStopped) {
90731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                mDesktopItemsLoaded = true;
90831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
90931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mRunning = false;
91031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
91131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
91231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
91331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static void loadLiveFolderIcon(Launcher launcher, Cursor c, int iconTypeIndex,
91431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
91531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
91631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        int iconType = c.getInt(iconTypeIndex);
91731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        switch (iconType) {
91831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
91931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String packageName = c.getString(iconPackageIndex);
92031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String resourceName = c.getString(iconResourceIndex);
92131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                PackageManager packageManager = launcher.getPackageManager();
92231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                try {
92331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    Resources resources = packageManager.getResourcesForApplication(packageName);
92431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    final int id = resources.getIdentifier(resourceName, null, null);
92531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    liveFolderInfo.icon = resources.getDrawable(id);
92631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (Exception e) {
92731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    liveFolderInfo.icon =
92831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
92931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
93031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
93131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                liveFolderInfo.iconResource.packageName = packageName;
93231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                liveFolderInfo.iconResource.resourceName = resourceName;
93331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                break;
93431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            default:
93531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                liveFolderInfo.icon =
936bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
93731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
93831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
93931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
94031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
94131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Finds the user folder defined by the specified id.
94231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
94331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param id The id of the folder to look for.
944bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     *
94531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return A UserFolderInfo if the folder exists or null otherwise.
94631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
94731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    FolderInfo findFolderById(long id) {
94831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mFolders.get(id);
94931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
95031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
95131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void addFolder(FolderInfo info) {
95231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mFolders.put(info.id, info);
95331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
95431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
95531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
95631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
95731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * new one.
95831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
95931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
96031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // See if a placeholder was created for us already
96131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        FolderInfo folderInfo = folders.get(id);
96231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
96331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // No placeholder -- create a new instance
96431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            folderInfo = new UserFolderInfo();
96531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            folders.put(id, folderInfo);
96631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
96731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return (UserFolderInfo) folderInfo;
96831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
96931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
97031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
97131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
97231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * new one.
97331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
97431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
97531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // See if a placeholder was created for us already
97631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        FolderInfo folderInfo = folders.get(id);
97731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
97831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // No placeholder -- create a new instance
97931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            folderInfo = new LiveFolderInfo();
98031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            folders.put(id, folderInfo);
98131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
98231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return (LiveFolderInfo) folderInfo;
98331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
98431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
98531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
98631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove the callback for the cached drawables or we leak the previous
98731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Home screen on orientation change.
98831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
98931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void unbind() {
990f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        // Interrupt the applications loader before setting the adapter to null
991f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        stopAndWaitForApplicationsLoader();
99231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mApplicationsAdapter = null;
99331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        unbindAppDrawables(mApplications);
99431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        unbindDrawables(mDesktopItems);
9957376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project        unbindAppWidgetHostViews(mDesktopAppWidgets);
996bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        unbindCachedIconDrawables();
99731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
998bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
99931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
100031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove the callback for the cached drawables or we leak the previous
100131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Home screen on orientation change.
100231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
100331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private void unbindDrawables(ArrayList<ItemInfo> desktopItems) {
100431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (desktopItems != null) {
100531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final int count = desktopItems.size();
100631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
100731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                ItemInfo item = desktopItems.get(i);
100831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                switch (item.itemType) {
100931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
101031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
101131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    ((ApplicationInfo)item).icon.setCallback(null);
101231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    break;
101331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
101431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
101531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
101631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
1017bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
101831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
101931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove the callback for the cached drawables or we leak the previous
102031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Home screen on orientation change.
102131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
102231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private void unbindAppDrawables(ArrayList<ApplicationInfo> applications) {
102331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (applications != null) {
102431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final int count = applications.size();
102531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
102631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                applications.get(i).icon.setCallback(null);
102731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
102831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
102931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
103031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
103131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
10327376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project     * Remove any {@link LauncherAppWidgetHostView} references in our widgets.
103331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
10347376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project    private void unbindAppWidgetHostViews(ArrayList<LauncherAppWidgetInfo> appWidgets) {
10357376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project        if (appWidgets != null) {
10367376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project            final int count = appWidgets.size();
103731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
10387376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project                LauncherAppWidgetInfo launcherInfo = appWidgets.get(i);
103931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                launcherInfo.hostView = null;
104031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
104131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
104231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
104331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
104431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
1045bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * Remove the callback for the cached drawables or we leak the previous
1046bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * Home screen on orientation change.
1047bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     */
1048bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    private void unbindCachedIconDrawables() {
1049bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        for (ApplicationInfo appInfo : mAppInfoCache.values()) {
1050bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            appInfo.icon.setCallback(null);
1051bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        }
1052bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    }
1053bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
1054bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    /**
105531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return The current list of applications
105631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1057ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    ApplicationsAdapter getApplicationsAdapter() {
105831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mApplicationsAdapter;
105931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
106031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
106131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
106231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return The current list of desktop items
106331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1064ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    ArrayList<ItemInfo> getDesktopItems() {
106531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mDesktopItems;
106631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
106731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
106831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
106931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return The current list of desktop items
107031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1071ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    ArrayList<LauncherAppWidgetInfo> getDesktopAppWidgets() {
10727376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project        return mDesktopAppWidgets;
107331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
107431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
107531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
107631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Add an item to the desktop
107731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param info
107831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1079ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    void addDesktopItem(ItemInfo info) {
108031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // TODO: write to DB; also check that folder has been added to folders list
108131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopItems.add(info);
108231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
108331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
108431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
108531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove an item from the desktop
108631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param info
108731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1088ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    void removeDesktopItem(ItemInfo info) {
108931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // TODO: write to DB; figure out if we should remove folder from folders list
109031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopItems.remove(info);
109131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
109231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
109331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
10947376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project     * Add a widget to the desktop
109531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1096ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    void addDesktopAppWidget(LauncherAppWidgetInfo info) {
10977376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project        mDesktopAppWidgets.add(info);
109831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
109931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
110031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
11017376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project     * Remove a widget from the desktop
110231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1103ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project    void removeDesktopAppWidget(LauncherAppWidgetInfo info) {
11047376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project        mDesktopAppWidgets.remove(info);
110531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
110631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
110731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
110831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Make an ApplicationInfo object for an application
110931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
111031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static ApplicationInfo getApplicationInfo(PackageManager manager, Intent intent) {
111131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
111231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
111331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (resolveInfo == null) {
111431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return null;
111531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
111631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
111731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ApplicationInfo info = new ApplicationInfo();
111831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ActivityInfo activityInfo = resolveInfo.activityInfo;
111931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        info.icon = activityInfo.loadIcon(manager);
112031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (info.title == null || info.title.length() == 0) {
112131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            info.title = activityInfo.loadLabel(manager);
112231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
112331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (info.title == null) {
112431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            info.title = "";
112531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
112631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
112731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return info;
112831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
112931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
113031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
113131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Make an ApplicationInfo object for a sortcut
113231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
113331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private ApplicationInfo getApplicationInfoShortcut(Cursor c, Launcher launcher,
113431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) {
113531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
113631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ApplicationInfo info = new ApplicationInfo();
113731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
113831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
113931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        int iconType = c.getInt(iconTypeIndex);
114031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        switch (iconType) {
114131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
114231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String packageName = c.getString(iconPackageIndex);
114331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String resourceName = c.getString(iconResourceIndex);
114431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                PackageManager packageManager = launcher.getPackageManager();
114531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                try {
114631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    Resources resources = packageManager.getResourcesForApplication(packageName);
114731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    final int id = resources.getIdentifier(resourceName, null, null);
114831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    info.icon = resources.getDrawable(id);
114931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (Exception e) {
115031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    info.icon = packageManager.getDefaultActivityIcon();
115131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
115231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.iconResource = new Intent.ShortcutIconResource();
115331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.iconResource.packageName = packageName;
115431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.iconResource.resourceName = resourceName;
115531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.customIcon = false;
115631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                break;
115731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
115831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                byte[] data = c.getBlob(iconIndex);
115931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
116031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.icon = new FastBitmapDrawable(
116131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        Utilities.createBitmapThumbnail(bitmap, launcher));
116231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.filtered = true;
116331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.customIcon = true;
116431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                break;
116531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            default:
116631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.icon = launcher.getPackageManager().getDefaultActivityIcon();
116731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.customIcon = false;
116831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                break;
116931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
117031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return info;
117131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
117231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
117331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
117431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove an item from the in-memory represention of a user folder. Does not change the DB.
117531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
117631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void removeUserFolderItem(UserFolderInfo folder, ItemInfo info) {
117731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        //noinspection SuspiciousMethodCalls
117831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        folder.contents.remove(info);
117931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
118031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
118131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
118231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Removes a UserFolder from the in-memory list of folders. Does not change the DB.
118331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param userFolderInfo
118431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
118531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void removeUserFolder(UserFolderInfo userFolderInfo) {
118631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mFolders.remove(userFolderInfo.id);
118731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
118831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
118931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
119031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Adds an item to the DB if it was not created previously, or move it to a new
119131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * <container, screen, cellX, cellY>
119231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
119331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container,
119431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int screen, int cellX, int cellY) {
119531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (item.container == ItemInfo.NO_ID) {
119631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // From all apps
119731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            addItemToDatabase(context, item, container, screen, cellX, cellY, false);
119831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } else {
119931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // From somewhere else
120031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            moveItemInDatabase(context, item, container, screen, cellX, cellY);
120131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
120231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
120331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
120431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
120531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Move an item in the DB to a new <container, screen, cellX, cellY>
120631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
120731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen,
120831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int cellX, int cellY) {
120931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.container = container;
121031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.screen = screen;
121131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.cellX = cellX;
121231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.cellY = cellY;
121331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
121431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentValues values = new ContentValues();
121531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
121631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
121731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        values.put(LauncherSettings.Favorites.CONTAINER, item.container);
121831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        values.put(LauncherSettings.Favorites.CELLX, item.cellX);
121931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        values.put(LauncherSettings.Favorites.CELLY, item.cellY);
122031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        values.put(LauncherSettings.Favorites.SCREEN, item.screen);
122131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
122231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
122331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
122431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
122531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
122631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Returns true if the shortcuts already exists in the database.
122731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * we identify a shortcut by its title and intent.
122831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
122931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static boolean shortcutExists(Context context, String title, Intent intent) {
123031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
123131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
123231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            new String[] { "title", "intent" }, "title=? and intent=?",
123331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            new String[] { title, intent.toURI() }, null);
123431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        boolean result = false;
123531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        try {
123631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            result = c.moveToFirst();
123731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } finally {
123831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            c.close();
123931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
124031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return result;
124131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
124231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
124331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    FolderInfo getFolderById(Context context, long id) {
124431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
124531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
124631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                "_id=? and itemType=? or itemType=?",
124731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                new String[] { String.valueOf(id),
124831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
124931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
125031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
125131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        try {
125231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (c.moveToFirst()) {
125331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
125431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
125531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
125631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
125731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
125831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
125931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
126031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                FolderInfo folderInfo = null;
126131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                switch (c.getInt(itemTypeIndex)) {
126231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
126331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        folderInfo = findOrMakeUserFolder(mFolders, id);
126431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        break;
126531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
126631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        folderInfo = findOrMakeLiveFolder(mFolders, id);
126731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        break;
126831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
126931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
127031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.title = c.getString(titleIndex);
127131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.id = id;
127231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.container = c.getInt(containerIndex);
127331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.screen = c.getInt(screenIndex);
127431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.cellX = c.getInt(cellXIndex);
127531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.cellY = c.getInt(cellYIndex);
127631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
127731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                return folderInfo;
127831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
127931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } finally {
128031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            c.close();
128131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
128231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
128331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return null;
128431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
128531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
128631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
128731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Add an item to the database in a specified container. Sets the container, screen, cellX and
128831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * cellY fields of the item. Also assigns an ID to the item.
128931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
129031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void addItemToDatabase(Context context, ItemInfo item, long container,
129131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int screen, int cellX, int cellY, boolean notify) {
129231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.container = container;
129331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.screen = screen;
129431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.cellX = cellX;
129531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.cellY = cellY;
129631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
129731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentValues values = new ContentValues();
129831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
129931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
130031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.onAddToDatabase(values);
130131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
130231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
130331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
130431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
130531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (result != null) {
130631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            item.id = Integer.parseInt(result.getPathSegments().get(1));
130731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
130831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
130931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
131031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
131131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Update an item to the database in a specified container.
131231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
131331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void updateItemInDatabase(Context context, ItemInfo item) {
131431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentValues values = new ContentValues();
131531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
131631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
131731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.onAddToDatabase(values);
131831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
131931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
132031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
132131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
132231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
132331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Removes the specified item from the database
132431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param context
132531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param item
132631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
132731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void deleteItemFromDatabase(Context context, ItemInfo item) {
132831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
132931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
133031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null);
133131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
133231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
133331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
133431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
133531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove the contents of the specified folder from the database
133631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
133731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
133831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
133931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
134031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
134131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.delete(LauncherSettings.Favorites.CONTENT_URI,
134231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
134331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
134431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
1345