LauncherModel.java revision dcd297f05a866e07090d6e2af8fb4b15f28cb555
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 17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19cb1a4778686a46c46d8dc88b6c83674f6fac6592Narayan Kamathimport android.app.SearchManager; 20629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetManager; 21629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetProviderInfo; 22f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onoratoimport android.content.BroadcastReceiver; 2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ComponentName; 245c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.content.ContentProviderClient; 25f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohenimport android.content.ContentProviderOperation; 2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ContentResolver; 2731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.ContentValues; 28aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.content.Context; 2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Intent; 300589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.content.Intent.ShortcutIconResource; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ActivityInfo; 3200fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohenimport android.content.pm.PackageInfo; 3331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.PackageManager; 3400fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohenimport android.content.pm.PackageManager.NameNotFoundException; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ResolveInfo; 3693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Leeimport android.content.res.Configuration; 3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.Resources; 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.database.Cursor; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.BitmapFactory; 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.net.Uri; 4217a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onoratoimport android.os.Environment; 433611578579b4bfb25616085dafdb1a45207394f9Joe Onoratoimport android.os.Handler; 443611578579b4bfb25616085dafdb1a45207394f9Joe Onoratoimport android.os.HandlerThread; 450589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.os.Parcelable; 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Process; 47aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.os.RemoteException; 489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.SystemClock; 49aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.util.Log; 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 51325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerimport com.android.launcher3.InstallWidgetReceiver.WidgetMimeTypeHandlerData; 52edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 53c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.lang.ref.WeakReference; 54c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.net.URISyntaxException; 55c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.text.Collator; 56c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.ArrayList; 57dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohenimport java.util.Arrays; 58c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.Collections; 59c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.Comparator; 60c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.HashMap; 61b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chungimport java.util.HashSet; 622abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chungimport java.util.Iterator; 63c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.List; 64b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chungimport java.util.Set; 65dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohenimport java.util.TreeMap; 66c2f801e770b4f80354b3edb722ec04222251990cMichael Jurka 6731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Maintains in-memory state of the Launcher. It is expected that there should be only one 6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * LauncherModel object held in a static. Also provide APIs for updating the database state 70bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project * for the Launcher. 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 72f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onoratopublic class LauncherModel extends BroadcastReceiver { 73a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato static final boolean DEBUG_LOADERS = false; 749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static final String TAG = "Launcher.Model"; 759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons 7717a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato private final boolean mAppsCanBeOnExternalStorage; 78d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato private int mBatchSize; // 0 is all apps at once 792ff10b3b0137d258569ce5471808842e88696133Daniel Sandler private int mAllAppsLoadDelay; // milliseconds between batches 80dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 81cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private final LauncherAppState mApp; 829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private final Object mLock = new Object(); 839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private DeferredHandler mHandler = new DeferredHandler(); 843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private LoaderTask mLoaderTask; 85b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private boolean mIsLoaderTaskRunning; 86c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka private volatile boolean mFlushingWorkerThread; 879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 8881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Specific runnable types that are run on the main thread deferred handler, this allows us to 8981b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // clear all queued binding runnables when the Launcher activity is destroyed. 9081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung private static final int MAIN_THREAD_NORMAL_RUNNABLE = 0; 9181b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung private static final int MAIN_THREAD_BINDING_RUNNABLE = 1; 9281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung 9381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung 94700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); 95700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick static { 96700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick sWorkerThread.start(); 97700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick } 98700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick private static final Handler sWorker = new Handler(sWorkerThread.getLooper()); 99700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick 100cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // We start off with everything not loaded. After that, we assume that 101cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // our monitoring of the package manager provides all updates and we never 102cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // need to do a requery. These are only ever touched from the loader thread. 103cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato private boolean mWorkspaceLoaded; 104cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato private boolean mAllAppsLoaded; 105cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 106b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // When we are loading pages synchronously, we can't just post the binding of items on the side 107b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // pages as this delays the rotation process. Instead, we wait for a callback from the first 108b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // draw (in Workspace) to initiate the binding of the remaining side pages. Any time we start 109b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // a normal load, we also clear this set of Runnables. 110b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung static final ArrayList<Runnable> mDeferredBindRunnables = new ArrayList<Runnable>(); 111b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private WeakReference<Callbacks> mCallbacks; 1139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 114a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // < only access in worker thread > 115487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen private AllAppsList mBgAllAppsList; 116a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 117b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // The lock that must be acquired before referencing any static bg data structures. Unlike 118b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // other locks, this one can generally be held long-term because we never expect any of these 119b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // static data structures to be referenced outside of the worker thread except on the first 120b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // load after configuration change. 1212abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung static final Object sBgLock = new Object(); 122b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 123487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgItemsIdMap maps *all* the ItemInfos (shortcuts, folders, and widgets) created by 124a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // LauncherModel to their ids 125487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final HashMap<Long, ItemInfo> sBgItemsIdMap = new HashMap<Long, ItemInfo>(); 126a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 127487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgWorkspaceItems is passed to bindItems, which expects a list of all folders and shortcuts 128487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // created by LauncherModel that are directly on the home screen (however, no widgets or 129487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // shortcuts within folders). 130487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final ArrayList<ItemInfo> sBgWorkspaceItems = new ArrayList<ItemInfo>(); 1310589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 132487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgAppWidgets is all LauncherAppWidgetInfo created by LauncherModel. Passed to bindAppWidget() 133487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final ArrayList<LauncherAppWidgetInfo> sBgAppWidgets = 134a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka new ArrayList<LauncherAppWidgetInfo>(); 135a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 136487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgFolders is all FolderInfos created by LauncherModel. Passed to bindFolders() 137487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final HashMap<Long, FolderInfo> sBgFolders = new HashMap<Long, FolderInfo>(); 138b1094bd9630f659cc606853b8a244b6a6b6c6943Winson Chung 139487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgDbIconCache is the set of ItemInfos that need to have their icons updated in the database 140487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final HashMap<Object, byte[]> sBgDbIconCache = new HashMap<Object, byte[]>(); 141dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 142dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // sBgWorkspaceScreens is the ordered set of workspace screens. 143dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen static final ArrayList<Long> sBgWorkspaceScreens = new ArrayList<Long>(); 144dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 145a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // </ only access in worker thread > 146a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 147a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka private IconCache mIconCache; 1480589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private Bitmap mDefaultIcon; 1499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 150d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen private static int mCellCountX; 151d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen private static int mCellCountY; 152aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 15399a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee protected int mPreviousConfigMcc; 15493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 1559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public interface Callbacks { 156ef2efcff5e70e5900f4f10f9e46c3fa17c03b0ecJoe Onorato public boolean setLoadOnResume(); 1579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public int getCurrentWorkspaceScreen(); 1589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startBinding(); 1599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end); 160dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void bindScreens(ArrayList<Long> orderedScreenIds); 161ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato public void bindFolders(HashMap<Long,FolderInfo> folders); 162e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen public void finishBindingItems(boolean upgradePath); 1639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAppWidget(LauncherAppWidgetInfo info); 1649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAllApplications(ArrayList<ApplicationInfo> apps); 16564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato public void bindAppsAdded(ArrayList<ApplicationInfo> apps); 16664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato public void bindAppsUpdated(ArrayList<ApplicationInfo> apps); 16783892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung public void bindComponentsRemoved(ArrayList<String> packageNames, 16883892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung ArrayList<ApplicationInfo> appInfos, 16983892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung boolean matchPackageNamesOnly); 170c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts); 171843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler public boolean isAllAppsVisible(); 1720dca1ec41479a74f8da080224fa0c7eacab674d6Andrew Flynn public boolean isAllAppsButtonRank(int rank); 173cb1a4778686a46c46d8dc88b6c83674f6fac6592Narayan Kamath public void bindSearchablesChanged(); 1741462de39f01cec0ba785386532719cb0207dd827Adam Cohen public void onPageBoundSynchronously(int page); 1759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 17631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 177cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherModel(Context context, IconCache iconCache) { 17817a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato mAppsCanBeOnExternalStorage = !Environment.isExternalStorageEmulated(); 179cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mApp = LauncherAppState.getInstance(); 180487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mBgAllAppsList = new AllAppsList(iconCache); 1810589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = iconCache; 1820589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 1830589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mDefaultIcon = Utilities.createIconBitmap( 184cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mIconCache.getFullResDefaultActivityIcon(), context); 1852ff10b3b0137d258569ce5471808842e88696133Daniel Sandler 186cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler final Resources res = context.getResources(); 18793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mAllAppsLoadDelay = res.getInteger(R.integer.config_allAppsBatchLoadDelay); 18893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mBatchSize = res.getInteger(R.integer.config_allAppsBatchSize); 18999a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee Configuration config = res.getConfiguration(); 19099a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee mPreviousConfigMcc = config.mcc; 1910589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 1920589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 193b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Runs the specified runnable immediately if called from the main thread, otherwise it is 194b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * posted on the main thread handler. */ 195b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void runOnMainThread(Runnable r) { 19681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, 0); 19781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung } 19881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung private void runOnMainThread(Runnable r, int type) { 199b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 200b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we are on the worker thread, post onto the main handler 201b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mHandler.post(r); 202b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 203b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r.run(); 204b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 205b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 206b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 207b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Runs the specified runnable immediately if called from the worker thread, otherwise it is 208b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * posted on the worker thread handler. */ 209b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private static void runOnWorkerThread(Runnable r) { 210b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 211b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r.run(); 212b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 213b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we are not on the worker thread, then post to the worker handler 214b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorker.post(r); 215b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 216b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 217b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 21856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public Bitmap getFallbackIcon() { 2190589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return Bitmap.createBitmap(mDefaultIcon); 220f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato } 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung public void unbindItemInfosAndClearQueuedBindRunnables() { 22381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 22481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung throw new RuntimeException("Expected unbindLauncherItemInfos() to be called from the " + 22581b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung "main thread"); 22681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung } 22781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung 22881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Clear any deferred bind runnables 22981b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung mDeferredBindRunnables.clear(); 23081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Remove any queued bind runnables 23181b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung mHandler.cancelAllRunnablesOfType(MAIN_THREAD_BINDING_RUNNABLE); 23281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Unbind all the workspace items 23381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung unbindWorkspaceItemsOnMainThread(); 234603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung } 235603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung 236b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Unbinds all the sBgWorkspaceItems and sBgAppWidgets on the main thread */ 23781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung void unbindWorkspaceItemsOnMainThread() { 238603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung // Ensure that we don't use the same workspace items data structure on the main thread 239603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung // by making a copy of workspace items first. 240b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<ItemInfo> tmpWorkspaceItems = new ArrayList<ItemInfo>(); 241b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<ItemInfo> tmpAppWidgets = new ArrayList<ItemInfo>(); 2422abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 243b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung tmpWorkspaceItems.addAll(sBgWorkspaceItems); 244b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung tmpAppWidgets.addAll(sBgAppWidgets); 245b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 246b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Runnable r = new Runnable() { 247b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 248b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 249b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo item : tmpWorkspaceItems) { 250b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.unbind(); 251b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 252b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo item : tmpAppWidgets) { 253b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.unbind(); 254b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 255b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 256b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 257b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnMainThread(r); 2584eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen } 2594eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen 2609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 2619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Adds an item to the DB if it was not created previously, or move it to a new 2629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * <container, screen, cellX, cellY> 2639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 2649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container, 265dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId, int cellX, int cellY) { 2669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (item.container == ItemInfo.NO_ID) { 2679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From all apps 268dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen addItemToDatabase(context, item, container, screenId, cellX, cellY, false); 2699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 2709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From somewhere else 271dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen moveItemInDatabase(context, item, container, screenId, cellX, cellY); 2729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 27431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 275b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka static void checkItemInfoLocked( 276b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka final long itemId, final ItemInfo item, StackTraceElement[] stackTrace) { 277b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ItemInfo modelItem = sBgItemsIdMap.get(itemId); 278b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelItem != null && item != modelItem) { 279b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // check all the data is consistent 280b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) { 281b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ShortcutInfo modelShortcut = (ShortcutInfo) modelItem; 282b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ShortcutInfo shortcut = (ShortcutInfo) item; 283b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelShortcut.title.toString().equals(shortcut.title.toString()) && 284b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.intent.filterEquals(shortcut.intent) && 285b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.id == shortcut.id && 286b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.itemType == shortcut.itemType && 287b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.container == shortcut.container && 288dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen modelShortcut.screenId == shortcut.screenId && 289b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.cellX == shortcut.cellX && 290b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.cellY == shortcut.cellY && 291b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.spanX == shortcut.spanX && 292b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.spanY == shortcut.spanY && 293b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ((modelShortcut.dropPos == null && shortcut.dropPos == null) || 294b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka (modelShortcut.dropPos != null && 295b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka shortcut.dropPos != null && 296b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.dropPos[0] == shortcut.dropPos[0] && 297b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.dropPos[1] == shortcut.dropPos[1]))) { 298b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // For all intents and purposes, this is the same object 299b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka return; 300b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 301b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 302b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka 303b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // the modelItem needs to match up perfectly with item if our model is 304b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // to be consistent with the database-- for now, just require 305b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // modelItem == item or the equality check above 306b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka String msg = "item: " + ((item != null) ? item.toString() : "null") + 307b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka "modelItem: " + 308b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ((modelItem != null) ? modelItem.toString() : "null") + 309b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka "Error: ItemInfo passed to checkItemInfo doesn't match original"; 310b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka RuntimeException e = new RuntimeException(msg); 311b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (stackTrace != null) { 312b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka e.setStackTrace(stackTrace); 313b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 314e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen // TODO: something breaks this in the upgrade path 315e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen //throw e; 316b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 317b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 318b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka 319816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka static void checkItemInfo(final ItemInfo item) { 320816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 321816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka final long itemId = item.id; 322816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka Runnable r = new Runnable() { 323b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka public void run() { 324b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka synchronized (sBgLock) { 325b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka checkItemInfoLocked(itemId, item, stackTrace); 326816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka } 327b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 328b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka }; 329b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 330816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka } 331816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka 332c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka static void updateItemInDatabaseHelper(Context context, final ContentValues values, 333c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ItemInfo item, final String callingFunction) { 334c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final long itemId = item.id; 335c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final Uri uri = LauncherSettings.Favorites.getContentUri(itemId, false); 336c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ContentResolver cr = context.getContentResolver(); 337c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 338487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 339c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 340c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka public void run() { 341c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.update(uri, values, null, null); 342f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemArrays(item, itemId, stackTrace); 343f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 344f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen }; 345f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen runOnWorkerThread(r); 346f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 347c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 348f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void updateItemsInDatabaseHelper(Context context, final ArrayList<ContentValues> valuesList, 349f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ArrayList<ItemInfo> items, final String callingFunction) { 350f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ContentResolver cr = context.getContentResolver(); 351c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 352f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 353f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Runnable r = new Runnable() { 354f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen public void run() { 355f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ContentProviderOperation> ops = 356f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen new ArrayList<ContentProviderOperation>(); 357f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int count = items.size(); 358f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < count; i++) { 359f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo item = items.get(i); 360f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final long itemId = item.id; 361f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final Uri uri = LauncherSettings.Favorites.getContentUri(itemId, false); 362f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ContentValues values = valuesList.get(i); 363f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 364f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build()); 365f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemArrays(item, itemId, stackTrace); 366487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen 367f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 368f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen try { 369f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen cr.applyBatch(LauncherProvider.AUTHORITY, ops); 370f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } catch (Exception e) { 371f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen e.printStackTrace(); 372c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 373c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 374c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 375b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 376c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 377bebf042666cffe52039b875a549a582abd78a431Adam Cohen 378f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void updateItemArrays(ItemInfo item, long itemId, StackTraceElement[] stackTrace) { 379f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Lock on mBgLock *after* the db operation 380f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen synchronized (sBgLock) { 381f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen checkItemInfoLocked(itemId, item, stackTrace); 382f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 383f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP && 384f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 385f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Item is in a folder, make sure this folder exists 386f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (!sBgFolders.containsKey(item.container)) { 387f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // An items container is being set to a that of an item which is not in 388f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // the list of Folders. 389f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen String msg = "item: " + item + " container being set to: " + 390f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container + ", not in the list of folders"; 391f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Log.e(TAG, msg); 392f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Launcher.dumpDebugLogsToConsole(); 393f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 394f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 395f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 396f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Items are added/removed from the corresponding FolderInfo elsewhere, such 397f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // as in Workspace.onDrop. Here, we just add/remove them from the list of items 398f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // that are on the desktop, as appropriate 399f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo modelItem = sBgItemsIdMap.get(itemId); 400f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || 401f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 402f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen switch (modelItem.itemType) { 403f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 404f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 405f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 406f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (!sBgWorkspaceItems.contains(modelItem)) { 407f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen sBgWorkspaceItems.add(modelItem); 408f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 409f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen break; 410f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen default: 411f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen break; 412f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 413f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } else { 414f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen sBgWorkspaceItems.remove(modelItem); 415f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 416f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 417f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 418f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 419c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka public void flushWorkerThread() { 420c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka mFlushingWorkerThread = true; 421c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka Runnable waiter = new Runnable() { 422c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka public void run() { 423c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka synchronized (this) { 424c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka notifyAll(); 425c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka mFlushingWorkerThread = false; 426c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } 427c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } 428c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka }; 429c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka 430c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka synchronized(waiter) { 431c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka runOnWorkerThread(waiter); 432c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka if (mLoaderTask != null) { 433c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka synchronized(mLoaderTask) { 434c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka mLoaderTask.notify(); 435c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } 436c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } 437c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka boolean success = false; 438c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka while (!success) { 439c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka try { 440c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka waiter.wait(); 441c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka success = true; 442c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } catch (InterruptedException e) { 443c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } 444c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } 445c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } 446c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka } 447c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka 4489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 4499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Move an item in the DB to a new <container, screen, cellX, cellY> 4509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 451a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka static void moveItemInDatabase(Context context, final ItemInfo item, final long container, 452dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY) { 4535524b4957fc7c1c858037327429411efdb8fe7d6Brian Muramatsu String transaction = "DbDebug Modify item (" + item.title + ") in db, id: " + item.id + 454dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen " (" + item.container + ", " + item.screenId + ", " + item.cellX + ", " + item.cellY + 455dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ") --> " + "(" + container + ", " + screenId + ", " + cellX + ", " + cellY + ")"; 456487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen Launcher.sDumpLogs.add(transaction); 457487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen Log.d(TAG, transaction); 4589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 4599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 4609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 461c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 4623d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // We store hotseat items in canonical form which is this orientation invariant position 4633d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // in the hotseat 464dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 4653d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 466dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 4673d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } else { 468dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 4693d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } 47031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 4729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CONTAINER, item.container); 4733d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung values.put(LauncherSettings.Favorites.CELLX, item.cellX); 4743d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung values.put(LauncherSettings.Favorites.CELLY, item.cellY); 475dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 476ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 477c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka updateItemInDatabaseHelper(context, values, item, "moveItemInDatabase"); 47831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 47931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 48031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 481f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen * Move items in the DB to a new <container, screen, cellX, cellY>. We assume that the 482f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen * cellX, cellY have already been updated on the ItemInfos. 483f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen */ 484f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void moveItemsInDatabase(Context context, final ArrayList<ItemInfo> items, 485f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final long container, final int screen) { 486f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 487f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ContentValues> contentValues = new ArrayList<ContentValues>(); 488f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int count = items.size(); 489f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 490f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < count; i++) { 491f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo item = items.get(i); 492f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen String transaction = "DbDebug Modify item (" + item.title + ") in db, id: " 493dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + item.id + " (" + item.container + ", " + item.screenId + ", " + item.cellX 494f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen + ", " + item.cellY + ") --> " + "(" + container + ", " + screen + ", " 495f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen + item.cellX + ", " + item.cellY + ")"; 496f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Launcher.sDumpLogs.add(transaction); 497f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container = container; 498f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 499f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // We store hotseat items in canonical form which is this orientation invariant position 500f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // in the hotseat 501f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (context instanceof Launcher && screen < 0 && 502f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 503dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(item.cellX, 504f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.cellY); 505f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } else { 506dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screen; 507f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 508f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 509f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ContentValues values = new ContentValues(); 510f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CONTAINER, item.container); 511f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CELLX, item.cellX); 512f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CELLY, item.cellY); 513dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 514f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 515f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen contentValues.add(values); 516f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 517f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemsInDatabaseHelper(context, contentValues, items, "moveItemInDatabase"); 518f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 519f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 520f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen /** 521bebf042666cffe52039b875a549a582abd78a431Adam Cohen * Move and/or resize item in the DB to a new <container, screen, cellX, cellY, spanX, spanY> 522d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen */ 523bebf042666cffe52039b875a549a582abd78a431Adam Cohen static void modifyItemInDatabase(Context context, final ItemInfo item, final long container, 524dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY, final int spanX, final int spanY) { 5255524b4957fc7c1c858037327429411efdb8fe7d6Brian Muramatsu String transaction = "DbDebug Modify item (" + item.title + ") in db, id: " + item.id + 526dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen " (" + item.container + ", " + item.screenId + ", " + item.cellX + ", " + item.cellY + 527dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ") --> " + "(" + container + ", " + screenId + ", " + cellX + ", " + cellY + ")"; 528487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen Launcher.sDumpLogs.add(transaction); 529487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen Log.d(TAG, transaction); 530d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen item.cellX = cellX; 531d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen item.cellY = cellY; 532bebf042666cffe52039b875a549a582abd78a431Adam Cohen item.spanX = spanX; 533bebf042666cffe52039b875a549a582abd78a431Adam Cohen item.spanY = spanY; 534bebf042666cffe52039b875a549a582abd78a431Adam Cohen 535bebf042666cffe52039b875a549a582abd78a431Adam Cohen // We store hotseat items in canonical form which is this orientation invariant position 536bebf042666cffe52039b875a549a582abd78a431Adam Cohen // in the hotseat 537dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 538bebf042666cffe52039b875a549a582abd78a431Adam Cohen container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 539dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 540bebf042666cffe52039b875a549a582abd78a431Adam Cohen } else { 541dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 542bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 543d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 544d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen final ContentValues values = new ContentValues(); 545d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen values.put(LauncherSettings.Favorites.CONTAINER, item.container); 546bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.CELLX, item.cellX); 547bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.CELLY, item.cellY); 548bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.SPANX, item.spanX); 549bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.SPANY, item.spanY); 550dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 551d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 552816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka updateItemInDatabaseHelper(context, values, item, "modifyItemInDatabase"); 553bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 554c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 555c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka /** 556c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * Update an item to the database in a specified container. 557c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka */ 558c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka static void updateItemInDatabase(Context context, final ItemInfo item) { 559c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ContentValues values = new ContentValues(); 560c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka item.onAddToDatabase(values); 561c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka item.updateValuesWithCoordinates(values, item.cellX, item.cellY); 562c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka updateItemInDatabaseHelper(context, values, item, "updateItemInDatabase"); 563d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 564d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 565d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen /** 5669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Returns true if the shortcuts already exists in the database. 5679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * we identify a shortcut by its title and intent. 568bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project */ 5699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static boolean shortcutExists(Context context, String title, Intent intent) { 5709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 5719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, 5729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { "title", "intent" }, "title=? and intent=?", 5739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { title, intent.toUri(0) }, null); 5749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato boolean result = false; 5759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 5769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato result = c.moveToFirst(); 5779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 5789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 5799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return result; 581bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project } 582bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 583bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project /** 584aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * Returns an ItemInfo array containing all the items in the LauncherModel. 585aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * The ItemInfo.id is not set through this function. 586aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung */ 587aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung static ArrayList<ItemInfo> getItemsInLocalCoordinates(Context context) { 588aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung ArrayList<ItemInfo> items = new ArrayList<ItemInfo>(); 589aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung final ContentResolver cr = context.getContentResolver(); 590aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, new String[] { 591aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung LauncherSettings.Favorites.ITEM_TYPE, LauncherSettings.Favorites.CONTAINER, 592aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY, 593aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung LauncherSettings.Favorites.SPANX, LauncherSettings.Favorites.SPANY }, null, null, null); 594aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 595aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); 596aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); 597aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); 598aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); 599aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); 600aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX); 601aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY); 602aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 603aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung try { 604aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung while (c.moveToNext()) { 605c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka ItemInfo item = new ItemInfo(); 606aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung item.cellX = c.getInt(cellXIndex); 607aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung item.cellY = c.getInt(cellYIndex); 608aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung item.spanX = c.getInt(spanXIndex); 609aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung item.spanY = c.getInt(spanYIndex); 610aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung item.container = c.getInt(containerIndex); 611aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung item.itemType = c.getInt(itemTypeIndex); 612dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = c.getInt(screenIndex); 613aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 614aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung items.add(item); 615aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 616aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } catch (Exception e) { 617aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung items.clear(); 618aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } finally { 619aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung c.close(); 620aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 621aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 622aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung return items; 623aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 624aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 625aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung /** 6269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList. 62731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 6289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo getFolderById(Context context, HashMap<Long,FolderInfo> folderList, long id) { 6299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 6309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null, 6319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato "_id=? and (itemType=? or itemType=?)", 6329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { String.valueOf(id), 633df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_FOLDER)}, null); 634f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 6369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (c.moveToFirst()) { 6379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); 6389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE); 6399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); 6409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); 6419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); 6429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); 643f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 6449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = null; 6459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (c.getInt(itemTypeIndex)) { 646df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 647df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen folderInfo = findOrMakeFolder(folderList, id); 6489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 6499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 65031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.title = c.getString(titleIndex); 6529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.id = id; 6539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.container = c.getInt(containerIndex); 654dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen folderInfo.screenId = c.getInt(screenIndex); 655d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen folderInfo.cellX = c.getInt(cellXIndex); 656d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen folderInfo.cellY = c.getInt(cellYIndex); 657ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 6589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return folderInfo; 6599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 6619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 6622fcbd686d1c2a9a9e520116a541c9caae0c2dc60Romain Guy } 663ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 6649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 6659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 66631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 6689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Add an item to the database in a specified container. Sets the container, screen, cellX and 6699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * cellY fields of the item. Also assigns an ID to the item. 6709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 6713d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung static void addItemToDatabase(Context context, final ItemInfo item, final long container, 672dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY, final boolean notify) { 6739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 6749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 6759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 6763d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // We store hotseat items in canonical form which is this orientation invariant position 6773d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // in the hotseat 678dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 6793d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 680dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 6813d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } else { 682dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 6833d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } 684ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 6859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 6869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 6879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.onAddToDatabase(values); 688ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 689cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherAppState app = LauncherAppState.getInstance(); 690dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.id = app.getLauncherProvider().generateNewItemId(); 691a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka values.put(LauncherSettings.Favorites._ID, item.id); 6923d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung item.updateValuesWithCoordinates(values, item.cellX, item.cellY); 693aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 694c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 695a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka public void run() { 696487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen String transaction = "DbDebug Add item (" + item.title + ") to db, id: " 697dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + item.id + " (" + container + ", " + screenId + ", " + cellX + ", " 698487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen + cellY + ")"; 699487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen Launcher.sDumpLogs.add(transaction); 700487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen Log.d(TAG, transaction); 701487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen 702a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI : 703a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values); 704ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 705b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 7062abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 707b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka checkItemInfoLocked(item.id, item, null); 708b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(item.id, item); 709b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (item.itemType) { 710b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 711b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.put(item.id, (FolderInfo) item); 712b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Fall through 713b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 714b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 715b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || 716b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 717b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(item); 718b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 719b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!sBgFolders.containsKey(item.container)) { 720b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Adding an item to a folder that doesn't exist. 721b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String msg = "adding item: " + item + " to a folder that " + 722b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung " doesn't exist"; 72328b3e10fdea4d719b46d2e0da9a916bacc238fd1Adam Cohen Log.e(TAG, msg); 724b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Launcher.dumpDebugLogsToConsole(); 725b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 726487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 727b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 728b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 729b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.add((LauncherAppWidgetInfo) item); 730b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 731b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 732a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 733a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 734c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 735b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 73631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 73731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 739aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * Creates a new unique child id, for a given cell span across all layouts. 740aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung */ 741845ba3b17b83a2b11d79c6fb076cf96ab4a737dfMichael Jurka static int getCellLayoutChildId( 742dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long container, long screen, int localCellX, int localCellY, int spanX, int spanY) { 7433d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung return (((int) container & 0xFF) << 24) 744dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen | ((int) screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF); 745aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 746aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 747d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen static int getCellCountX() { 748d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen return mCellCountX; 749aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 750aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 751d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen static int getCellCountY() { 752d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen return mCellCountY; 753aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 754aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 755aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung /** 756aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * Updates the model orientation helper to take into account the current layout dimensions 757aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * when performing local/canonical coordinate transformations. 758aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung */ 759aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung static void updateWorkspaceLayoutCells(int shortAxisCellCount, int longAxisCellCount) { 760d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen mCellCountX = shortAxisCellCount; 761d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen mCellCountY = longAxisCellCount; 762aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 763aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 764aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung /** 765c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * Removes the specified item from the database 766c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * @param context 767c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * @param item 7689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 769c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka static void deleteItemFromDatabase(Context context, final ItemInfo item) { 7709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 771c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final Uri uriToDelete = LauncherSettings.Favorites.getContentUri(item.id, false); 772487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen 77383df188ce0822f4058406e5f2878d1cf34bf413eMichael Jurka Runnable r = new Runnable() { 774a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka public void run() { 775487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen String transaction = "DbDebug Delete item (" + item.title + ") from db, id: " 776dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + item.id + " (" + item.container + ", " + item.screenId + ", " + item.cellX + 777487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen ", " + item.cellY + ")"; 778487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen Launcher.sDumpLogs.add(transaction); 779487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen Log.d(TAG, transaction); 780487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen 781c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.delete(uriToDelete, null, null); 782b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 783b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 7842abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 785b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (item.itemType) { 786b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 787b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.remove(item.id); 788b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo info: sBgItemsIdMap.values()) { 789b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info.container == item.id) { 790b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // We are deleting a folder which still contains items that 791b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // think they are contained by that folder. 792b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String msg = "deleting a folder (" + item + ") which still " + 793b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung "contains items (" + info + ")"; 79428b3e10fdea4d719b46d2e0da9a916bacc238fd1Adam Cohen Log.e(TAG, msg); 795b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Launcher.dumpDebugLogsToConsole(); 796b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 797487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 798b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.remove(item); 799b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 800b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 801b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 802b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.remove(item); 803b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 804b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 805b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.remove((LauncherAppWidgetInfo) item); 806b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 807b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 808b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(item.id); 809b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgDbIconCache.remove(item); 810a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 811a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 81283df188ce0822f4058406e5f2878d1cf34bf413eMichael Jurka }; 813b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 81431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 81531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 817dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen * Update the order of the workspace screens in the database. The array list contains 818dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen * a list of screen ids in the order that they should appear. 819dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen */ 820dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen static void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) { 821dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ContentResolver cr = context.getContentResolver(); 822dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI; 823dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 824dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Remove any negative screen ids -- these aren't persisted 825dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Iterator<Long> iter = screens.iterator(); 826dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen while (iter.hasNext()) { 827dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long id = iter.next(); 828dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (id < 0) { 829dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen iter.remove(); 830dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 831dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 832dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 833dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Runnable r = new Runnable() { 834dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen @Override 835dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void run() { 836dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ArrayList<Long> screensCopy = new ArrayList<Long>(); 837dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 838dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Clear the table 839dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen cr.delete(uri, null, null); 840dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen int count = screens.size(); 841dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ContentValues[] values = new ContentValues[count]; 842dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (int i = 0; i < count; i++) { 843dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ContentValues v = new ContentValues(); 844dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId = screens.get(i); 845dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen v.put(LauncherSettings.WorkspaceScreens._ID, screenId); 846dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i); 847dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen screensCopy.add(screenId); 848dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values[i] = v; 849dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 850dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen cr.bulkInsert(uri, values); 851dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sBgWorkspaceScreens.clear(); 852dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sBgWorkspaceScreens.addAll(screensCopy); 853dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 854dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen }; 855dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen runOnWorkerThread(r); 856dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 857dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 858dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen /** 8599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Remove the contents of the specified folder from the database 8609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 861a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka static void deleteFolderContentsFromDatabase(Context context, final FolderInfo info) { 8629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 863f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 864c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 865c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka public void run() { 866c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null); 867b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 8682abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 869b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(info.id); 870b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.remove(info.id); 871b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgDbIconCache.remove(info); 872b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.remove(info); 873b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 874c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 875c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.delete(LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, 876c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka LauncherSettings.Favorites.CONTAINER + "=" + info.id, null); 877b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 8782abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 879b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo childInfo : info.contents) { 880b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(childInfo.id); 881b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgDbIconCache.remove(childInfo); 882b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 883afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 884c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 885c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 886b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 8879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 888f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 8899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 8909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Set this as the current Launcher activity object for the loader. 8919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 8929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void initialize(Callbacks callbacks) { 8939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 8949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mCallbacks = new WeakReference<Callbacks>(callbacks); 895f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 896f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 897f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 8981d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato /** 8999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and 9009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * ACTION_PACKAGE_CHANGED. 9019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 902cb1a4778686a46c46d8dc88b6c83674f6fac6592Narayan Kamath @Override 903f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato public void onReceive(Context context, Intent intent) { 9043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "onReceive intent=" + intent); 905aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 9063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String action = intent.getAction(); 9079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 9083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (Intent.ACTION_PACKAGE_CHANGED.equals(action) 9093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato || Intent.ACTION_PACKAGE_REMOVED.equals(action) 9103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato || Intent.ACTION_PACKAGE_ADDED.equals(action)) { 9113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String packageName = intent.getData().getSchemeSpecificPart(); 9123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 913f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 9143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int op = PackageUpdatedTask.OP_NONE; 91564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato 9163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (packageName == null || packageName.length() == 0) { 9173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // they sent us a bad intent 9183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 9193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 92056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 9213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { 9223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato op = PackageUpdatedTask.OP_UPDATE; 9233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { 9243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (!replacing) { 9253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato op = PackageUpdatedTask.OP_REMOVE; 92656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 9273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // else, we are replacing the package, so a PACKAGE_ADDED will be sent 9283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // later, we will update the package at this time 9293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { 9303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (!replacing) { 9313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato op = PackageUpdatedTask.OP_ADD; 9323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 9333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato op = PackageUpdatedTask.OP_UPDATE; 93456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 9353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 93656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 9373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (op != PackageUpdatedTask.OP_NONE) { 9383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName })); 939f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 940f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 9413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { 942cec583352cd76bd4319d56beec03a4820a3e9d58Joe Onorato // First, schedule to add these apps back in. 943cec583352cd76bd4319d56beec03a4820a3e9d58Joe Onorato String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 944cec583352cd76bd4319d56beec03a4820a3e9d58Joe Onorato enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packages)); 945cec583352cd76bd4319d56beec03a4820a3e9d58Joe Onorato // Then, rebind everything. 946e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato startLoaderFromBackground(); 9473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { 9483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 9493611578579b4bfb25616085dafdb1a45207394f9Joe Onorato enqueuePackageUpdated(new PackageUpdatedTask( 9503611578579b4bfb25616085dafdb1a45207394f9Joe Onorato PackageUpdatedTask.OP_UNAVAILABLE, packages)); 951e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } else if (Intent.ACTION_LOCALE_CHANGED.equals(action)) { 95293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // If we have changed locale we need to clear out the labels in all apps/workspace. 95393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee forceReload(); 95493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { 95593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // Check if configuration change was an mcc/mnc change which would affect app resources 95693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // and we would need to clear out the labels in all apps/workspace. Same handling as 95793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // above for ACTION_LOCALE_CHANGED 95893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee Configuration currentConfig = context.getResources().getConfiguration(); 95999a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee if (mPreviousConfigMcc != currentConfig.mcc) { 96093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee Log.d(TAG, "Reload apps on config change. curr_mcc:" 96199a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee + currentConfig.mcc + " prevmcc:" + mPreviousConfigMcc); 96293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee forceReload(); 96393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 96493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // Update previousConfig 96599a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee mPreviousConfigMcc = currentConfig.mcc; 966cbf7c4d50ce2609518640c3f590f6df435edabaeWinson Chung } else if (SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED.equals(action) || 967cbf7c4d50ce2609518640c3f590f6df435edabaeWinson Chung SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED.equals(action)) { 968ec9788e6819a24ef5dc8fe4edf44f280e4a703feMichael Jurka if (mCallbacks != null) { 969ec9788e6819a24ef5dc8fe4edf44f280e4a703feMichael Jurka Callbacks callbacks = mCallbacks.get(); 970ec9788e6819a24ef5dc8fe4edf44f280e4a703feMichael Jurka if (callbacks != null) { 971ec9788e6819a24ef5dc8fe4edf44f280e4a703feMichael Jurka callbacks.bindSearchablesChanged(); 972ec9788e6819a24ef5dc8fe4edf44f280e4a703feMichael Jurka } 973cfdf7ee64db8820d91a1cd82bf7b961fb2083dceWinson Chung } 974e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 975e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 976e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato 97793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee private void forceReload() { 978f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung resetLoadedState(true, true); 979f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 980f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // Do this here because if the launcher activity is running it will be restarted. 981f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // If it's not running startLoaderFromBackground will merely tell it that it needs 982f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // to reload. 983f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung startLoaderFromBackground(); 984f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung } 985f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 986f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung public void resetLoadedState(boolean resetAllAppsLoaded, boolean resetWorkspaceLoaded) { 98793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (mLock) { 98893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // Stop any existing loaders first, so they don't set mAllAppsLoaded or 98993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // mWorkspaceLoaded to true later 99093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee stopLoaderLocked(); 991f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung if (resetAllAppsLoaded) mAllAppsLoaded = false; 992f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung if (resetWorkspaceLoaded) mWorkspaceLoaded = false; 99393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 99493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 99593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 996e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato /** 997e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * When the launcher is in the background, it's possible for it to miss paired 998e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * configuration changes. So whenever we trigger the loader from the background 999e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * tell the launcher that it needs to re-run the loader when it comes back instead 1000e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * of doing it now. 1001e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato */ 1002e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato public void startLoaderFromBackground() { 1003e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato boolean runLoader = false; 1004e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato if (mCallbacks != null) { 1005e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato Callbacks callbacks = mCallbacks.get(); 1006e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato if (callbacks != null) { 1007e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato // Only actually run the loader if they're not paused. 1008e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato if (!callbacks.setLoadOnResume()) { 1009e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato runLoader = true; 1010e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1011e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1012e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1013e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato if (runLoader) { 1014b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung startLoader(false, -1); 1015f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 10163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1017f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 101893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // If there is already a loader task running, tell it to stop. 101993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // returns true if isLaunching() was true on the old task 102093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee private boolean stopLoaderLocked() { 102193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee boolean isLaunching = false; 102293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee LoaderTask oldTask = mLoaderTask; 102393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (oldTask != null) { 102493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (oldTask.isLaunching()) { 102593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee isLaunching = true; 102693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 102793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee oldTask.stopLocked(); 102893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 102993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee return isLaunching; 103093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 103193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 1032b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void startLoader(boolean isLaunching, int synchronousBindPage) { 10333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 10343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 10353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "startLoader isLaunching=" + isLaunching); 10363611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1037843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 1038b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Clear any deferred bind-runnables from the synchronized load process 1039b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // We must do this before any loading/binding is scheduled below. 1040b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mDeferredBindRunnables.clear(); 1041b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 10423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Don't bother to start the thread if we know it's not going to do anything 10433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mCallbacks != null && mCallbacks.get() != null) { 10443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // If there is already one running, tell it to stop. 104593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // also, don't downgrade isLaunching if we're already running 104693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee isLaunching = isLaunching || stopLoaderLocked(); 1047cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching); 1048b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (synchronousBindPage > -1 && mAllAppsLoaded && mWorkspaceLoaded) { 1049b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mLoaderTask.runBindSynchronousPage(synchronousBindPage); 1050b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1051b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorkerThread.setPriority(Thread.NORM_PRIORITY); 1052b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorker.post(mLoaderTask); 1053b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1054b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1055b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1056b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1057b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1058b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung void bindRemainingSynchronousPages() { 1059b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Post the remaining side pages to be loaded 1060b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!mDeferredBindRunnables.isEmpty()) { 1061b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (final Runnable r : mDeferredBindRunnables) { 106281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung mHandler.post(r, MAIN_THREAD_BINDING_RUNNABLE); 1063b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 1064b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mDeferredBindRunnables.clear(); 1065b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 10663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1067b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 10683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void stopLoader() { 10693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 10703611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask != null) { 10713611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask.stopLocked(); 10729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1073f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 10743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1075b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 1076c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka public boolean isAllAppsLoaded() { 1077c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka return mAllAppsLoaded; 1078c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka } 1079c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka 108036a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung boolean isLoadingWorkspace() { 108136a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung synchronized (mLock) { 108236a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung if (mLoaderTask != null) { 108336a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung return mLoaderTask.isLoadingWorkspace(); 108436a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung } 108536a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung } 108636a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung return false; 108736a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung } 108836a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 10893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato /** 10903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * Runnable for the thread that loads the contents of the launcher: 10913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - workspace icons 10923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - widgets 10933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - all apps icons 10943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato */ 10953611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private class LoaderTask implements Runnable { 10963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private Context mContext; 10973611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private boolean mIsLaunching; 109836a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung private boolean mIsLoadingAndBindingWorkspace; 10993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private boolean mStopped; 11003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private boolean mLoadAndBindStepFinished; 1101e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen private boolean mIsUpgradePath; 1102b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1103c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung private HashMap<Object, CharSequence> mLabelCache; 11043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 11053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato LoaderTask(Context context, boolean isLaunching) { 11063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mContext = context; 11073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mIsLaunching = isLaunching; 1108c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache = new HashMap<Object, CharSequence>(); 11093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1110f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 11113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato boolean isLaunching() { 11123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return mIsLaunching; 11133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1114f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 111536a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung boolean isLoadingWorkspace() { 111636a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung return mIsLoadingAndBindingWorkspace; 111736a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung } 111836a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 11193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void loadAndBindWorkspace() { 112036a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung mIsLoadingAndBindingWorkspace = true; 112136a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 11223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Load the workspace 11233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 11243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "loadAndBindWorkspace mWorkspaceLoaded=" + mWorkspaceLoaded); 11253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1126288a36b563801a26d00084cb823435a3ba4cb76cMichael Jurka 1127a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka if (!mWorkspaceLoaded) { 11283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato loadWorkspace(); 112993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (LoaderTask.this) { 113093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (mStopped) { 113193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee return; 113293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 113393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mWorkspaceLoaded = true; 11349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 11353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1136cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 11373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Bind the workspace 1138b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung bindWorkspace(-1); 11393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1140f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 11413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void waitForIdle() { 11423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Wait until the either we're stopped or the other threads are done. 11433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This way we don't start loading all apps until the workspace has settled 11443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // down. 11453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 11463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long workspaceWaitTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1147843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 11483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.postIdle(new Runnable() { 11493611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 11503611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 11513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoadAndBindStepFinished = true; 11523611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 11533611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "done with previous binding step"); 11549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 11553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato LoaderTask.this.notify(); 11569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 11579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 11583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 11593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 1160c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka while (!mStopped && !mLoadAndBindStepFinished && !mFlushingWorkerThread) { 11613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato try { 1162c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka // Just in case mFlushingWorkerThread changes but we aren't woken up, 1163c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka // wait no longer than 1sec at a time 1164c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka this.wait(1000); 11653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } catch (InterruptedException ex) { 11663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Ignore 11679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 11683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 11693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 11703611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "waited " 1171aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung + (SystemClock.uptimeMillis()-workspaceWaitTime) 11723611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + "ms for previous step to finish binding"); 11739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1174843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 11753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1176f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1177b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung void runBindSynchronousPage(int synchronousBindPage) { 1178b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (synchronousBindPage < 0) { 1179b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we have a valid page index to load synchronously 1180b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Should not call runBindSynchronousPage() without " + 1181b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung "valid page index"); 1182b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1183b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!mAllAppsLoaded || !mWorkspaceLoaded) { 1184b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we don't try and bind a specified page when the pages have not been 1185b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // loaded already (we should load everything asynchronously in that case) 1186b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Expecting AllApps and Workspace to be loaded"); 1187b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1188b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung synchronized (mLock) { 1189b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (mIsLoaderTaskRunning) { 1190b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we are never running the background loading at this point since 1191b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // we also touch the background collections 1192b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Error! Background loading is already running"); 1193b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1194b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1195b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1196b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: Throw an exception if we are already loading (since we touch the worker thread 1197b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // data structures, we can't allow any other thread to touch that data, but because 1198b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // this call is synchronous, we can get away with not locking). 1199b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1200cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // The LauncherModel is static in the LauncherAppState and mHandler may have queued 1201a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen // operations from the previous activity. We need to ensure that all queued operations 1202a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen // are executed before any synchronous binding work is done. 1203a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen mHandler.flush(); 1204a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen 1205b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Divide the set of loaded items into those that we are binding synchronously, and 1206b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // everything else that is to be bound normally (asynchronously). 1207b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung bindWorkspace(synchronousBindPage); 1208b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: For now, continue posting the binding of AllApps as there are other issues that 1209b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // arise from that. 1210b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung onlyBindAllApps(); 1211b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1212b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 12133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 1214b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung synchronized (mLock) { 1215b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mIsLoaderTaskRunning = true; 1216b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 12173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Optimize for end-user experience: if the Launcher is up and // running with the 12183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // All Apps interface in the foreground, load All Apps first. Otherwise, load the 12193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // workspace first (default). 12203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks cbk = mCallbacks.get(); 12213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final boolean loadWorkspaceFirst = cbk != null ? (!cbk.isAllAppsVisible()) : true; 1222843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 12233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato keep_running: { 1224843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler // Elevate priority when Home launches for the first time to avoid 1225843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler // starving at boot time. Staring at a blank home is not cool. 1226dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler synchronized (mLock) { 1227aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (DEBUG_LOADERS) Log.d(TAG, "Setting thread priority to " + 1228aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung (mIsLaunching ? "DEFAULT" : "BACKGROUND")); 1229843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler android.os.Process.setThreadPriority(mIsLaunching 1230843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler ? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND); 1231dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 1232843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler if (loadWorkspaceFirst) { 1233843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace"); 1234843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler loadAndBindWorkspace(); 1235843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } else { 1236843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler if (DEBUG_LOADERS) Log.d(TAG, "step 1: special: loading all apps"); 1237cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato loadAndBindAllApps(); 12389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1239843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 12403611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mStopped) { 12413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break keep_running; 12423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 12433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 12443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Whew! Hard work done. Slow us down, and wait until the UI thread has 12453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // settled down. 12469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 1247843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler if (mIsLaunching) { 1248aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (DEBUG_LOADERS) Log.d(TAG, "Setting thread priority to BACKGROUND"); 1249843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 12509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 12519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 12523611578579b4bfb25616085dafdb1a45207394f9Joe Onorato waitForIdle(); 1253f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1254843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler // second step 1255843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler if (loadWorkspaceFirst) { 1256843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps"); 1257cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato loadAndBindAllApps(); 1258843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } else { 1259843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler if (DEBUG_LOADERS) Log.d(TAG, "step 2: special: loading workspace"); 1260843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler loadAndBindWorkspace(); 1261843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 12627ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung 12637ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung // Restore the default thread priority after we are done loading items 12647ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung synchronized (mLock) { 12657ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 12667ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung } 12673611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1268843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 1269aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung // Update the saved icons if necessary 1270aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (DEBUG_LOADERS) Log.d(TAG, "Comparing loaded icons to database icons"); 12712abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1272b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (Object key : sBgDbIconCache.keySet()) { 1273b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung updateSavedIcon(mContext, (ShortcutInfo) key, sBgDbIconCache.get(key)); 1274b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1275b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgDbIconCache.clear(); 1276aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } 1277aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung 12783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Clear out this reference, otherwise we end up holding it until all of the 12793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // callback runnables are done. 12803611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mContext = null; 1281f3d5ea926d4dd1a739b9d3816543728af723cc26Joe Onorato 12823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 12833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // If we are still the last one to be scheduled, remove ourselves. 12843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask == this) { 12853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask = null; 1286843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 1287b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mIsLoaderTaskRunning = false; 12883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 12893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1290f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 12913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void stopLocked() { 12923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 12933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mStopped = true; 12943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato this.notify(); 1295f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 12963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1297f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 12983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato /** 12993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * Gets the callbacks object. If we've been stopped, or if the launcher object 13003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * has somehow been garbage collected, return null instead. Pass in the Callbacks 13013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * object that was around when the deferred message was scheduled, and if there's 13023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * a new Callbacks object around then also return null. This will save us from 13033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * calling onto it with data that will be ignored. 13043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato */ 13053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Callbacks tryGetCallbacks(Callbacks oldCallbacks) { 13063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 13073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mStopped) { 13083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 13093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1310ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato 13113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mCallbacks == null) { 13123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 13133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1314f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 13153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = mCallbacks.get(); 13163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != oldCallbacks) { 13173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 13183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 13193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks == null) { 13203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "no mCallbacks"); 13213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 13229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 13233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 13243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return callbacks; 1325f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 13263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1327f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 13283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // check & update map of what's occupied; used to discard overlapping/invalid items 1329dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item) { 1330dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long containerIndex = item.screenId; 1331f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1332dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (occupied.containsKey(LauncherSettings.Favorites.CONTAINER_HOTSEAT)) { 1333dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT) 1334dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen [(int) item.screenId][0] != null) { 1335dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Log.e(TAG, "Error loading shortcut into hotseat " + item 1336dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + " into position (" + item.screenId + ":" + item.cellX + "," 1337dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + item.cellY + ") occupied by " 1338dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT) 1339dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen [(int) item.screenId][0]); 1340dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen return false; 1341dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 13426ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung } else { 1343dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ItemInfo[][] items = new ItemInfo[mCellCountX + 1][mCellCountY + 1]; 1344dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen items[(int) item.screenId][0] = item; 1345dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen occupied.put((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT, items); 13466ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung return true; 13476ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung } 1348f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung } else if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { 1349f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung // Skip further checking if it is not the hotseat or workspace container 13503611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return true; 13513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1352f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung 1353dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (!occupied.containsKey(item.screenId)) { 1354dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ItemInfo[][] items = new ItemInfo[mCellCountX + 1][mCellCountY + 1]; 1355dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen occupied.put(item.screenId, items); 1356dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1357dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1358dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ItemInfo[][] screens = occupied.get(item.screenId); 13596ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung // Check if any workspace icons overlap with each other 13603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int x = item.cellX; x < (item.cellX+item.spanX); x++) { 13613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int y = item.cellY; y < (item.cellY+item.spanY); y++) { 1362dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (screens[x][y] != null) { 13633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.e(TAG, "Error loading shortcut " + item 1364dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + " into cell (" + containerIndex + "-" + item.screenId + ":" 13653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + x + "," + y 1366aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung + ") occupied by " 1367dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + screens[x][y]); 13683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return false; 13698802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 13708802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 13713611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 13723611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int x = item.cellX; x < (item.cellX+item.spanX); x++) { 13733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int y = item.cellY; y < (item.cellY+item.spanY); y++) { 1374dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen screens[x][y] = item; 13758802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 13768802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 1377f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung 13783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return true; 13793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 13808802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler 13813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void loadWorkspace() { 13823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1383f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 13843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Context context = mContext; 13853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final ContentResolver contentResolver = context.getContentResolver(); 13863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final PackageManager manager = context.getPackageManager(); 13873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final AppWidgetManager widgets = AppWidgetManager.getInstance(context); 13883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final boolean isSafeMode = manager.isSafeMode(); 1389f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1390b85f8a44b51258f22938773ca30dd85845345010Michael Jurka // Make sure the default workspace is loaded, if needed 1391e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen boolean loadOldDb = mApp.getLauncherProvider().shouldLoadOldDb(); 1392e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen Uri contentUri = loadOldDb ? LauncherSettings.Favorites.OLD_CONTENT_URI : 1393e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen LauncherSettings.Favorites.CONTENT_URI; 1394e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 1395e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen mIsUpgradePath = loadOldDb; 1396b85f8a44b51258f22938773ca30dd85845345010Michael Jurka 13972abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1398b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.clear(); 1399b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.clear(); 1400b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.clear(); 1401b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.clear(); 1402b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgDbIconCache.clear(); 1403dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sBgWorkspaceScreens.clear(); 1404b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1405b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<Long> itemsToRemove = new ArrayList<Long>(); 1406b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1407e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen final Cursor c = contentResolver.query(contentUri, null, null, null, null); 1408b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1409b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // +1 for the hotseat (it can be larger than the workspace) 1410b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Load workspace in reverse order to ensure that latest items are loaded first (and 1411b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // before any earlier duplicates) 1412dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final HashMap<Long, ItemInfo[][]> occupied = new HashMap<Long, ItemInfo[][]>(); 1413b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1414b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1415b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); 1416b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int intentIndex = c.getColumnIndexOrThrow 1417b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.INTENT); 1418b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int titleIndex = c.getColumnIndexOrThrow 1419b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.TITLE); 1420b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int iconTypeIndex = c.getColumnIndexOrThrow( 1421b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ICON_TYPE); 1422b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); 1423b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int iconPackageIndex = c.getColumnIndexOrThrow( 1424b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ICON_PACKAGE); 1425b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int iconResourceIndex = c.getColumnIndexOrThrow( 1426b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ICON_RESOURCE); 1427b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int containerIndex = c.getColumnIndexOrThrow( 1428b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.CONTAINER); 1429b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int itemTypeIndex = c.getColumnIndexOrThrow( 1430b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ITEM_TYPE); 1431b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int appWidgetIdIndex = c.getColumnIndexOrThrow( 1432b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.APPWIDGET_ID); 1433b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int screenIndex = c.getColumnIndexOrThrow( 1434b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.SCREEN); 1435b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int cellXIndex = c.getColumnIndexOrThrow 1436b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.CELLX); 1437b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int cellYIndex = c.getColumnIndexOrThrow 1438b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.CELLY); 1439b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int spanXIndex = c.getColumnIndexOrThrow 1440b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.SPANX); 1441b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int spanYIndex = c.getColumnIndexOrThrow( 1442b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.SPANY); 1443b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung //final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI); 1444b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung //final int displayModeIndex = c.getColumnIndexOrThrow( 1445b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // LauncherSettings.Favorites.DISPLAY_MODE); 1446b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1447b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ShortcutInfo info; 1448b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String intentDescription; 1449b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherAppWidgetInfo appWidgetInfo; 1450b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int container; 1451b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung long id; 1452b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent intent; 1453b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1454b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung while (!mStopped && c.moveToNext()) { 1455b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1456b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int itemType = c.getInt(itemTypeIndex); 1457b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1458b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (itemType) { 1459b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1460b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1461b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intentDescription = c.getString(intentIndex); 1462b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1463b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intent = Intent.parseUri(intentDescription, 0); 1464b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (URISyntaxException e) { 1465b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung continue; 1466b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1467968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka 1468b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 1469b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info = getShortcutInfo(manager, intent, context, c, iconIndex, 1470b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung titleIndex, mLabelCache); 1471b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1472b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info = getShortcutInfo(c, context, iconTypeIndex, 1473b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung iconPackageIndex, iconResourceIndex, iconIndex, 1474b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung titleIndex); 1475b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1476b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // App shortcuts that used to be automatically added to Launcher 1477b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // didn't always have the correct intent flags set, so do that 1478b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // here 1479b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (intent.getAction() != null && 14809ad005639e1698c94674cdfadf3ae342fb56c9b5Michael Jurka intent.getCategories() != null && 14819ad005639e1698c94674cdfadf3ae342fb56c9b5Michael Jurka intent.getAction().equals(Intent.ACTION_MAIN) && 1482968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { 1483b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intent.addFlags( 1484b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent.FLAG_ACTIVITY_NEW_TASK | 1485b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 1486b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1487968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka } 14883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 1489b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info != null) { 1490b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.intent = intent; 1491b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.id = c.getLong(idIndex); 1492b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung container = c.getInt(containerIndex); 1493b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.container = container; 1494dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen info.screenId = c.getInt(screenIndex); 1495b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.cellX = c.getInt(cellXIndex); 1496b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.cellY = c.getInt(cellYIndex); 1497b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // check & update map of what's occupied 1498b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!checkItemPlacement(occupied, info)) { 1499b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1500b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1501b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1502b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (container) { 1503b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: 1504b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: 1505b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(info); 1506b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1507b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung default: 1508b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Item is in a user folder 1509b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folderInfo = 1510b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung findOrMakeFolder(sBgFolders, container); 1511b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.add(info); 1512b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1513b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1514e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT && 1515e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen loadOldDb) { 1516dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen info.screenId = permuteScreens(info.screenId); 1517e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 1518b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(info.id, info); 1519b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1520b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // now that we've loaded everthing re-save it with the 1521b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // icon in case it disappears somehow. 1522b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung queueIconToBeChecked(sBgDbIconCache, info, c, iconIndex); 1523b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1524b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Failed to load the shortcut, probably because the 1525b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // activity manager couldn't resolve it (maybe the app 1526b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // was uninstalled), or the db row was somehow screwed up. 1527b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Delete it. 1528b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung id = c.getLong(idIndex); 1529b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.e(TAG, "Error loading shortcut " + id + ", removing it"); 1530b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung contentResolver.delete(LauncherSettings.Favorites.getContentUri( 1531b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung id, false), null, null); 1532b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1533b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1534b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1535b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 1536b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung id = c.getLong(idIndex); 1537b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folderInfo = findOrMakeFolder(sBgFolders, id); 1538b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1539b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.title = c.getString(titleIndex); 1540b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.id = id; 15413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato container = c.getInt(containerIndex); 1542b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.container = container; 1543dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen folderInfo.screenId = c.getInt(screenIndex); 1544b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.cellX = c.getInt(cellXIndex); 1545b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.cellY = c.getInt(cellYIndex); 15463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 15473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // check & update map of what's occupied 1548b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!checkItemPlacement(occupied, folderInfo)) { 15493611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 15509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 15513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato switch (container) { 1552b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: 1553b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: 1554b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(folderInfo); 1555b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 15569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1557e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT && 1558e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen loadOldDb) { 1559dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen folderInfo.screenId = permuteScreens(folderInfo.screenId); 1560e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 156117a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato 1562b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(folderInfo.id, folderInfo); 1563b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.put(folderInfo.id, folderInfo); 1564b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1565b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1566b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 1567b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Read all Launcher-specific widget details 1568b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int appWidgetId = c.getInt(appWidgetIdIndex); 15693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato id = c.getLong(idIndex); 1570f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1571b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final AppWidgetProviderInfo provider = 1572b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung widgets.getAppWidgetInfo(appWidgetId); 1573b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1574b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!isSafeMode && (provider == null || provider.provider == null || 1575b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung provider.provider.getPackageName() == null)) { 1576b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String log = "Deleting widget that isn't installed anymore: id=" 1577b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung + id + " appWidgetId=" + appWidgetId; 1578b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.e(TAG, log); 1579b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Launcher.sDumpLogs.add(log); 1580b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsToRemove.add(id); 1581b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1582b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, 1583b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung provider.provider); 1584b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.id = id; 1585dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen appWidgetInfo.screenId = c.getInt(screenIndex); 1586b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.cellX = c.getInt(cellXIndex); 1587b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.cellY = c.getInt(cellYIndex); 1588b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.spanX = c.getInt(spanXIndex); 1589b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.spanY = c.getInt(spanYIndex); 1590b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int[] minSpan = Launcher.getMinSpanForWidget(context, provider); 1591b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.minSpanX = minSpan[0]; 1592b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.minSpanY = minSpan[1]; 1593b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1594b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung container = c.getInt(containerIndex); 1595b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && 1596b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1597b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.e(TAG, "Widget found where container != " + 1598b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!"); 1599b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung continue; 1600b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1601e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT && 1602e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen loadOldDb) { 1603dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen appWidgetInfo.screenId = 1604dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen permuteScreens(appWidgetInfo.screenId); 1605e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 1606b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1607e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen appWidgetInfo.container = c.getInt(containerIndex); 1608b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // check & update map of what's occupied 1609b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!checkItemPlacement(occupied, appWidgetInfo)) { 1610b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1611b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1612b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(appWidgetInfo.id, appWidgetInfo); 1613b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.add(appWidgetInfo); 1614b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 16159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 16163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1617b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (Exception e) { 1618b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.w(TAG, "Desktop items loading interrupted:", e); 1619b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1620b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1621b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } finally { 1622b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung c.close(); 1623b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1624ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 1625b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemsToRemove.size() > 0) { 1626b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ContentProviderClient client = contentResolver.acquireContentProviderClient( 1627b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.CONTENT_URI); 1628b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Remove dead items 1629b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (long id : itemsToRemove) { 1630b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (DEBUG_LOADERS) { 1631b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "Removed id = " + id); 1632b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1633b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Don't notify content observers 1634b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1635b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung client.delete(LauncherSettings.Favorites.getContentUri(id, false), 1636b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung null, null); 1637b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (RemoteException e) { 1638b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.w(TAG, "Could not remove id = " + id); 1639b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1640b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1641b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 16428802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler 1643dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (loadOldDb) { 1644dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long maxScreenId = 0; 1645dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // If we're importing we use the old screen order. 1646dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (ItemInfo item: sBgItemsIdMap.values()) { 1647dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId = item.screenId; 1648dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 1649dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen !sBgWorkspaceScreens.contains(screenId)) { 1650dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sBgWorkspaceScreens.add(screenId); 1651dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (screenId > maxScreenId) { 1652dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen maxScreenId = screenId; 1653dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1654dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1655dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1656dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Collections.sort(sBgWorkspaceScreens); 1657dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen mApp.getLauncherProvider().updateMaxScreenId(maxScreenId); 1658dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); 1659dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } else { 1660dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Uri screensUri = LauncherSettings.WorkspaceScreens.CONTENT_URI; 1661dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Cursor sc = contentResolver.query(screensUri, null, null, null, null); 1662dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen TreeMap<Integer, Long> orderedScreens = new TreeMap<Integer, Long>(); 1663dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1664dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen try { 1665dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final int idIndex = sc.getColumnIndexOrThrow( 1666dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen LauncherSettings.WorkspaceScreens._ID); 1667dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final int rankIndex = sc.getColumnIndexOrThrow( 1668dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen LauncherSettings.WorkspaceScreens.SCREEN_RANK); 1669dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen while (sc.moveToNext()) { 1670dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen try { 1671dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId = sc.getLong(idIndex); 1672dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen int rank = sc.getInt(rankIndex); 1673dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1674dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen orderedScreens.put(rank, screenId); 1675dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } catch (Exception e) { 1676dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Log.w(TAG, "Desktop items loading interrupted:", e); 1677dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1678dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1679dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } finally { 1680dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sc.close(); 1681dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1682dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1683dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Iterator<Integer> iter = orderedScreens.keySet().iterator(); 1684dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen while (iter.hasNext()) { 1685dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sBgWorkspaceScreens.add(orderedScreens.get(iter.next())); 1686dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1687dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1688dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Remove any empty screens 1689dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ArrayList<Long> unusedScreens = new ArrayList<Long>(); 1690dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen unusedScreens.addAll(sBgWorkspaceScreens); 1691dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1692dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (ItemInfo item: sBgItemsIdMap.values()) { 1693dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId = item.screenId; 1694dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1695dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 1696dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen unusedScreens.contains(screenId)) { 1697dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen unusedScreens.remove(screenId); 1698dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1699dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1700dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1701dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // If there are any empty screens remove them, and update. 1702dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (unusedScreens.size() != 0) { 1703dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sBgWorkspaceScreens.removeAll(unusedScreens); 1704dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); 1705dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1706dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1707dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1708b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (DEBUG_LOADERS) { 1709b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms"); 1710b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "workspace layout: "); 1711dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Iterator<Long> iter = occupied.keySet().iterator(); 1712dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen int nScreens = occupied.size(); 1713b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int y = 0; y < mCellCountY; y++) { 1714b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String line = ""; 1715dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1716dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (int s = 0; s < nScreens; s++) { 1717dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId = iter.next(); 1718b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (s > 0) { 1719b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung line += " | "; 1720b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1721b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int x = 0; x < mCellCountX; x++) { 1722dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen line += ((occupied.get(screenId)[x][y] != null) ? "#" : "."); 17239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 17249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1725b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "[ " + line + " ]"); 17269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 17279c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 17283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1729b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 17305c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 1731e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen // We rearrange the screens from the old launcher 1732e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen // 12345 -> 34512 1733dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen private long permuteScreens(long screen) { 1734e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen if (screen >= 2) { 1735e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen return screen - 2; 1736e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } else { 1737e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen return screen + 3; 1738e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 1739e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 1740e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 1741b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of items who are directly or indirectly (via another container) on the 1742b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * specified screen. */ 1743b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void filterCurrentWorkspaceItems(int currentScreen, 1744b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> allWorkspaceItems, 1745b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> currentScreenItems, 1746b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> otherScreenItems) { 17472abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung // Purge any null ItemInfos 17482abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung Iterator<ItemInfo> iter = allWorkspaceItems.iterator(); 17492abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung while (iter.hasNext()) { 17502abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung ItemInfo i = iter.next(); 17512abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (i == null) { 17522abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung iter.remove(); 17532abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung } 17542abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung } 17552abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung 1756b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we aren't filtering on a screen, then the set of items to load is the full set of 1757b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // items given. 1758b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (currentScreen < 0) { 1759b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.addAll(allWorkspaceItems); 1760b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1761b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1762b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Order the set of items by their containers first, this allows use to walk through the 1763b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // list sequentially, build up a list of containers that are in the specified screen, 1764b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // as well as all items in those containers. 1765b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Set<Long> itemsOnScreen = new HashSet<Long>(); 1766b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Collections.sort(allWorkspaceItems, new Comparator<ItemInfo>() { 1767b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 1768b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public int compare(ItemInfo lhs, ItemInfo rhs) { 1769b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung return (int) (lhs.container - rhs.container); 1770b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1771b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }); 1772b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo info : allWorkspaceItems) { 1773b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { 1774dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (info.screenId == currentScreen) { 1775b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 1776b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 1777b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1778b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenItems.add(info); 17793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1780b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1781b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 1782b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 1783b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1784b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemsOnScreen.contains(info.container)) { 1785b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 1786b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 1787b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1788b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenItems.add(info); 17895c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 17905c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 17913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1792b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 17935c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 1794b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of widgets which are on the specified screen. */ 1795b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void filterCurrentAppWidgets(int currentScreen, 1796b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> appWidgets, 1797b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> currentScreenWidgets, 1798b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) { 1799b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we aren't filtering on a screen, then the set of items to load is the full set of 1800b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // widgets given. 1801b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (currentScreen < 0) { 1802b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenWidgets.addAll(appWidgets); 1803b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1804b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1805b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (LauncherAppWidgetInfo widget : appWidgets) { 18062abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (widget == null) continue; 1807b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 1808dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen widget.screenId == currentScreen) { 1809b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenWidgets.add(widget); 1810b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1811b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenWidgets.add(widget); 1812a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 18139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 18143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 181531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1816b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of folders which are on the specified screen. */ 1817b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void filterCurrentFolders(int currentScreen, 1818b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, ItemInfo> itemsIdMap, 1819b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> folders, 1820b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> currentScreenFolders, 1821b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> otherScreenFolders) { 1822b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we aren't filtering on a screen, then the set of items to load is the full set of 1823b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // widgets given. 1824b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (currentScreen < 0) { 1825b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenFolders.putAll(folders); 1826b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 18273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 1828b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (long id : folders.keySet()) { 1829b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ItemInfo info = itemsIdMap.get(id); 1830b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folder = folders.get(id); 18312abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (info == null || folder == null) continue; 1832b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 1833dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen info.screenId == currentScreen) { 1834b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenFolders.put(id, folder); 1835b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1836b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenFolders.put(id, folder); 1837b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 18383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1839b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 184031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1841b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to 1842b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * right) */ 1843b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) { 1844b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: review this 1845b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Collections.sort(workspaceItems, new Comparator<ItemInfo>() { 1846db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung @Override 1847db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung public int compare(ItemInfo lhs, ItemInfo rhs) { 1848db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int cellCountX = LauncherModel.getCellCountX(); 1849db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int cellCountY = LauncherModel.getCellCountY(); 1850db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int screenOffset = cellCountX * cellCountY; 1851db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int containerOffset = screenOffset * (Launcher.SCREEN_COUNT + 1); // +1 hotseat 1852dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long lr = (lhs.container * containerOffset + lhs.screenId * screenOffset + 1853db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung lhs.cellY * cellCountX + lhs.cellX); 1854dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long rr = (rhs.container * containerOffset + rhs.screenId * screenOffset + 1855db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung rhs.cellY * cellCountX + rhs.cellX); 1856db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung return (int) (lr - rr); 1857db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung } 1858db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung }); 1859b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1860db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung 1861dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen private void bindWorkspaceScreens(final Callbacks oldCallbacks, 1862dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ArrayList<Long> orderedScreens) { 1863dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1864dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Runnable r = new Runnable() { 1865dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen @Override 1866dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void run() { 1867dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Callbacks callbacks = tryGetCallbacks(oldCallbacks); 1868dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (callbacks != null) { 1869dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen callbacks.bindScreens(orderedScreens); 1870dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1871dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1872dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen }; 1873dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 1874dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1875dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1876b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void bindWorkspaceItems(final Callbacks oldCallbacks, 1877b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<ItemInfo> workspaceItems, 1878b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<LauncherAppWidgetInfo> appWidgets, 1879b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final HashMap<Long, FolderInfo> folders, 1880b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<Runnable> deferredBindRunnables) { 1881b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1882b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final boolean postOnMainThread = (deferredBindRunnables != null); 1883603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung 1884b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the workspace items 1885db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int N = workspaceItems.size(); 1886b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int i = 0; i < N; i += ITEMS_CHUNK) { 18873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int start = i; 18883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i); 1889b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 1890b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 18919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 1892c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 18939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 1894603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung callbacks.bindItems(workspaceItems, start, start+chunkSize); 18959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 18969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1897b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 1898b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 1899b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung deferredBindRunnables.add(r); 1900b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 190181b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 19023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1903b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1904b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1905b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the folders 1906b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!folders.isEmpty()) { 1907b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 1908b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 1909b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 1910b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 1911b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.bindFolders(folders); 19129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1913b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1914b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 1915b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 1916b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung deferredBindRunnables.add(r); 1917b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 191881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 19199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 19203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1921b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1922b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the widgets, one at a time 1923b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung N = appWidgets.size(); 1924b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int i = 0; i < N; i++) { 1925b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final LauncherAppWidgetInfo widget = appWidgets.get(i); 1926b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 1927b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 1928b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 1929b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 1930b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.bindAppWidget(widget); 19313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1932b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1933b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 1934b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 1935b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung deferredBindRunnables.add(r); 1936b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 193781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 19383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 19393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1940b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1941b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1942b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** 1943b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * Binds all loaded data to actual views on the main thread. 1944b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung */ 1945b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void bindWorkspace(int synchronizeBindPage) { 1946b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final long t = SystemClock.uptimeMillis(); 1947b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Runnable r; 1948b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1949b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Don't use these two variables in any of the callback runnables. 1950b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Otherwise we hold a reference to them. 1951b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Callbacks oldCallbacks = mCallbacks.get(); 1952b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (oldCallbacks == null) { 1953b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // This launcher has exited and nobody bothered to tell us. Just bail. 1954b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.w(TAG, "LoaderTask running with no launcher"); 1955b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung return; 1956b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1957b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 19584a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung final boolean isLoadingSynchronously = (synchronizeBindPage > -1); 19594a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung final int currentScreen = isLoadingSynchronously ? synchronizeBindPage : 1960b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung oldCallbacks.getCurrentWorkspaceScreen(); 1961b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1962b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Load all the items that are on the current page first (and in the process, unbind 1963b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // all the existing workspace items before we call startBinding() below. 1964b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung unbindWorkspaceItemsOnMainThread(); 1965b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> workspaceItems = new ArrayList<ItemInfo>(); 1966b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> appWidgets = 1967b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 1968b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> folders = new HashMap<Long, FolderInfo>(); 1969b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, ItemInfo> itemsIdMap = new HashMap<Long, ItemInfo>(); 1970dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ArrayList<Long> orderedScreenIds = new ArrayList<Long>(); 19712abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1972b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung workspaceItems.addAll(sBgWorkspaceItems); 1973b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgets.addAll(sBgAppWidgets); 1974b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folders.putAll(sBgFolders); 1975b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsIdMap.putAll(sBgItemsIdMap); 1976dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen orderedScreenIds.addAll(sBgWorkspaceScreens); 1977b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1978b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1979b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<ItemInfo>(); 1980b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<ItemInfo>(); 1981b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> currentAppWidgets = 1982b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 1983b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> otherAppWidgets = 1984b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 1985b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> currentFolders = new HashMap<Long, FolderInfo>(); 1986b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> otherFolders = new HashMap<Long, FolderInfo>(); 1987b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1988b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Separate the items that are on the current screen, and all the other remaining items 1989b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung filterCurrentWorkspaceItems(currentScreen, workspaceItems, currentWorkspaceItems, 1990b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherWorkspaceItems); 1991b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung filterCurrentAppWidgets(currentScreen, appWidgets, currentAppWidgets, 1992b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherAppWidgets); 1993b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung filterCurrentFolders(currentScreen, itemsIdMap, folders, currentFolders, 1994b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherFolders); 1995b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sortWorkspaceItemsSpatially(currentWorkspaceItems); 1996b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sortWorkspaceItemsSpatially(otherWorkspaceItems); 1997b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1998b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Tell the workspace that we're about to start binding items 1999b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r = new Runnable() { 20003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 20013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 20023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != null) { 2003b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.startBinding(); 20049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 20059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2006b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 200781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 2008b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2009dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen bindWorkspaceScreens(oldCallbacks, orderedScreenIds); 2010dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2011b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Load items on the current page 2012b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, 2013b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentFolders, null); 20141462de39f01cec0ba785386532719cb0207dd827Adam Cohen if (isLoadingSynchronously) { 20151462de39f01cec0ba785386532719cb0207dd827Adam Cohen r = new Runnable() { 20161462de39f01cec0ba785386532719cb0207dd827Adam Cohen public void run() { 20171462de39f01cec0ba785386532719cb0207dd827Adam Cohen Callbacks callbacks = tryGetCallbacks(oldCallbacks); 20181462de39f01cec0ba785386532719cb0207dd827Adam Cohen if (callbacks != null) { 20191462de39f01cec0ba785386532719cb0207dd827Adam Cohen callbacks.onPageBoundSynchronously(currentScreen); 20201462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 20211462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 20221462de39f01cec0ba785386532719cb0207dd827Adam Cohen }; 202381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 20241462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 2025b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 20264a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung // Load all the remaining pages (if we are loading synchronously, we want to defer this 20274a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung // work until after the first render) 2028b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mDeferredBindRunnables.clear(); 2029b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, otherFolders, 20304a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung (isLoadingSynchronously ? mDeferredBindRunnables : null)); 2031b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2032b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Tell the workspace that we're done binding items 2033b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r = new Runnable() { 20343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2035b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2036b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 2037e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen callbacks.finishBindingItems(mIsUpgradePath); 2038b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2039b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 204098e030be2abc03e90e9fd9f8bf67e2e01db39cc0Winson Chung // If we're profiling, ensure this is the last thing in the queue. 20413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 20423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound workspace in " 20433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 20449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 204536a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 204636a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung mIsLoadingAndBindingWorkspace = false; 20479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2048b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 20494a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung if (isLoadingSynchronously) { 20504a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung mDeferredBindRunnables.add(r); 20514a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung } else { 205281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 20534a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung } 20543611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 20553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 20563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void loadAndBindAllApps() { 20573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 20583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "loadAndBindAllApps mAllAppsLoaded=" + mAllAppsLoaded); 20593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 20603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (!mAllAppsLoaded) { 20613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato loadAllAppsByBatch(); 206293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (LoaderTask.this) { 206393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (mStopped) { 206493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee return; 206593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 206693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mAllAppsLoaded = true; 20673611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 20683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 20693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato onlyBindAllApps(); 20703611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 20713611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 20723611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 20733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void onlyBindAllApps() { 20743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 20753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (oldCallbacks == null) { 20763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 20773611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "LoaderTask running with no launcher (onlyBindAllApps)"); 20783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 20793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 20803611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 20813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // shallow copy 2082c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung @SuppressWarnings("unchecked") 20833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final ArrayList<ApplicationInfo> list 2084487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen = (ArrayList<ApplicationInfo>) mBgAllAppsList.data.clone(); 2085c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung Runnable r = new Runnable() { 20863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 20873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = SystemClock.uptimeMillis(); 20883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = tryGetCallbacks(oldCallbacks); 20893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != null) { 20903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAllApplications(list); 20919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 20923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 20933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound all " + list.size() + " apps from cache in " 2094a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 20959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 20963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2097c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung }; 2098c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung boolean isRunningOnMainThread = !(sWorkerThread.getThreadId() == Process.myTid()); 2099c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung if (oldCallbacks.isAllAppsVisible() && isRunningOnMainThread) { 2100c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung r.run(); 2101c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung } else { 2102c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung mHandler.post(r); 2103c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung } 21043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 21053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 21063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void loadAllAppsByBatch() { 21073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 21083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 21093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Don't use these two variables in any of the callback runnables. 21103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Otherwise we hold a reference to them. 21113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 21123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (oldCallbacks == null) { 21133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 21143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "LoaderTask running with no launcher (loadAllAppsByBatch)"); 21153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 21169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 211731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 21193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 2120cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 21213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final PackageManager packageManager = mContext.getPackageManager(); 21223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato List<ResolveInfo> apps = null; 21233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 21243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int N = Integer.MAX_VALUE; 21253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 21263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int startIndex; 21273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int i=0; 21283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int batchSize = -1; 21293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato while (i < N && !mStopped) { 21303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (i == 0) { 2131487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mBgAllAppsList.clear(); 21323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 21333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato apps = packageManager.queryIntentActivities(mainIntent, 0); 21343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 21353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "queryIntentActivities took " 21363611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis()-qiaTime) + "ms"); 21373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 21383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (apps == null) { 2139cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato return; 2140cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato } 21413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato N = apps.size(); 21423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 21433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "queryIntentActivities got " + N + " apps"); 21443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 21453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (N == 0) { 21463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // There are no apps?!? 21473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 21483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 21493611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mBatchSize == 0) { 21503611578579b4bfb25616085dafdb1a45207394f9Joe Onorato batchSize = N; 21513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 21523611578579b4bfb25616085dafdb1a45207394f9Joe Onorato batchSize = mBatchSize; 21533611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 21543611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 21553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long sortTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 21563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Collections.sort(apps, 2157c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung new LauncherModel.ShortcutNameComparator(packageManager, mLabelCache)); 21583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 21593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "sort took " 21603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis()-sortTime) + "ms"); 21613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2162cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato } 2163cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 21643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t2 = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 21653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 21663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato startIndex = i; 21673611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int j=0; i<N && j<batchSize; j++) { 21683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This builds the icon bitmaps. 2169487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mBgAllAppsList.add(new ApplicationInfo(packageManager, apps.get(i), 2170c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka mIconCache, mLabelCache)); 21713611578579b4bfb25616085dafdb1a45207394f9Joe Onorato i++; 2172cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato } 2173cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 21743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final boolean first = i <= batchSize; 21753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2176487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen final ArrayList<ApplicationInfo> added = mBgAllAppsList.added; 2177487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mBgAllAppsList.added = new ArrayList<ApplicationInfo>(); 21783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 2179cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato mHandler.post(new Runnable() { 2180cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato public void run() { 2181cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato final long t = SystemClock.uptimeMillis(); 2182cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato if (callbacks != null) { 21833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (first) { 21843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAllApplications(added); 21853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 21863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAppsAdded(added); 21873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 21883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 21893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound " + added.size() + " apps in " 21903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis() - t) + "ms"); 21913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 21923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 21933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.i(TAG, "not binding apps: no Launcher activity"); 2194cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato } 2195cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato } 2196cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato }); 2197cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 21983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 21993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "batch of " + (i-startIndex) + " icons processed in " 22003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis()-t2) + "ms"); 22013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 22023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 22033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mAllAppsLoadDelay > 0 && i < N) { 22043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato try { 22053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 22063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "sleeping for " + mAllAppsLoadDelay + "ms"); 22073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 22083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Thread.sleep(mAllAppsLoadDelay); 22093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } catch (InterruptedException exc) { } 22103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2211cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato } 2212cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 22133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 22143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "cached all " + N + " apps in " 22153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis()-t) + "ms" 22163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (mAllAppsLoadDelay > 0 ? " (including delay)" : "")); 22173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 22183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2219dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 22203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void dumpState() { 22212abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 2222b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mLoaderTask.mContext=" + mContext); 2223b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mLoaderTask.mIsLaunching=" + mIsLaunching); 2224b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mLoaderTask.mStopped=" + mStopped); 2225b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mLoaderTask.mLoadAndBindStepFinished=" + mLoadAndBindStepFinished); 2226b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mItems size=" + sBgWorkspaceItems.size()); 2227b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 22283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 22293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 223031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato void enqueuePackageUpdated(PackageUpdatedTask task) { 2232700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick sWorker.post(task); 22333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2234d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 22353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private class PackageUpdatedTask implements Runnable { 22363611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int mOp; 22373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato String[] mPackages; 2238d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 22393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_NONE = 0; 22403611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_ADD = 1; 22413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_UPDATE = 2; 22423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_REMOVE = 3; // uninstlled 22433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_UNAVAILABLE = 4; // external media unmounted 224431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2245d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 22463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public PackageUpdatedTask(int op, String[] packages) { 22473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mOp = op; 22483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mPackages = packages; 22493611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2250d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 22513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2252cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler final Context context = mApp.getContext(); 2253dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 22543611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String[] packages = mPackages; 22553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int N = packages.length; 22563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato switch (mOp) { 22573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_ADD: 22583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 22593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.addPackage " + packages[i]); 2260487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mBgAllAppsList.addPackage(context, packages[i]); 2261dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 22623611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 22633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_UPDATE: 22643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 22653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.updatePackage " + packages[i]); 2266487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mBgAllAppsList.updatePackage(context, packages[i]); 2267cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherAppState app = 2268cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherAppState.getInstance(); 2269d9cb4a124ac5c83080ace5ac92980df9c6f49e8eMichael Jurka WidgetPreviewLoader.removeFromDb( 2270d9cb4a124ac5c83080ace5ac92980df9c6f49e8eMichael Jurka app.getWidgetPreviewCacheDb(), packages[i]); 22713611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 22723611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 22733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_REMOVE: 22743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_UNAVAILABLE: 22753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 22763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]); 2277487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mBgAllAppsList.removePackage(packages[i]); 2278cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherAppState app = 2279cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler LauncherAppState.getInstance(); 2280d9cb4a124ac5c83080ace5ac92980df9c6f49e8eMichael Jurka WidgetPreviewLoader.removeFromDb( 2281d9cb4a124ac5c83080ace5ac92980df9c6f49e8eMichael Jurka app.getWidgetPreviewCacheDb(), packages[i]); 22823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 22833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 22843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2285dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 22863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato ArrayList<ApplicationInfo> added = null; 22873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato ArrayList<ApplicationInfo> modified = null; 228883892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung final ArrayList<ApplicationInfo> removedApps = new ArrayList<ApplicationInfo>(); 22893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 2290487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mBgAllAppsList.added.size() > 0) { 22915d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung added = new ArrayList<ApplicationInfo>(mBgAllAppsList.added); 22925d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.added.clear(); 22933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2294487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mBgAllAppsList.modified.size() > 0) { 22955d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung modified = new ArrayList<ApplicationInfo>(mBgAllAppsList.modified); 22965d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.modified.clear(); 22973611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 22985d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung if (mBgAllAppsList.removed.size() > 0) { 229983892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung removedApps.addAll(mBgAllAppsList.removed); 23005d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.removed.clear(); 2301cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung } 2302cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung 23033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null; 23043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks == null) { 23053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "Nobody to tell about the new app. Launcher is probably loading."); 23063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 2307be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 2308be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 23093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (added != null) { 23103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final ArrayList<ApplicationInfo> addedFinal = added; 23113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 23123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2313cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung Callbacks cb = mCallbacks != null ? mCallbacks.get() : null; 2314cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 23153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAppsAdded(addedFinal); 23163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 23173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 23183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 23193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 23203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (modified != null) { 23213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final ArrayList<ApplicationInfo> modifiedFinal = modified; 23223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 23233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2324cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung Callbacks cb = mCallbacks != null ? mCallbacks.get() : null; 2325cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 23263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAppsUpdated(modifiedFinal); 23273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 23283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 23293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 23303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 233183892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung // If a package has been removed, or an app has been removed as a result of 233283892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung // an update (for example), make the removed callback. 233383892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung if (mOp == OP_REMOVE || !removedApps.isEmpty()) { 233483892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung final boolean permanent = (mOp == OP_REMOVE); 233583892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung final ArrayList<String> removedPackageNames = 233683892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung new ArrayList<String>(Arrays.asList(packages)); 233783892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung 23383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 23393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2340cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung Callbacks cb = mCallbacks != null ? mCallbacks.get() : null; 2341cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 234283892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung callbacks.bindComponentsRemoved(removedPackageNames, 234383892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung removedApps, permanent); 23443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 23453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 23463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 2347be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 234880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 2349c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka final ArrayList<Object> widgetsAndShortcuts = 2350c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka getSortedWidgetsAndShortcuts(context); 235180baf5a6b3c62a62265f626d43d1167783c94131Winson Chung mHandler.post(new Runnable() { 235280baf5a6b3c62a62265f626d43d1167783c94131Winson Chung @Override 235380baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public void run() { 2354cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung Callbacks cb = mCallbacks != null ? mCallbacks.get() : null; 2355cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 2356c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka callbacks.bindPackagesUpdated(widgetsAndShortcuts); 235780baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 235880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 235980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung }); 236031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 236131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 236231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2363c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka // Returns a list of ResolveInfos/AppWindowInfos in sorted order 2364c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka public static ArrayList<Object> getSortedWidgetsAndShortcuts(Context context) { 2365c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka PackageManager packageManager = context.getPackageManager(); 2366c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka final ArrayList<Object> widgetsAndShortcuts = new ArrayList<Object>(); 2367c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka widgetsAndShortcuts.addAll(AppWidgetManager.getInstance(context).getInstalledProviders()); 2368c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); 2369c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka widgetsAndShortcuts.addAll(packageManager.queryIntentActivities(shortcutsIntent, 0)); 2370c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka Collections.sort(widgetsAndShortcuts, 2371c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka new LauncherModel.WidgetAndShortcutNameComparator(packageManager)); 2372c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka return widgetsAndShortcuts; 2373c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 2374c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka 23759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 237656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * This is called from the code that adds shortcuts from the intent receiver. This 237756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * doesn't have a Cursor, but 23789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 237956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, Context context) { 2380c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung return getShortcutInfo(manager, intent, context, null, -1, -1, null); 238156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 238256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 238356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato /** 238456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * Make an ShortcutInfo object for a shortcut that is an application. 238556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * 238656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * If c is not null, then it will be used to fill in missing data like the title and icon. 238756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato */ 238856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, Context context, 2389c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung Cursor c, int iconIndex, int titleIndex, HashMap<Object, CharSequence> labelCache) { 239056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap icon = null; 2391c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 239231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 239356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato ComponentName componentName = intent.getComponent(); 239456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (componentName == null) { 23959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 239631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 239731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 239800fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen try { 239900fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen PackageInfo pi = manager.getPackageInfo(componentName.getPackageName(), 0); 240000fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen if (!pi.applicationInfo.enabled) { 240100fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen // If we return null here, the corresponding item will be removed from the launcher 240200fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen // db and will not appear in the workspace. 240300fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen return null; 240400fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen } 240500fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen } catch (NameNotFoundException e) { 240600fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen Log.d(TAG, "getPackInfo failed for package " + componentName.getPackageName()); 240700fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen } 240800fcb49a4cf68b973ac488520f3ed20444c02f8dAdam Cohen 24098ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: See if the PackageManager knows about this case. If it doesn't 24108ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // then return null & delete this. 24118ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 241256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the resource -- This may implicitly give us back the fallback icon, 241356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // but don't worry about that. All we're doing with usingFallbackIcon is 241456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // to avoid saving lots of copies of that in the database, and most apps 241556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // have icons anyway. 2416c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung 2417c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung // Attempt to use queryIntentActivities to get the ResolveInfo (with IntentFilter info) and 2418c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung // if that fails, or is ambiguious, fallback to the standard way of getting the resolve info 2419c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung // via resolveActivity(). 2420c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung ResolveInfo resolveInfo = null; 2421c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung ComponentName oldComponent = intent.getComponent(); 2422c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung Intent newIntent = new Intent(intent.getAction(), null); 2423c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung newIntent.addCategory(Intent.CATEGORY_LAUNCHER); 2424c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung newIntent.setPackage(oldComponent.getPackageName()); 2425c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung List<ResolveInfo> infos = manager.queryIntentActivities(newIntent, 0); 2426c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung for (ResolveInfo i : infos) { 2427c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung ComponentName cn = new ComponentName(i.activityInfo.packageName, 2428c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung i.activityInfo.name); 2429c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung if (cn.equals(oldComponent)) { 2430c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung resolveInfo = i; 2431c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung } 2432c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung } 2433c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung if (resolveInfo == null) { 2434c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung resolveInfo = manager.resolveActivity(intent, 0); 2435c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung } 243656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resolveInfo != null) { 2437aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung icon = mIconCache.getIcon(componentName, resolveInfo, labelCache); 243856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 243956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the db 244056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 244156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (c != null) { 2442931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka icon = getIconFromCursor(c, iconIndex, context); 244356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 24449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 244556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the fallback icon 244656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 244756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 244856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 244956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 245056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.setIcon(icon); 245156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 245256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the resource 245356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resolveInfo != null) { 24545308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung ComponentName key = LauncherModel.getComponentNameFromResolveInfo(resolveInfo); 24555308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung if (labelCache != null && labelCache.containsKey(key)) { 24565308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung info.title = labelCache.get(key); 2457c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 2458c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung info.title = resolveInfo.activityInfo.loadLabel(manager); 2459c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung if (labelCache != null) { 24605308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung labelCache.put(key, info.title); 2461c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 2462c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 246356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 246456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the db 246556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (info.title == null) { 246656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (c != null) { 246756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = c.getString(titleIndex); 246856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 246956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 247056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // fall back to the class name of the activity 24719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (info.title == null) { 247256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = componentName.getClassName(); 24739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 24749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; 24759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 24769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 247731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 24789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 24798a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung * Returns the set of workspace ShortcutInfos with the specified intent. 24808a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung */ 24818a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung static ArrayList<ItemInfo> getWorkspaceShortcutItemInfosWithIntent(Intent intent) { 24828a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung ArrayList<ItemInfo> items = new ArrayList<ItemInfo>(); 24838a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung synchronized (sBgLock) { 24848a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung for (ItemInfo info : sBgWorkspaceItems) { 24858a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung if (info instanceof ShortcutInfo) { 24868a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung ShortcutInfo shortcut = (ShortcutInfo) info; 24878a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung if (shortcut.intent.toUri(0).equals(intent.toUri(0))) { 24888a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung items.add(shortcut); 24898a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 24908a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 24918a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 24928a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 24938a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung return items; 24948a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 24958a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung 24968a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung /** 24970589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Make an ShortcutInfo object for a shortcut that isn't an application. 24989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 24990589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private ShortcutInfo getShortcutInfo(Cursor c, Context context, 250056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex, 250156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato int titleIndex) { 250231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 250356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap icon = null; 2504c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 25059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 25067376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project 25078ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: If there's an explicit component and we can't install that, delete it. 25088ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 250956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = c.getString(titleIndex); 251056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 25119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconType = c.getInt(iconTypeIndex); 25129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (iconType) { 25139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_RESOURCE: 25149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String packageName = c.getString(iconPackageIndex); 25159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String resourceName = c.getString(iconResourceIndex); 25169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato PackageManager packageManager = context.getPackageManager(); 251756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = false; 251856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the resource 25199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 25209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Resources resources = packageManager.getResourcesForApplication(packageName); 252156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (resources != null) { 252256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato final int id = resources.getIdentifier(resourceName, null, null); 2523c9a961952d1a057029874f8426b90181f6876034Michael Jurka icon = Utilities.createIconBitmap( 2524c9a961952d1a057029874f8426b90181f6876034Michael Jurka mIconCache.getFullResIcon(resources, id), context); 252556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 25269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } catch (Exception e) { 252756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // drop this. we have other places to look for icons 252856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 252956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the db 253056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 2531931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka icon = getIconFromCursor(c, iconIndex, context); 253256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 253356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the fallback icon 253456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 253556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 253656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 25377376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project } 25389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 25399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_BITMAP: 2540931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka icon = getIconFromCursor(c, iconIndex, context); 254156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 254256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato icon = getFallbackIcon(); 254356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = false; 254456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 254556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } else { 254656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = true; 25479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 25489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 25499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato default: 2550d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato icon = getFallbackIcon(); 255156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 25529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.customIcon = false; 25539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 255431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 2555d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato info.setIcon(icon); 25569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 2557f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 255831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2559931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka Bitmap getIconFromCursor(Cursor c, int iconIndex, Context context) { 25603a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka @SuppressWarnings("all") // suppress dead code warning 25613a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka final boolean debug = false; 25623a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka if (debug) { 256356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.d(TAG, "getIconFromCursor app=" 256456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato + c.getString(c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE))); 256556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 256656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato byte[] data = c.getBlob(iconIndex); 256756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato try { 2568931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka return Utilities.createIconBitmap( 2569931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka BitmapFactory.decodeByteArray(data, 0, data.length), context); 257056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } catch (Exception e) { 257156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return null; 257256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 257356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 257456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 25753d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung ShortcutInfo addShortcut(Context context, Intent data, long container, int screen, 25763d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung int cellX, int cellY, boolean notify) { 2577a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final ShortcutInfo info = infoFromShortcutIntent(context, data, null); 2578d919882006a457d16dea46bd546472e6534b5c19Adam Cohen if (info == null) { 2579d919882006a457d16dea46bd546472e6534b5c19Adam Cohen return null; 2580d919882006a457d16dea46bd546472e6534b5c19Adam Cohen } 25813d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung addItemToDatabase(context, info, container, screen, cellX, cellY, notify); 25820589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 25830589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 25840589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 25850589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 2586a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung /** 258755cef262f97749300c2f6e764da0b00cbcb78879Winson Chung * Attempts to find an AppWidgetProviderInfo that matches the given component. 258855cef262f97749300c2f6e764da0b00cbcb78879Winson Chung */ 258955cef262f97749300c2f6e764da0b00cbcb78879Winson Chung AppWidgetProviderInfo findAppWidgetProviderInfoWithComponent(Context context, 259055cef262f97749300c2f6e764da0b00cbcb78879Winson Chung ComponentName component) { 259155cef262f97749300c2f6e764da0b00cbcb78879Winson Chung List<AppWidgetProviderInfo> widgets = 259255cef262f97749300c2f6e764da0b00cbcb78879Winson Chung AppWidgetManager.getInstance(context).getInstalledProviders(); 259355cef262f97749300c2f6e764da0b00cbcb78879Winson Chung for (AppWidgetProviderInfo info : widgets) { 259455cef262f97749300c2f6e764da0b00cbcb78879Winson Chung if (info.provider.equals(component)) { 259555cef262f97749300c2f6e764da0b00cbcb78879Winson Chung return info; 259655cef262f97749300c2f6e764da0b00cbcb78879Winson Chung } 259755cef262f97749300c2f6e764da0b00cbcb78879Winson Chung } 259855cef262f97749300c2f6e764da0b00cbcb78879Winson Chung return null; 2599a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 2600a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 260168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung /** 260268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung * Returns a list of all the widgets that can handle configuration with a particular mimeType. 260368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung */ 260468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung List<WidgetMimeTypeHandlerData> resolveWidgetsForMimeType(Context context, String mimeType) { 260568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final PackageManager packageManager = context.getPackageManager(); 260668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final List<WidgetMimeTypeHandlerData> supportedConfigurationActivities = 260768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung new ArrayList<WidgetMimeTypeHandlerData>(); 260868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung 260968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final Intent supportsIntent = 261068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung new Intent(InstallWidgetReceiver.ACTION_SUPPORTS_CLIPDATA_MIMETYPE); 261168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung supportsIntent.setType(mimeType); 261268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung 261368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // Create a set of widget configuration components that we can test against 261468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final List<AppWidgetProviderInfo> widgets = 261568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung AppWidgetManager.getInstance(context).getInstalledProviders(); 261668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final HashMap<ComponentName, AppWidgetProviderInfo> configurationComponentToWidget = 261768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung new HashMap<ComponentName, AppWidgetProviderInfo>(); 261868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung for (AppWidgetProviderInfo info : widgets) { 261968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung configurationComponentToWidget.put(info.configure, info); 262068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung } 262168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung 262268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // Run through each of the intents that can handle this type of clip data, and cross 262368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // reference them with the components that are actual configuration components 262468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final List<ResolveInfo> activities = packageManager.queryIntentActivities(supportsIntent, 262568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung PackageManager.MATCH_DEFAULT_ONLY); 262668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung for (ResolveInfo info : activities) { 262768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final ActivityInfo activityInfo = info.activityInfo; 262868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final ComponentName infoComponent = new ComponentName(activityInfo.packageName, 262968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung activityInfo.name); 263068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung if (configurationComponentToWidget.containsKey(infoComponent)) { 263168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung supportedConfigurationActivities.add( 263268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung new InstallWidgetReceiver.WidgetMimeTypeHandlerData(info, 263368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung configurationComponentToWidget.get(infoComponent))); 263468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung } 263568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung } 263668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung return supportedConfigurationActivities; 263768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung } 263868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung 2639a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) { 26400589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 26410589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); 26420589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON); 26430589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 2644d919882006a457d16dea46bd546472e6534b5c19Adam Cohen if (intent == null) { 2645d919882006a457d16dea46bd546472e6534b5c19Adam Cohen // If the intent is null, we can't construct a valid ShortcutInfo, so we return null 2646d919882006a457d16dea46bd546472e6534b5c19Adam Cohen Log.e(TAG, "Can't construct ShorcutInfo with null intent"); 2647d919882006a457d16dea46bd546472e6534b5c19Adam Cohen return null; 2648d919882006a457d16dea46bd546472e6534b5c19Adam Cohen } 2649d919882006a457d16dea46bd546472e6534b5c19Adam Cohen 26500589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Bitmap icon = null; 26510589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato boolean customIcon = false; 26520589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutIconResource iconResource = null; 26530589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 26540589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (bitmap != null && bitmap instanceof Bitmap) { 26550589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato icon = Utilities.createIconBitmap(new FastBitmapDrawable((Bitmap)bitmap), context); 26560589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato customIcon = true; 26570589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } else { 26580589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 26590589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (extra != null && extra instanceof ShortcutIconResource) { 26600589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato try { 26610589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato iconResource = (ShortcutIconResource) extra; 26620589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final PackageManager packageManager = context.getPackageManager(); 26630589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Resources resources = packageManager.getResourcesForApplication( 26640589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato iconResource.packageName); 26650589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final int id = resources.getIdentifier(iconResource.resourceName, null, null); 2666c9a961952d1a057029874f8426b90181f6876034Michael Jurka icon = Utilities.createIconBitmap( 2667c9a961952d1a057029874f8426b90181f6876034Michael Jurka mIconCache.getFullResIcon(resources, id), context); 26680589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } catch (Exception e) { 26690589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Log.w(TAG, "Could not load shortcut icon: " + extra); 26700589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 26710589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 26720589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 26730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 2674c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 267556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 26760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (icon == null) { 2677a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung if (fallbackIcon != null) { 2678a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung icon = fallbackIcon; 2679a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } else { 2680a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung icon = getFallbackIcon(); 2681a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung info.usingFallbackIcon = true; 2682a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 26830589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 26840589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.setIcon(icon); 268556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 26860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.title = name; 26870589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.intent = intent; 26880589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.customIcon = customIcon; 26890589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.iconResource = iconResource; 26900589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 26910589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 26920589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 26930589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 2694aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung boolean queueIconToBeChecked(HashMap<Object, byte[]> cache, ShortcutInfo info, Cursor c, 2695aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung int iconIndex) { 269617a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato // If apps can't be on SD, don't even bother. 269717a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato if (!mAppsCanBeOnExternalStorage) { 2698aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung return false; 269917a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato } 270056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // If this icon doesn't have a custom icon, check to see 270156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // what's stored in the DB, and if it doesn't match what 270256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // we're going to show, store what we are going to show back 270356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // into the DB. We do this so when we're loading, if the 270456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // package manager can't find an icon (for example because 270556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the app is on SD) then we can use that instead. 2706ddc9c1fb1ab426772add520d277ea9c2cd674094Joe Onorato if (!info.customIcon && !info.usingFallbackIcon) { 2707aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung cache.put(info, c.getBlob(iconIndex)); 2708aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung return true; 2709aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } 2710aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung return false; 2711aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } 2712aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung void updateSavedIcon(Context context, ShortcutInfo info, byte[] data) { 2713aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung boolean needSave = false; 2714aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung try { 2715aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (data != null) { 2716aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung Bitmap saved = BitmapFactory.decodeByteArray(data, 0, data.length); 2717aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung Bitmap loaded = info.getIcon(mIconCache); 2718aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung needSave = !saved.sameAs(loaded); 2719aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } else { 272056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato needSave = true; 272156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 2722aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } catch (Exception e) { 2723aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung needSave = true; 2724aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } 2725aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (needSave) { 2726aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung Log.d(TAG, "going to save icon bitmap for info=" + info); 2727aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung // This is slower than is ideal, but this only happens once 2728aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung // or when the app is updated with a new icon. 2729aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung updateItemInDatabase(context, info); 273056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 273156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 273256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 273331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 2734df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * Return an existing FolderInfo object if we have encountered this ID previously, 27359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * or make a new one. 273631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 2737df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private static FolderInfo findOrMakeFolder(HashMap<Long, FolderInfo> folders, long id) { 27389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // See if a placeholder was created for us already 27399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = folders.get(id); 2740df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (folderInfo == null) { 27419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // No placeholder -- create a new instance 2742c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka folderInfo = new FolderInfo(); 27439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folders.put(id, folderInfo); 274431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 2745df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return folderInfo; 274631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 274731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 27481190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung public static final Comparator<ApplicationInfo> getAppNameComparator() { 27491190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung final Collator collator = Collator.getInstance(); 27501190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung return new Comparator<ApplicationInfo>() { 27511190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung public final int compare(ApplicationInfo a, ApplicationInfo b) { 27521190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung int result = collator.compare(a.title.toString(), b.title.toString()); 27531190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung if (result == 0) { 27541190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung result = a.componentName.compareTo(b.componentName); 27551190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung } 27561190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung return result; 27575b1808da75ed3e3528cb31dee56a4e363812cc21Michael Jurka } 27581190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung }; 27591190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung } 276078403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung public static final Comparator<ApplicationInfo> APP_INSTALL_TIME_COMPARATOR 276178403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung = new Comparator<ApplicationInfo>() { 276278403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung public final int compare(ApplicationInfo a, ApplicationInfo b) { 276378403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung if (a.firstInstallTime < b.firstInstallTime) return 1; 276478403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung if (a.firstInstallTime > b.firstInstallTime) return -1; 276578403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung return 0; 276678403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung } 276778403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung }; 27681190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung public static final Comparator<AppWidgetProviderInfo> getWidgetNameComparator() { 27691190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung final Collator collator = Collator.getInstance(); 27701190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung return new Comparator<AppWidgetProviderInfo>() { 27711190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung public final int compare(AppWidgetProviderInfo a, AppWidgetProviderInfo b) { 27721190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung return collator.compare(a.label.toString(), b.label.toString()); 27731190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung } 27741190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung }; 27751190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung } 27765308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung static ComponentName getComponentNameFromResolveInfo(ResolveInfo info) { 27775308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung if (info.activityInfo != null) { 27785308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung return new ComponentName(info.activityInfo.packageName, info.activityInfo.name); 27795308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung } else { 27805308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung return new ComponentName(info.serviceInfo.packageName, info.serviceInfo.name); 27815308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung } 27825308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung } 2783785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public static class ShortcutNameComparator implements Comparator<ResolveInfo> { 27841190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung private Collator mCollator; 2785785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung private PackageManager mPackageManager; 2786c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung private HashMap<Object, CharSequence> mLabelCache; 2787785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung ShortcutNameComparator(PackageManager pm) { 2788785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung mPackageManager = pm; 2789c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache = new HashMap<Object, CharSequence>(); 27901190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung mCollator = Collator.getInstance(); 2791c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 2792c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung ShortcutNameComparator(PackageManager pm, HashMap<Object, CharSequence> labelCache) { 2793c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mPackageManager = pm; 2794c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache = labelCache; 27951190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung mCollator = Collator.getInstance(); 2796785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 2797785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung public final int compare(ResolveInfo a, ResolveInfo b) { 2798c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung CharSequence labelA, labelB; 27995308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung ComponentName keyA = LauncherModel.getComponentNameFromResolveInfo(a); 28005308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung ComponentName keyB = LauncherModel.getComponentNameFromResolveInfo(b); 28015308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung if (mLabelCache.containsKey(keyA)) { 28025308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung labelA = mLabelCache.get(keyA); 2803c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 2804c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung labelA = a.loadLabel(mPackageManager).toString(); 2805c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung 28065308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung mLabelCache.put(keyA, labelA); 2807c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 28085308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung if (mLabelCache.containsKey(keyB)) { 28095308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung labelB = mLabelCache.get(keyB); 2810c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 2811c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung labelB = b.loadLabel(mPackageManager).toString(); 2812c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung 28135308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung mLabelCache.put(keyB, labelB); 2814c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 28151190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung return mCollator.compare(labelA, labelB); 2816785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 2817785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung }; 28181ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung public static class WidgetAndShortcutNameComparator implements Comparator<Object> { 28191190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung private Collator mCollator; 28201ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung private PackageManager mPackageManager; 28211ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung private HashMap<Object, String> mLabelCache; 28221ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung WidgetAndShortcutNameComparator(PackageManager pm) { 28231ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung mPackageManager = pm; 28241ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung mLabelCache = new HashMap<Object, String>(); 28251190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung mCollator = Collator.getInstance(); 28261ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung } 28271ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung public final int compare(Object a, Object b) { 28281ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung String labelA, labelB; 2829c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung if (mLabelCache.containsKey(a)) { 2830c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung labelA = mLabelCache.get(a); 2831c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 2832c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung labelA = (a instanceof AppWidgetProviderInfo) ? 28331ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung ((AppWidgetProviderInfo) a).label : 28341ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung ((ResolveInfo) a).loadLabel(mPackageManager).toString(); 2835c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache.put(a, labelA); 2836c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 2837c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung if (mLabelCache.containsKey(b)) { 2838c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung labelB = mLabelCache.get(b); 2839c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 2840c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung labelB = (b instanceof AppWidgetProviderInfo) ? 28411ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung ((AppWidgetProviderInfo) b).label : 28421ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung ((ResolveInfo) b).loadLabel(mPackageManager).toString(); 2843c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache.put(b, labelB); 2844c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 28451190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung return mCollator.compare(labelA, labelB); 28461ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung } 28471ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung }; 2848be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 2849be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 2850be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mCallbacks=" + mCallbacks); 2851487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.data", mBgAllAppsList.data); 2852487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.added", mBgAllAppsList.added); 2853487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.removed", mBgAllAppsList.removed); 2854487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.modified", mBgAllAppsList.modified); 28553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask != null) { 28563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask.dumpState(); 28573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 28583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "mLoaderTask=null"); 28593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2860be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 286131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 2862