LauncherModel.java revision bc219c3c127cb74cf4fe578f05022b745da921b8
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;
31bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Projectimport android.graphics.drawable.Drawable;
3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.net.Uri;
3331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport 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.Collections;
3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.HashMap;
3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.List;
4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.Comparator;
4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.lang.ref.WeakReference;
4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.text.Collator;
4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.net.URISyntaxException;
4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Maintains in-memory state of the Launcher. It is expected that there should be only one
4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * LauncherModel object held in a static. Also provide APIs for updating the database state
48bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project * for the Launcher.
4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpublic class LauncherModel {
5131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static final int UI_NOTIFICATION_RATE = 4;
5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static final int DEFAULT_APPLICATIONS_NUMBER = 42;
5331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static final long APPLICATION_NOT_RESPONDING_TIMEOUT = 5000;
54bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
56bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    private static final boolean DEBUG = false;
57bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
58bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    private 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;
6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private ArrayList<LauncherGadgetInfo> mDesktopGadgets;
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;
7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private Thread mLoader;
7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private Thread mDesktopLoader;
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
7731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    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        }
8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopItemsLoader.stop();
8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopItemsLoaded = false;
8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
89bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * Drop our cache of components to their lables & icons.  We do
90bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * this from Launcher when applications are added/removed.  It's a
91bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * bit overkill, but it's a rare operation anyway.
92bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     */
93bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    synchronized void dropApplicationCache() {
94bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        mAppInfoCache.clear();
95bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    }
96bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
97bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    /**
9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Loads the list of installed applications in mApplications.
9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
100bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    synchronized void loadApplications(boolean isLaunching, Launcher launcher,
101bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            boolean localeChanged) {
102bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        if (localeChanged) {
103bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            dropApplicationCache();
104bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        }
10531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (isLaunching && mApplicationsLoaded && !localeChanged) {
10631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return;
10831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mApplicationsAdapter == null || isLaunching || localeChanged) {
111bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            mApplications = new ArrayList<ApplicationInfo>(DEFAULT_APPLICATIONS_NUMBER);
112bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            mApplicationsAdapter = new ApplicationsAdapter(launcher, mApplications);
11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
11431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
11531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mApplicationsLoader != null && mApplicationsLoader.isRunning()) {
11631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mApplicationsLoader.stop();
11731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // Wait for the currently running thread to finish, this can take a little
11831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // time but it should be well below the timeout limit
11931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            try {
12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                mLoader.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            } catch (InterruptedException e) {
12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                // Empty
12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mApplicationsLoaded = false;
12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (!isLaunching) {
12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            startApplicationsLoader(launcher);
13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private void startApplicationsLoader(Launcher launcher) {
13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mApplicationsLoader = new ApplicationsLoader(launcher);
13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mLoader = new Thread(mApplicationsLoader, "Applications Loader");
13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mLoader.start();
13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private class ApplicationsLoader implements Runnable {
14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final WeakReference<Launcher> mLauncher;
14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private volatile boolean mStopped;
14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private volatile boolean mRunning;
14431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        ApplicationsLoader(Launcher launcher) {
14631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mLauncher = new WeakReference<Launcher>(launcher);
14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
14831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void stop() {
15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mStopped = true;
15131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        boolean isRunning() {
15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return mRunning;
15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
15731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        public void run() {
15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mRunning = true;
15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
16131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final Launcher launcher = mLauncher.get();
16631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final PackageManager manager = launcher.getPackageManager();
16731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
16831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
16931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (apps != null && !mStopped) {
17031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int count = apps.size();
17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final ApplicationsAdapter applicationList = mApplicationsAdapter;
17231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                ChangeNotifier action = new ChangeNotifier(applicationList);
17431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                for (int i = 0; i < count && !mStopped; i++) {
17631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    ResolveInfo info = apps.get(i);
177bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                    ComponentName componentName = new ComponentName(
17831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            info.activityInfo.applicationInfo.packageName,
179bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                            info.activityInfo.name);
180bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                    ApplicationInfo application = mAppInfoCache.get(componentName);
181bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                    if (application == null) {
182bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        application = new ApplicationInfo();
183bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        application.title = info.loadLabel(manager);
184bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        if (application.title == null) {
185bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                            application.title = info.activityInfo.name;
186bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        }
187bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        application.setActivity(componentName,
188bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                                Intent.FLAG_ACTIVITY_NEW_TASK |
189bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                                Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
190bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        application.container = ItemInfo.NO_ID;
191bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        application.icon = info.activityInfo.loadIcon(manager);
192bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        if (DEBUG) {
193bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                            Log.d(Launcher.LOG_TAG, "Loaded ApplicationInfo for " + componentName);
194bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        }
195bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        mAppInfoCache.put(componentName, application);
196bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                    }
19731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
19831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    action.add(application);
19931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
20031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
20131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                action.sort(new Comparator<ApplicationInfo>() {
20231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    public final int compare(ApplicationInfo a, ApplicationInfo b) {
20331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        return sCollator.compare(a.title.toString(), b.title.toString());
20431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
20531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                });
20631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
20731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                if (!mStopped) {
20831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    launcher.runOnUiThread(action);
20931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
21031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
21131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (!mStopped) {
21331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                mApplicationsLoaded = true;
21431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
21531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mRunning = false;
21631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
21731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
21831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
21931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static class ChangeNotifier implements Runnable {
22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final ApplicationsAdapter mApplicationList;
221bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        private final ArrayList<ApplicationInfo> mBuffer;
22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
22331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        ChangeNotifier(ApplicationsAdapter applicationList) {
22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mApplicationList = applicationList;
22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mBuffer = new ArrayList<ApplicationInfo>(UI_NOTIFICATION_RATE);
22631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
22731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
22831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        public void run() {
22931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final ArrayList<ApplicationInfo> buffer = mBuffer;
23031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final ApplicationsAdapter applicationList = mApplicationList;
23131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final int count = buffer.size();
23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            applicationList.setNotifyOnChange(false);
23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            applicationList.clear();
23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                applicationList.setNotifyOnChange(false);
23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                applicationList.add(buffer.get(i));
23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
23931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
24031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            applicationList.notifyDataSetChanged();
24131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            buffer.clear();
24231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
24331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
24431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void add(ApplicationInfo application) {
24531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mBuffer.add(application);
24631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
24731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
24831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void sort(Comparator<ApplicationInfo> comparator) {
24931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            Collections.sort(mBuffer, comparator);
25031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
25131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
25231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
25331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    boolean isDesktopLoaded() {
25431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mDesktopItems != null && mDesktopGadgets != null && mDesktopItemsLoaded;
25531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
256bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
25731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
25831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Loads all of the items on the desktop, in folders, or in the dock.
25931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * These can be apps, shortcuts or widgets
26031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
26131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void loadUserItems(boolean isLaunching, Launcher launcher, boolean localeChanged,
26231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            boolean loadApplications) {
26331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
26431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (isLaunching && isDesktopLoaded()) {
26531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (loadApplications) startApplicationsLoader(launcher);
26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // We have already loaded our data from the DB
26731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            launcher.onDesktopItemsLoaded();
26831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return;
26931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
27031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
27131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (mDesktopItemsLoader != null && mDesktopItemsLoader.isRunning()) {
27231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopItemsLoader.stop();
27331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // Wait for the currently running thread to finish, this can take a little
27431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // time but it should be well below the timeout limit
27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            try {
27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                mDesktopLoader.join(APPLICATION_NOT_RESPONDING_TIMEOUT);
27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            } catch (InterruptedException e) {
27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                // Empty
27931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
28031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
28131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
28231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopItemsLoaded = false;
28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopItemsLoader = new DesktopItemsLoader(launcher, localeChanged, loadApplications);
28431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopLoader = new Thread(mDesktopItemsLoader, "Desktop Items Loader");
28531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopLoader.start();
28631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
28831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static void updateShortcutLabels(ContentResolver resolver, PackageManager manager) {
28931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final Cursor c = resolver.query(LauncherSettings.Favorites.CONTENT_URI,
29031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                new String[] { LauncherSettings.Favorites.ID, LauncherSettings.Favorites.TITLE,
29131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        LauncherSettings.Favorites.INTENT, LauncherSettings.Favorites.ITEM_TYPE },
29231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                null, null, null);
29331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
29631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
29731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
29931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // boolean changed = false;
30031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
30131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        try {
30231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            while (c.moveToNext()) {
30331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                try {
30431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    if (c.getInt(itemTypeIndex) !=
30531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        continue;
30731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
30831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
30931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    final String intentUri = c.getString(intentIndex);
31031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    if (intentUri != null) {
31131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        final Intent shortcut = Intent.getIntent(intentUri);
31231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        if (Intent.ACTION_MAIN.equals(shortcut.getAction())) {
31331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            final ComponentName name = shortcut.getComponent();
31431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (name != null) {
31531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                final ActivityInfo activityInfo = manager.getActivityInfo(name, 0);
31631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                final String title = c.getString(titleIndex);
31731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                String label = getLabel(manager, activityInfo);
31831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
31931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                if (title == null || !title.equals(label)) {
32031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    final ContentValues values = new ContentValues();
32131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    values.put(LauncherSettings.Favorites.TITLE, label);
32231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
32331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    resolver.update(LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION,
32431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                            values, "_id=?",
32531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                            new String[] { String.valueOf(c.getLong(idIndex)) });
32631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
32731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    // changed = true;
32831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                }
32931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
33031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        }
33131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
33231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (URISyntaxException e) {
33331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    // Ignore
33431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (PackageManager.NameNotFoundException e) {
33531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    // Ignore
33631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
33731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
33831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } finally {
33931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            c.close();
34031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
34131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
34231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // if (changed) resolver.notifyChange(Settings.Favorites.CONTENT_URI, null);
34331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
34431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
34531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
34631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        String label = activityInfo.loadLabel(manager).toString();
34731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (label == null) {
34831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
34931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (label == null) {
35031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                label = activityInfo.name;
35131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
35231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
35331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return label;
35431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
35531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
35631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private class DesktopItemsLoader implements Runnable {
35731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private volatile boolean mStopped;
35831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private volatile boolean mRunning;
35931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
36031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final WeakReference<Launcher> mLauncher;
36131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final boolean mLocaleChanged;
36231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        private final boolean mLoadApplications;
36331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
36431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        DesktopItemsLoader(Launcher launcher, boolean localeChanged, boolean loadApplications) {
36531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mLoadApplications = loadApplications;
36631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mLauncher = new WeakReference<Launcher>(launcher);
36731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mLocaleChanged = localeChanged;
36831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
36931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
37031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void stop() {
37131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mStopped = true;
37231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
37331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
37431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        boolean isRunning() {
37531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return mRunning;
37631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
37731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
37831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        public void run() {
37931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mRunning = true;
38031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
38131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final Launcher launcher = mLauncher.get();
38231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final ContentResolver contentResolver = launcher.getContentResolver();
38331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final PackageManager manager = launcher.getPackageManager();
38431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
38531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (mLocaleChanged) {
38631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                updateShortcutLabels(contentResolver, manager);
38731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
38831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
38931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopItems = new ArrayList<ItemInfo>();
39031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mDesktopGadgets = new ArrayList<LauncherGadgetInfo>();
39131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mFolders = new HashMap<Long, FolderInfo>();
39231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
39331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final ArrayList<ItemInfo> desktopItems = mDesktopItems;
39431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final ArrayList<LauncherGadgetInfo> desktopGadgets = mDesktopGadgets;
39531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
39631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final Cursor c = contentResolver.query(
39731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
39831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
39931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            try {
40031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ID);
40131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
40231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
40331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int iconTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_TYPE);
40431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
40531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int iconPackageIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_PACKAGE);
40631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE);
40731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
40831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
40931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int gadgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.GADGET_ID);
41031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
41131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
41231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
41331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
41431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
41531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI);
41631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE);
41731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
41831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                ApplicationInfo info;
41931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String intentDescription;
42031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                Widget widgetInfo;
42131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                LauncherGadgetInfo gadgetInfo;
42231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                int container;
42331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                long id;
42431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                Intent intent;
42531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
42631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final HashMap<Long, FolderInfo> folders = mFolders;
42731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
42831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                while (!mStopped && c.moveToNext()) {
42931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    try {
43031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        int itemType = c.getInt(itemTypeIndex);
43131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
43231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        switch (itemType) {
43331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
43431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
43531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            intentDescription = c.getString(intentIndex);
43631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            try {
43731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                intent = Intent.getIntent(intentDescription);
43831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            } catch (java.net.URISyntaxException e) {
43931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                continue;
44031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
44131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
44231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
44331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info = getApplicationInfo(manager, intent);
44431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            } else {
44531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info = getApplicationInfoShortcut(c, launcher, iconTypeIndex,
44631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                        iconPackageIndex, iconResourceIndex, iconIndex);
44731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
44831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
44931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (info == null) {
45031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info = new ApplicationInfo();
45131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.icon = manager.getDefaultActivityIcon();
45231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
45331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
45431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (info != null) {
45531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.title = c.getString(titleIndex);
45631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.intent = intent;
45731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
45831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.id = c.getLong(idIndex);
45931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                container = c.getInt(containerIndex);
46031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.container = container;
46131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.screen = c.getInt(screenIndex);
46231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.cellX = c.getInt(cellXIndex);
46331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                info.cellY = c.getInt(cellYIndex);
46431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
46531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                switch (container) {
46631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
46731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    desktopItems.add(info);
46831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    break;
46931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                default:
47031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    // Item is in a user folder
47131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    UserFolderInfo folderInfo =
47231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                            findOrMakeUserFolder(folders, container);
47331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    folderInfo.add(info);
47431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    break;
47531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                }
47631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
47731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
47831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
47931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
48031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            id = c.getLong(idIndex);
48131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            UserFolderInfo folderInfo = findOrMakeUserFolder(folders, id);
48231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
48331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.title = c.getString(titleIndex);
48431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
48531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.id = id;
48631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            container = c.getInt(containerIndex);
48731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.container = container;
48831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.screen = c.getInt(screenIndex);
48931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.cellX = c.getInt(cellXIndex);
49031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            folderInfo.cellY = c.getInt(cellYIndex);
49131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
49231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            switch (container) {
49331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
49431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    desktopItems.add(folderInfo);
49531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    break;
49631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
49731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
49831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
49931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
50031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            id = c.getLong(idIndex);
50131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(folders, id);
50231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
50331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            intentDescription = c.getString(intentIndex);
50431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            intent = null;
50531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (intentDescription != null) {
50631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                try {
50731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    intent = Intent.getIntent(intentDescription);
50831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                } catch (java.net.URISyntaxException e) {
50931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    // Ignore, a live folder might not have a base intent
51031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                }
51131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
51231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
51331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.title = c.getString(titleIndex);
51431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.id = id;
51531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            container = c.getInt(containerIndex);
51631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.container = container;
51731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.screen = c.getInt(screenIndex);
51831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.cellX = c.getInt(cellXIndex);
51931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.cellY = c.getInt(cellYIndex);
52031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.uri = Uri.parse(c.getString(uriIndex));
52131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.baseIntent = intent;
52231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            liveFolderInfo.displayMode = c.getInt(displayModeIndex);
52331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
52431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            loadLiveFolderIcon(launcher, c, iconTypeIndex, iconPackageIndex,
52531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    iconResourceIndex, liveFolderInfo);
52631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
52731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            switch (container) {
52831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                case LauncherSettings.Favorites.CONTAINER_DESKTOP:
52931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    desktopItems.add(liveFolderInfo);
53031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                    break;
53131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
53231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
53331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH:
53431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo = Widget.makeSearch();
53531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
53631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            container = c.getInt(containerIndex);
53731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
53831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                Log.e(Launcher.LOG_TAG, "Widget found where container "
53931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                        + "!= CONTAINER_DESKTOP  ignoring!");
54031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                continue;
54131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
542bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
54331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.id = c.getLong(idIndex);
54431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.screen = c.getInt(screenIndex);
54531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.container = container;
54631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.cellX = c.getInt(cellXIndex);
54731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            widgetInfo.cellY = c.getInt(cellYIndex);
54831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
54931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            desktopItems.add(widgetInfo);
55031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
55131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        case LauncherSettings.Favorites.ITEM_TYPE_GADGET:
55231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            // Read all Launcher-specific gadget details
55331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            int gadgetId = c.getInt(gadgetIdIndex);
55431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            gadgetInfo = new LauncherGadgetInfo(gadgetId);
55531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            gadgetInfo.id = c.getLong(idIndex);
55631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            gadgetInfo.screen = c.getInt(screenIndex);
55731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            gadgetInfo.cellX = c.getInt(cellXIndex);
55831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            gadgetInfo.cellY = c.getInt(cellYIndex);
55931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            gadgetInfo.spanX = c.getInt(spanXIndex);
56031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            gadgetInfo.spanY = c.getInt(spanYIndex);
56131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
56231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            container = c.getInt(containerIndex);
56331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
56431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                Log.e(Launcher.LOG_TAG, "Gadget found where container "
56531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                        + "!= CONTAINER_DESKTOP -- ignoring!");
56631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                                continue;
56731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            }
56831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            gadgetInfo.container = c.getInt(containerIndex);
569bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
57031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            desktopGadgets.add(gadgetInfo);
57131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            break;
57231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        }
57331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    } catch (Exception e) {
57431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        Log.w(Launcher.LOG_TAG, "Desktop items loading interrupted:", e);
57531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
57631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
57731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            } finally {
57831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                c.close();
57931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
58031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
58131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (!mStopped) {
58231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                launcher.runOnUiThread(new Runnable() {
58331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    public void run() {
58431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        launcher.onDesktopItemsLoaded();
58531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
58631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                });
58731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                if (mLoadApplications) startApplicationsLoader(launcher);
58831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
58931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
59031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (!mStopped) {
59131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                mDesktopItemsLoaded = true;
59231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
59331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            mRunning = false;
59431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
59531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
59631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
59731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static void loadLiveFolderIcon(Launcher launcher, Cursor c, int iconTypeIndex,
59831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
59931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
60031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        int iconType = c.getInt(iconTypeIndex);
60131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        switch (iconType) {
60231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
60331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String packageName = c.getString(iconPackageIndex);
60431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String resourceName = c.getString(iconResourceIndex);
60531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                PackageManager packageManager = launcher.getPackageManager();
60631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                try {
60731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    Resources resources = packageManager.getResourcesForApplication(packageName);
60831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    final int id = resources.getIdentifier(resourceName, null, null);
60931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    liveFolderInfo.icon = resources.getDrawable(id);
61031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (Exception e) {
61131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    liveFolderInfo.icon =
61231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                            launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
61331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
61431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
61531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                liveFolderInfo.iconResource.packageName = packageName;
61631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                liveFolderInfo.iconResource.resourceName = resourceName;
61731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                break;
61831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            default:
61931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                liveFolderInfo.icon =
620bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project                        launcher.getResources().getDrawable(R.drawable.ic_launcher_folder);
62131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
62231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
62331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
62431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
62531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Finds the user folder defined by the specified id.
62631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
62731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param id The id of the folder to look for.
628bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     *
62931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return A UserFolderInfo if the folder exists or null otherwise.
63031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
63131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    FolderInfo findFolderById(long id) {
63231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mFolders.get(id);
63331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
63431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
63531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void addFolder(FolderInfo info) {
63631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mFolders.put(info.id, info);
63731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
63831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
63931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
64031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
64131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * new one.
64231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
64331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
64431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // See if a placeholder was created for us already
64531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        FolderInfo folderInfo = folders.get(id);
64631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
64731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // No placeholder -- create a new instance
64831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            folderInfo = new UserFolderInfo();
64931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            folders.put(id, folderInfo);
65031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
65131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return (UserFolderInfo) folderInfo;
65231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
65331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
65431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
65531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
65631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * new one.
65731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
65831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
65931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // See if a placeholder was created for us already
66031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        FolderInfo folderInfo = folders.get(id);
66131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
66231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // No placeholder -- create a new instance
66331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            folderInfo = new LiveFolderInfo();
66431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            folders.put(id, folderInfo);
66531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
66631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return (LiveFolderInfo) folderInfo;
66731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
66831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
66931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
67031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove the callback for the cached drawables or we leak the previous
67131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Home screen on orientation change.
67231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
67331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void unbind() {
67431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mApplicationsAdapter = null;
67531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        unbindAppDrawables(mApplications);
67631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        unbindDrawables(mDesktopItems);
67731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        unbindGadgetHostViews(mDesktopGadgets);
678bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        unbindCachedIconDrawables();
67931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
680bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
68131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
68231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove the callback for the cached drawables or we leak the previous
68331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Home screen on orientation change.
68431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
68531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private void unbindDrawables(ArrayList<ItemInfo> desktopItems) {
68631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (desktopItems != null) {
68731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final int count = desktopItems.size();
68831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
68931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                ItemInfo item = desktopItems.get(i);
69031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                switch (item.itemType) {
69131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
69231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
69331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    ((ApplicationInfo)item).icon.setCallback(null);
69431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    break;
69531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
69631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
69731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
69831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
699bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
70031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
70131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove the callback for the cached drawables or we leak the previous
70231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Home screen on orientation change.
70331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
70431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private void unbindAppDrawables(ArrayList<ApplicationInfo> applications) {
70531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (applications != null) {
70631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final int count = applications.size();
70731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
70831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                applications.get(i).icon.setCallback(null);
70931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
71031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
71131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
71231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
71331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
71431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove any {@link LauncherGadgetHostView} references in our gadgets.
71531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
71631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private void unbindGadgetHostViews(ArrayList<LauncherGadgetInfo> gadgets) {
71731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (gadgets != null) {
71831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final int count = gadgets.size();
71931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
72031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                LauncherGadgetInfo launcherInfo = gadgets.get(i);
72131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                launcherInfo.hostView = null;
72231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
72331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
72431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
72531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
72631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
727bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * Remove the callback for the cached drawables or we leak the previous
728bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     * Home screen on orientation change.
729bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project     */
730bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    private void unbindCachedIconDrawables() {
731bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        for (ApplicationInfo appInfo : mAppInfoCache.values()) {
732bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project            appInfo.icon.setCallback(null);
733bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project        }
734bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    }
735bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project
736bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project    /**
73731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return The current list of applications
73831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
73931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public ArrayList<ApplicationInfo> getApplications() {
74031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mApplications;
74131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
74231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
74331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
74431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return The current list of applications
74531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
74631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public ApplicationsAdapter getApplicationsAdapter() {
74731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mApplicationsAdapter;
74831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
74931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
75031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
75131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return The current list of desktop items
75231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
75331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public ArrayList<ItemInfo> getDesktopItems() {
75431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mDesktopItems;
75531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
75631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
75731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
75831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return The current list of desktop items
75931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
76031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public ArrayList<LauncherGadgetInfo> getDesktopGadgets() {
76131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mDesktopGadgets;
76231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
76331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
76431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
76531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Add an item to the desktop
76631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param info
76731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
76831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void addDesktopItem(ItemInfo info) {
76931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // TODO: write to DB; also check that folder has been added to folders list
77031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopItems.add(info);
77131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
77231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
77331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
77431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove an item from the desktop
77531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param info
77631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
77731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void removeDesktopItem(ItemInfo info) {
77831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // TODO: write to DB; figure out if we should remove folder from folders list
77931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopItems.remove(info);
78031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
78131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
78231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
78331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Add a gadget to the desktop
78431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
78531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void addDesktopGadget(LauncherGadgetInfo info) {
78631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopGadgets.add(info);
78731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
78831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
78931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
79031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove a gadget from the desktop
79131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
79231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void removeDesktopGadget(LauncherGadgetInfo info) {
79331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDesktopGadgets.remove(info);
79431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
79531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
79631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
79731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Make an ApplicationInfo object for an application
79831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
79931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private static ApplicationInfo getApplicationInfo(PackageManager manager, Intent intent) {
80031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ResolveInfo resolveInfo = manager.resolveActivity(intent, 0);
80131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
80231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (resolveInfo == null) {
80331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return null;
80431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
80531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
80631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ApplicationInfo info = new ApplicationInfo();
80731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ActivityInfo activityInfo = resolveInfo.activityInfo;
80831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        info.icon = activityInfo.loadIcon(manager);
80931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (info.title == null || info.title.length() == 0) {
81031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            info.title = activityInfo.loadLabel(manager);
81131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
81231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (info.title == null) {
81331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            info.title = "";
81431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
81531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
81631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return info;
81731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
81831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
81931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
82031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Make an ApplicationInfo object for a sortcut
82131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
82231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private ApplicationInfo getApplicationInfoShortcut(Cursor c, Launcher launcher,
82331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex) {
82431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
82531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ApplicationInfo info = new ApplicationInfo();
82631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
82731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
82831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        int iconType = c.getInt(iconTypeIndex);
82931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        switch (iconType) {
83031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
83131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String packageName = c.getString(iconPackageIndex);
83231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                String resourceName = c.getString(iconResourceIndex);
83331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                PackageManager packageManager = launcher.getPackageManager();
83431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                try {
83531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    Resources resources = packageManager.getResourcesForApplication(packageName);
83631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    final int id = resources.getIdentifier(resourceName, null, null);
83731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    info.icon = resources.getDrawable(id);
83831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                } catch (Exception e) {
83931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    info.icon = packageManager.getDefaultActivityIcon();
84031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
84131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.iconResource = new Intent.ShortcutIconResource();
84231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.iconResource.packageName = packageName;
84331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.iconResource.resourceName = resourceName;
84431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.customIcon = false;
84531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                break;
84631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            case LauncherSettings.Favorites.ICON_TYPE_BITMAP:
84731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                byte[] data = c.getBlob(iconIndex);
84831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
84931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.icon = new FastBitmapDrawable(
85031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        Utilities.createBitmapThumbnail(bitmap, launcher));
85131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.filtered = true;
85231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.customIcon = true;
85331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                break;
85431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            default:
85531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.icon = launcher.getPackageManager().getDefaultActivityIcon();
85631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                info.customIcon = false;
85731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                break;
85831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
85931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return info;
86031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
86131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
86231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
86331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove an item from the in-memory represention of a user folder. Does not change the DB.
86431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
86531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void removeUserFolderItem(UserFolderInfo folder, ItemInfo info) {
86631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        //noinspection SuspiciousMethodCalls
86731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        folder.contents.remove(info);
86831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
86931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
87031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
87131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Removes a UserFolder from the in-memory list of folders. Does not change the DB.
87231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param userFolderInfo
87331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
87431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void removeUserFolder(UserFolderInfo userFolderInfo) {
87531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mFolders.remove(userFolderInfo.id);
87631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
87731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
87831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
87931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Adds an item to the DB if it was not created previously, or move it to a new
88031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * <container, screen, cellX, cellY>
88131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
88231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container,
88331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int screen, int cellX, int cellY) {
88431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (item.container == ItemInfo.NO_ID) {
88531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // From all apps
88631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            addItemToDatabase(context, item, container, screen, cellX, cellY, false);
88731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } else {
88831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // From somewhere else
88931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            moveItemInDatabase(context, item, container, screen, cellX, cellY);
89031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
89131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
89231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
89331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
89431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Move an item in the DB to a new <container, screen, cellX, cellY>
89531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
89631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen,
89731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int cellX, int cellY) {
89831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.container = container;
89931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.screen = screen;
90031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.cellX = cellX;
90131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.cellY = cellY;
90231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
90331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentValues values = new ContentValues();
90431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
90531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
90631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        values.put(LauncherSettings.Favorites.CONTAINER, item.container);
90731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        values.put(LauncherSettings.Favorites.CELLX, item.cellX);
90831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        values.put(LauncherSettings.Favorites.CELLY, item.cellY);
90931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        values.put(LauncherSettings.Favorites.SCREEN, item.screen);
91031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
91131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
91231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
91331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
91431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
91531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Returns true if the shortcuts already exists in the database.
91631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * we identify a shortcut by its title and intent.
91731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
91831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static boolean shortcutExists(Context context, String title, Intent intent) {
91931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
92031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
92131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            new String[] { "title", "intent" }, "title=? and intent=?",
92231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            new String[] { title, intent.toURI() }, null);
92331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        boolean result = false;
92431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        try {
92531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            result = c.moveToFirst();
92631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } finally {
92731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            c.close();
92831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
92931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return result;
93031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
93131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
93231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    FolderInfo getFolderById(Context context, long id) {
93331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
93431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
93531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                "_id=? and itemType=? or itemType=?",
93631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                new String[] { String.valueOf(id),
93731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
93831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
93931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
94031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        try {
94131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (c.moveToFirst()) {
94231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
94331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE);
94431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
94531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
94631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
94731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
94831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
94931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                FolderInfo folderInfo = null;
95031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                switch (c.getInt(itemTypeIndex)) {
95131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
95231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        folderInfo = findOrMakeUserFolder(mFolders, id);
95331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        break;
95431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
95531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        folderInfo = findOrMakeLiveFolder(mFolders, id);
95631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        break;
95731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
95831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
95931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.title = c.getString(titleIndex);
96031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.id = id;
96131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.container = c.getInt(containerIndex);
96231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.screen = c.getInt(screenIndex);
96331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.cellX = c.getInt(cellXIndex);
96431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                folderInfo.cellY = c.getInt(cellYIndex);
96531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
96631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                return folderInfo;
96731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
96831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } finally {
96931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            c.close();
97031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
97131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
97231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return null;
97331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
97431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
97531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
97631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Add an item to the database in a specified container. Sets the container, screen, cellX and
97731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * cellY fields of the item. Also assigns an ID to the item.
97831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
97931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void addItemToDatabase(Context context, ItemInfo item, long container,
98031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int screen, int cellX, int cellY, boolean notify) {
98131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.container = container;
98231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.screen = screen;
98331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.cellX = cellX;
98431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.cellY = cellY;
98531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
98631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentValues values = new ContentValues();
98731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
98831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
98931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.onAddToDatabase(values);
99031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
99131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
99231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
99331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
99431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (result != null) {
99531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            item.id = Integer.parseInt(result.getPathSegments().get(1));
99631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
99731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
99831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
99931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
100031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Update an item to the database in a specified container.
100131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
100231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void updateItemInDatabase(Context context, ItemInfo item) {
100331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentValues values = new ContentValues();
100431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
100531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
100631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        item.onAddToDatabase(values);
100731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
100831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
100931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
101031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
101131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
101231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Removes the specified item from the database
101331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param context
101431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param item
101531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
101631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void deleteItemFromDatabase(Context context, ItemInfo item) {
101731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
101831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
101931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.delete(LauncherSettings.Favorites.getContentUri(item.id, false), null, null);
102031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
102131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
102231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
102331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
102431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove the contents of the specified folder from the database
102531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
102631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
102731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final ContentResolver cr = context.getContentResolver();
102831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
102931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
103031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        cr.delete(LauncherSettings.Favorites.CONTENT_URI,
103131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
103231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
103331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
1034