LauncherModel.java revision c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594
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.AppWidgetProviderInfo; 21f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.BroadcastReceiver; 22f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ComponentName; 23f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ContentProviderClient; 24f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ContentProviderOperation; 25f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ContentResolver; 26f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ContentValues; 27f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.Context; 28f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.Intent; 290589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.content.Intent.ShortcutIconResource; 30f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.IntentFilter; 31f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.SharedPreferences; 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.PackageManager; 33bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monkimport android.content.pm.ProviderInfo; 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ResolveInfo; 3593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Leeimport android.content.res.Configuration; 3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.Resources; 3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.database.Cursor; 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.BitmapFactory; 4071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.graphics.Rect; 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; 49c3919c0e994309982efc8779af57e2bc78dcac43Chris Wrenimport android.provider.BaseColumns; 50a90303bb6fdad59e4a55855edba68c9902192599Winson Chungimport android.text.TextUtils; 51aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.util.Log; 5271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.util.LongSparseArray; 53c916834ad0da535f08325bcd902a60070f2f7e53Winson Chungimport android.util.Pair; 5434c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurka 55ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyalimport com.android.launcher3.compat.AppWidgetManagerCompat; 56ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherActivityInfoCompat; 57ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherAppsCompat; 58349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat; 59e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo; 60ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.UserHandleCompat; 61ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.UserManagerCompat; 62edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 63c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.lang.ref.WeakReference; 64c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.net.URISyntaxException; 65349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport java.security.InvalidParameterException; 66c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.text.Collator; 67c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.ArrayList; 68dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohenimport java.util.Arrays; 6964359a53dc827797917a8d9a0697a91996789801Winson Chungimport java.util.Collection; 70c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.Collections; 71c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.Comparator; 72c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.HashMap; 73b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chungimport java.util.HashSet; 742abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chungimport java.util.Iterator; 75c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.List; 76f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport java.util.Map.Entry; 77b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chungimport java.util.Set; 78c2f801e770b4f80354b3edb722ec04222251990cMichael Jurka 7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Maintains in-memory state of the Launcher. It is expected that there should be only one 8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * LauncherModel object held in a static. Also provide APIs for updating the database state 82bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project * for the Launcher. 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 84ed13187a745866483139e2878037e1f8427ce567Kenny Guypublic class LauncherModel extends BroadcastReceiver 85c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy implements LauncherAppsCompat.OnAppsChangedCallbackCompat { 86a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato static final boolean DEBUG_LOADERS = false; 87ee52336a9ed0c98f78831a0e44b21f5a8d8c17d1Chris Wren private static final boolean DEBUG_RECEIVER = false; 889448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal private static final boolean REMOVE_UNRESTORED_ICONS = true; 892a66bbf3f01c2be20ecbf9df4dd9e98d50ed119fSunny Goyal private static final boolean ADD_MANAGED_PROFILE_SHORTCUTS = false; 90b358f813c93ac0d6c4f31058947efd16b188cd1eChris Wren 919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static final String TAG = "Launcher.Model"; 929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 938707e0fa1ca2c79be862c29cb919b7372f0b6a50Daniel Sandler // true = use a "More Apps" folder for non-workspace apps on upgrade 948707e0fa1ca2c79be862c29cb919b7372f0b6a50Daniel Sandler // false = strew non-workspace apps across the workspace on upgrade 958707e0fa1ca2c79be862c29cb919b7372f0b6a50Daniel Sandler public static final boolean UPGRADE_USE_MORE_APPS_FOLDER = false; 96d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler public static final int LOADER_FLAG_NONE = 0; 97d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler public static final int LOADER_FLAG_CLEAR_WORKSPACE = 1 << 0; 98d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler public static final int LOADER_FLAG_MIGRATE_SHORTCUTS = 1 << 1; 99d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler 1003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons 1017aff399974c756930070d82d7b2df88f125dacd6Derek Prothro private static final long INVALID_SCREEN_ID = -1L; 102a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung 103ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung private final boolean mAppsCanBeOnRemoveableStorage; 104a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung private final boolean mOldContentProviderExists; 105dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 106cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler private final LauncherAppState mApp; 1079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private final Object mLock = new Object(); 1089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private DeferredHandler mHandler = new DeferredHandler(); 1093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private LoaderTask mLoaderTask; 110b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private boolean mIsLoaderTaskRunning; 1119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 112e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal /** 113e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal * Maintain a set of packages per user, for which we added a shortcut on the workspace. 114e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal */ 115e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal private static final String INSTALLED_SHORTCUTS_SET_PREFIX = "installed_shortcuts_set_for_user_"; 116e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 11781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Specific runnable types that are run on the main thread deferred handler, this allows us to 11881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // clear all queued binding runnables when the Launcher activity is destroyed. 11981b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung private static final int MAIN_THREAD_NORMAL_RUNNABLE = 0; 12081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung private static final int MAIN_THREAD_BINDING_RUNNABLE = 1; 12181b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung 122bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk private static final String MIGRATE_AUTHORITY = "com.android.launcher2.settings"; 12381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung 124700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); 125700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick static { 126700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick sWorkerThread.start(); 127700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick } 128700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick private static final Handler sWorker = new Handler(sWorkerThread.getLooper()); 129700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick 130cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // We start off with everything not loaded. After that, we assume that 131cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // our monitoring of the package manager provides all updates and we never 132cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // need to do a requery. These are only ever touched from the loader thread. 133cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato private boolean mWorkspaceLoaded; 134cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato private boolean mAllAppsLoaded; 135cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 136b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // When we are loading pages synchronously, we can't just post the binding of items on the side 137b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // pages as this delays the rotation process. Instead, we wait for a callback from the first 138b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // draw (in Workspace) to initiate the binding of the remaining side pages. Any time we start 139b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // a normal load, we also clear this set of Runnables. 140b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung static final ArrayList<Runnable> mDeferredBindRunnables = new ArrayList<Runnable>(); 141b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato private WeakReference<Callbacks> mCallbacks; 1439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 144a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // < only access in worker thread > 1454caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen AllAppsList mBgAllAppsList; 146a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 147b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // The lock that must be acquired before referencing any static bg data structures. Unlike 148b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // other locks, this one can generally be held long-term because we never expect any of these 149b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // static data structures to be referenced outside of the worker thread except on the first 150b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // load after configuration change. 1512abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung static final Object sBgLock = new Object(); 152b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 153487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgItemsIdMap maps *all* the ItemInfos (shortcuts, folders, and widgets) created by 154a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // LauncherModel to their ids 155487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final HashMap<Long, ItemInfo> sBgItemsIdMap = new HashMap<Long, ItemInfo>(); 156a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 157487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgWorkspaceItems is passed to bindItems, which expects a list of all folders and shortcuts 158487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // created by LauncherModel that are directly on the home screen (however, no widgets or 159487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // shortcuts within folders). 160487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final ArrayList<ItemInfo> sBgWorkspaceItems = new ArrayList<ItemInfo>(); 1610589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 162487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgAppWidgets is all LauncherAppWidgetInfo created by LauncherModel. Passed to bindAppWidget() 163487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final ArrayList<LauncherAppWidgetInfo> sBgAppWidgets = 164a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka new ArrayList<LauncherAppWidgetInfo>(); 165a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 166487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgFolders is all FolderInfos created by LauncherModel. Passed to bindFolders() 167487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final HashMap<Long, FolderInfo> sBgFolders = new HashMap<Long, FolderInfo>(); 168b1094bd9630f659cc606853b8a244b6a6b6c6943Winson Chung 169487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgDbIconCache is the set of ItemInfos that need to have their icons updated in the database 170487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final HashMap<Object, byte[]> sBgDbIconCache = new HashMap<Object, byte[]>(); 171dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 172dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // sBgWorkspaceScreens is the ordered set of workspace screens. 173dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen static final ArrayList<Long> sBgWorkspaceScreens = new ArrayList<Long>(); 174dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1755940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen // sBgWidgetProviders is the set of widget providers including custom internal widgets 1765940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen public static HashMap<ComponentName, LauncherAppWidgetProviderInfo> sBgWidgetProviders; 1775940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen public static boolean sWidgetProvidersDirty; 1785940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 179f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // sPendingPackages is a set of packages which could be on sdcard and are not available yet 180513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala static final HashMap<UserHandleCompat, HashSet<String>> sPendingPackages = 181513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala new HashMap<UserHandleCompat, HashSet<String>>(); 182f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 183a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // </ only access in worker thread > 184a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 185a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka private IconCache mIconCache; 1869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 18799a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee protected int mPreviousConfigMcc; 18893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 189ed13187a745866483139e2878037e1f8427ce567Kenny Guy private final LauncherAppsCompat mLauncherApps; 190ed13187a745866483139e2878037e1f8427ce567Kenny Guy private final UserManagerCompat mUserManager; 191ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public interface Callbacks { 193ef2efcff5e70e5900f4f10f9e46c3fa17c03b0ecJoe Onorato public boolean setLoadOnResume(); 1949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public int getCurrentWorkspaceScreen(); 1959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startBinding(); 19664359a53dc827797917a8d9a0697a91996789801Winson Chung public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end, 19764359a53dc827797917a8d9a0697a91996789801Winson Chung boolean forceAnimateIcons); 198dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void bindScreens(ArrayList<Long> orderedScreenIds); 19964359a53dc827797917a8d9a0697a91996789801Winson Chung public void bindAddScreens(ArrayList<Long> orderedScreenIds); 200ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato public void bindFolders(HashMap<Long,FolderInfo> folders); 201e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen public void finishBindingItems(boolean upgradePath); 2029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAppWidget(LauncherAppWidgetInfo info); 203eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public void bindAllApplications(ArrayList<AppInfo> apps); 204d64d1763c590b1c954b759156683abf39ff22945Winson Chung public void bindAppsAdded(ArrayList<Long> newScreens, 205d64d1763c590b1c954b759156683abf39ff22945Winson Chung ArrayList<ItemInfo> addNotAnimated, 206c58497ee619416c4949b16eb43486c11618b69e5Winson Chung ArrayList<ItemInfo> addAnimated, 207c58497ee619416c4949b16eb43486c11618b69e5Winson Chung ArrayList<AppInfo> addedApps); 208eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public void bindAppsUpdated(ArrayList<AppInfo> apps); 2094390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated, 2104390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ArrayList<ShortcutInfo> removed, UserHandleCompat user); 2114390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets); 212e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void updatePackageState(ArrayList<PackageInstallInfo> installInfo); 213a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal public void updatePackageBadge(String packageName); 21483892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung public void bindComponentsRemoved(ArrayList<String> packageNames, 2151a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal ArrayList<AppInfo> appInfos, UserHandleCompat user, int reason); 216c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts); 217cb1a4778686a46c46d8dc88b6c83674f6fac6592Narayan Kamath public void bindSearchablesChanged(); 218a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung public boolean isAllAppsButtonRank(int rank); 2191462de39f01cec0ba785386532719cb0207dd827Adam Cohen public void onPageBoundSynchronously(int page); 220ede4129e77f8347e32c0da9c615bcff2cbc06fd8Winson Chung public void dumpLogsToLocalData(); 22171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal public void bindAddPendingItem(PendingAddItemInfo info, long container, long screenId, 22271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] cell, int spanX, int spanY); 2239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22564359a53dc827797917a8d9a0697a91996789801Winson Chung public interface ItemInfoFilter { 22664359a53dc827797917a8d9a0697a91996789801Winson Chung public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn); 22764359a53dc827797917a8d9a0697a91996789801Winson Chung } 22864359a53dc827797917a8d9a0697a91996789801Winson Chung 22971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal public interface ScreenPosProvider { 23071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int getScreenIndex(ArrayList<Long> screenIDs); 23171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 23271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 2331307f63f8a93541bf6e2d29c11fab69778a25e42Bjorn Bringert LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) { 234a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung Context context = app.getContext(); 235e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler 236ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung mAppsCanBeOnRemoveableStorage = Environment.isExternalStorageRemovable(); 23771483f417bb19f524cda41081f5ccac6084dc103Adam Cohen String oldProvider = context.getString(R.string.old_launcher_provider_uri); 238bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk // This may be the same as MIGRATE_AUTHORITY, or it may be replaced by a different 239bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk // resource string. 240bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk String redirectAuthority = Uri.parse(oldProvider).getAuthority(); 241bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk ProviderInfo providerInfo = 242bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk context.getPackageManager().resolveContentProvider(MIGRATE_AUTHORITY, 0); 243bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk ProviderInfo redirectProvider = 244bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk context.getPackageManager().resolveContentProvider(redirectAuthority, 0); 24571483f417bb19f524cda41081f5ccac6084dc103Adam Cohen 24671483f417bb19f524cda41081f5ccac6084dc103Adam Cohen Log.d(TAG, "Old launcher provider: " + oldProvider); 247bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk mOldContentProviderExists = (providerInfo != null) && (redirectProvider != null); 24871483f417bb19f524cda41081f5ccac6084dc103Adam Cohen 24971483f417bb19f524cda41081f5ccac6084dc103Adam Cohen if (mOldContentProviderExists) { 25071483f417bb19f524cda41081f5ccac6084dc103Adam Cohen Log.d(TAG, "Old launcher provider exists."); 25171483f417bb19f524cda41081f5ccac6084dc103Adam Cohen } else { 25271483f417bb19f524cda41081f5ccac6084dc103Adam Cohen Log.d(TAG, "Old launcher provider does not exist."); 25371483f417bb19f524cda41081f5ccac6084dc103Adam Cohen } 25471483f417bb19f524cda41081f5ccac6084dc103Adam Cohen 255e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mApp = app; 2561307f63f8a93541bf6e2d29c11fab69778a25e42Bjorn Bringert mBgAllAppsList = new AllAppsList(iconCache, appFilter); 2570589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = iconCache; 2580589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 259cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler final Resources res = context.getResources(); 26099a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee Configuration config = res.getConfiguration(); 26199a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee mPreviousConfigMcc = config.mcc; 262ed13187a745866483139e2878037e1f8427ce567Kenny Guy mLauncherApps = LauncherAppsCompat.getInstance(context); 263ed13187a745866483139e2878037e1f8427ce567Kenny Guy mUserManager = UserManagerCompat.getInstance(context); 2640589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 2650589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 266b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Runs the specified runnable immediately if called from the main thread, otherwise it is 267b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * posted on the main thread handler. */ 268b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void runOnMainThread(Runnable r) { 26981b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, 0); 27081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung } 27181b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung private void runOnMainThread(Runnable r, int type) { 272b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 273b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we are on the worker thread, post onto the main handler 274b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mHandler.post(r); 275b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 276b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r.run(); 277b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 278b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 279b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 280b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Runs the specified runnable immediately if called from the worker thread, otherwise it is 281b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * posted on the worker thread handler. */ 282b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private static void runOnWorkerThread(Runnable r) { 283b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 284b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r.run(); 285b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 286b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we are not on the worker thread, then post to the worker handler 287b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorker.post(r); 288b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 289b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 290b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 291e43a1e788223ab5a4405c5eeb0133ff57efbc768Winson Chung boolean canMigrateFromOldLauncherDb(Launcher launcher) { 292e43a1e788223ab5a4405c5eeb0133ff57efbc768Winson Chung return mOldContentProviderExists && !launcher.isLauncherPreinstalled() ; 293a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung } 294a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung 295e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal public void setPackageState(final ArrayList<PackageInstallInfo> installInfo) { 296aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren // Process the updated package state 297aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren Runnable r = new Runnable() { 298aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren public void run() { 299e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks callbacks = getCallback(); 300aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren if (callbacks != null) { 301e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyal callbacks.updatePackageState(installInfo); 302aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } 303aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } 304aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren }; 305aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren mHandler.post(r); 306aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } 307aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren 308a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal public void updatePackageBadge(final String packageName) { 309a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal // Process the updated package badge 310a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal Runnable r = new Runnable() { 311a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal public void run() { 312e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks callbacks = getCallback(); 313a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal if (callbacks != null) { 314a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal callbacks.updatePackageBadge(packageName); 315a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 316a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 317a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal }; 318a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal mHandler.post(r); 319a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 320a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal 32176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void addAppsToAllApps(final Context ctx, final ArrayList<AppInfo> allAppsApps) { 322e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final Callbacks callbacks = getCallback(); 32376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 32476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (allAppsApps == null) { 32576a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen throw new RuntimeException("allAppsApps must not be null"); 32676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 32776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (allAppsApps.isEmpty()) { 32876a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen return; 32976a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 33076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 33176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen // Process the newly added applications and add them to the database first 33276a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen Runnable r = new Runnable() { 33376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void run() { 33476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen runOnMainThread(new Runnable() { 33576a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void run() { 336e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 33776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (callbacks == cb && cb != null) { 3386d0dde01f307051ee1849481c989d9e87774b894Chris Wren callbacks.bindAppsAdded(null, null, null, allAppsApps); 33976a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 34076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 34176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen }); 34276a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 34376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen }; 34476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen runOnWorkerThread(r); 345997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 34676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 34776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void addAndBindAddedWorkspaceApps(final Context context, 34876a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen final ArrayList<ItemInfo> workspaceApps) { 34971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal addAndBindAddedWorkspaceApps(context, workspaceApps, 35071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal new ScreenPosProvider() { 35171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 35271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal @Override 35371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal public int getScreenIndex(ArrayList<Long> screenIDs) { 35471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal return screenIDs.isEmpty() ? 0 : 1; 35571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 35671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal }, 1, false); 35771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 35871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 35971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal private static boolean findNextAvailableIconSpaceInScreen(ArrayList<Rect> occupiedPos, 36071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] xy, int spanX, int spanY) { 36171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherAppState app = LauncherAppState.getInstance(); 36271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 36371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int xCount = (int) grid.numColumns; 36471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int yCount = (int) grid.numRows; 36571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal boolean[][] occupied = new boolean[xCount][yCount]; 36671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (occupiedPos != null) { 36771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal for (Rect r : occupiedPos) { 36871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal for (int x = r.left; 0 <= x && x < r.right && x < xCount; x++) { 36971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal for (int y = r.top; 0 <= y && y < r.bottom && y < yCount; y++) { 37071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal occupied[x][y] = true; 37171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 37271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 37371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 37471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 37571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal return CellLayout.findVacantCell(xy, spanX, spanY, xCount, yCount, occupied); 37671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 37771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 37871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal /** 37971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * Find a position on the screen for the given size or adds a new screen. 38071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * @return screenId and the coordinates for the item. 38171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal */ 38271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal private static Pair<Long, int[]> findSpaceForItem( 38371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal Context context, 38471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal ScreenPosProvider preferredScreen, 38571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int fallbackStartScreen, 38671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal ArrayList<Long> workspaceScreens, 38771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal ArrayList<Long> addedWorkspaceScreensFinal, 38871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int spanX, int spanY) { 38971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Load position of items which are on the desktop. We can't use sBgItemsIdMap because 39071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // loadWorkspace() may not have been called. 39171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final ContentResolver cr = context.getContentResolver(); 39271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, 39371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal new String[] { 39471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherSettings.Favorites.SCREEN, 39571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherSettings.Favorites.CELLX, 39671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherSettings.Favorites.CELLY, 39771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherSettings.Favorites.SPANX, 39871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherSettings.Favorites.SPANY, 39971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherSettings.Favorites.CONTAINER 40071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal }, 40171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal "container=?", 40271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal new String[] { Integer.toString(LauncherSettings.Favorites.CONTAINER_DESKTOP) }, 40371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal null); 40471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 40571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); 40671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); 40771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); 40871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX); 40971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY); 41071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LongSparseArray<ArrayList<Rect>> screenItems = new LongSparseArray<ArrayList<Rect>>(); 41171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal try { 41271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal while (c.moveToNext()) { 41371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal Rect rect = new Rect(); 41471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal rect.left = c.getInt(cellXIndex); 41571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal rect.top = c.getInt(cellYIndex); 41671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal rect.right = rect.left + Math.max(1, c.getInt(spanXIndex)); 41771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal rect.bottom = rect.top + Math.max(1, c.getInt(spanYIndex)); 41871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 41971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal long screenId = c.getInt(screenIndex); 42071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal ArrayList<Rect> items = screenItems.get(screenId); 42171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (items == null) { 42271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal items = new ArrayList<Rect>(); 42371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.put(screenId, items); 42471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 42571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal items.add(rect); 42671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 42771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } catch (Exception e) { 42871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.clear(); 42971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } finally { 43071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal c.close(); 43171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 43271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 43371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Find appropriate space for the item. 43471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal long screenId = 0; 43571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] cordinates = new int[2]; 43671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal boolean found = false; 43771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 43871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int screenCount = workspaceScreens.size(); 43971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // First check the preferred screen. 44071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int preferredScreenIndex = preferredScreen.getScreenIndex(workspaceScreens); 44171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (preferredScreenIndex < screenCount) { 44271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId = workspaceScreens.get(preferredScreenIndex); 44371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal found = findNextAvailableIconSpaceInScreen( 44471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY); 44571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 44671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 44771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!found) { 44871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Search on any of the screens. 44971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal for (int screen = fallbackStartScreen; screen < screenCount; screen++) { 45071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId = workspaceScreens.get(screen); 45171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (findNextAvailableIconSpaceInScreen( 45271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY)) { 45371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // We found a space for it 45471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal found = true; 45571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal break; 45671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 45771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 45871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 45971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 46071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!found) { 46171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Still no position found. Add a new screen to the end. 46271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId = LauncherAppState.getLauncherProvider().generateNewScreenId(); 46371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 46471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Save the screen id for binding in the workspace 46571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal workspaceScreens.add(screenId); 46671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal addedWorkspaceScreensFinal.add(screenId); 46776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 46871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // If we still can't find an empty space, then God help us all!!! 46971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!findNextAvailableIconSpaceInScreen( 47071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY)) { 47171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal throw new RuntimeException("Can't find space to add the item"); 47271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 473fe9d96a39651de99819208e95c7ec7d432a402e0Winson Chung } 47471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal return Pair.create(screenId, cordinates); 47571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 47671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 47771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal /** 47871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * Adds the provided items to the workspace. 47971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * @param preferredScreen the screen where we should try to add the app first 48071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * @param fallbackStartScreen the screen to start search for empty space if 48171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * preferredScreen is not available. 48271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal */ 48371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal public void addAndBindPendingItem( 48471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final Context context, 48571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final PendingAddItemInfo addInfo, 48671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final ScreenPosProvider preferredScreen, 48771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int fallbackStartScreen) { 48871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final Callbacks callbacks = getCallback(); 48971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Process the newly added applications and add them to the database first 49071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal Runnable r = new Runnable() { 49171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal public void run() { 49271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>(); 493c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal ArrayList<Long> workspaceScreens = loadWorkspaceScreensDb(context); 49471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 49571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Find appropriate space for the item. 49671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal Pair<Long, int[]> coords = findSpaceForItem(context, preferredScreen, 49771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal fallbackStartScreen, workspaceScreens, addedWorkspaceScreensFinal, 49871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal addInfo.spanX, 49971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal addInfo.spanY); 50071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final long screenId = coords.first; 50171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int[] cordinates = coords.second; 50271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 50371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Update the workspace screens 50471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal updateWorkspaceScreenOrder(context, workspaceScreens); 50571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal runOnMainThread(new Runnable() { 50671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal public void run() { 50771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal Callbacks cb = getCallback(); 50871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (callbacks == cb && cb != null) { 50971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal cb.bindAddScreens(addedWorkspaceScreensFinal); 51071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal cb.bindAddPendingItem(addInfo, 51171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherSettings.Favorites.CONTAINER_DESKTOP, 51271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId, cordinates, addInfo.spanX, addInfo.spanY); 51371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 51471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 51571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal }); 51671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 51771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal }; 51871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal runOnWorkerThread(r); 51971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 52071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 52171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal /** 52271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * Adds the provided items to the workspace. 52371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * @param preferredScreen the screen where we should try to add the app first 52471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * @param fallbackStartScreen the screen to start search for empty space if 52571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * preferredScreen is not available. 52671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal */ 52771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal public void addAndBindAddedWorkspaceApps(final Context context, 52871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final ArrayList<ItemInfo> workspaceApps, 52971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final ScreenPosProvider preferredScreen, 53071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final int fallbackStartScreen, 53171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final boolean allowDuplicate) { 53271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final Callbacks callbacks = getCallback(); 53376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (workspaceApps.isEmpty()) { 5349e6a0a20d40675ef98c7fdb8892cf34b90152f7aWinson Chung return; 535997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 53664359a53dc827797917a8d9a0697a91996789801Winson Chung // Process the newly added applications and add them to the database first 53764359a53dc827797917a8d9a0697a91996789801Winson Chung Runnable r = new Runnable() { 53864359a53dc827797917a8d9a0697a91996789801Winson Chung public void run() { 53964359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>(); 54064359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>(); 54164359a53dc827797917a8d9a0697a91996789801Winson Chung 54276828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // Get the list of workspace screens. We need to append to this list and 54376828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // can not use sBgWorkspaceScreens because loadWorkspace() may not have been 54476828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // called. 545c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal ArrayList<Long> workspaceScreens = loadWorkspaceScreensDb(context); 54664359a53dc827797917a8d9a0697a91996789801Winson Chung synchronized(sBgLock) { 54771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal for (ItemInfo item : workspaceApps) { 54871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!allowDuplicate) { 54971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Short-circuit this logic if the icon exists somewhere on the workspace 55071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (shortcutExists(context, item.title.toString(), 55171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal item.getIntent(), item.user)) { 55271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal continue; 553c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 55464359a53dc827797917a8d9a0697a91996789801Winson Chung } 55564359a53dc827797917a8d9a0697a91996789801Winson Chung 55671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Find appropriate space for the item. 55771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal Pair<Long, int[]> coords = findSpaceForItem(context, preferredScreen, 55871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal fallbackStartScreen, workspaceScreens, addedWorkspaceScreensFinal, 55971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 1, 1); 56071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal long screenId = coords.first; 56171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] cordinates = coords.second; 56271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 563997a92348a6d6e061737399321393449c16cd4d8Winson Chung ShortcutInfo shortcutInfo; 56471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (item instanceof ShortcutInfo) { 56571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal shortcutInfo = (ShortcutInfo) item; 56671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } else if (item instanceof AppInfo) { 56771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal shortcutInfo = ((AppInfo) item).makeShortcut(); 568997a92348a6d6e061737399321393449c16cd4d8Winson Chung } else { 569997a92348a6d6e061737399321393449c16cd4d8Winson Chung throw new RuntimeException("Unexpected info type"); 570997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 57194d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung 57264359a53dc827797917a8d9a0697a91996789801Winson Chung // Add the shortcut to the db 57364359a53dc827797917a8d9a0697a91996789801Winson Chung addItemToDatabase(context, shortcutInfo, 57464359a53dc827797917a8d9a0697a91996789801Winson Chung LauncherSettings.Favorites.CONTAINER_DESKTOP, 57571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId, cordinates[0], cordinates[1], false); 57664359a53dc827797917a8d9a0697a91996789801Winson Chung // Save the ShortcutInfo for binding in the workspace 57764359a53dc827797917a8d9a0697a91996789801Winson Chung addedShortcutsFinal.add(shortcutInfo); 57864359a53dc827797917a8d9a0697a91996789801Winson Chung } 57964359a53dc827797917a8d9a0697a91996789801Winson Chung } 58064359a53dc827797917a8d9a0697a91996789801Winson Chung 58176828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // Update the workspace screens 58276828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung updateWorkspaceScreenOrder(context, workspaceScreens); 58376828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 58476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (!addedShortcutsFinal.isEmpty()) { 585997a92348a6d6e061737399321393449c16cd4d8Winson Chung runOnMainThread(new Runnable() { 586997a92348a6d6e061737399321393449c16cd4d8Winson Chung public void run() { 587e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 588997a92348a6d6e061737399321393449c16cd4d8Winson Chung if (callbacks == cb && cb != null) { 589997a92348a6d6e061737399321393449c16cd4d8Winson Chung final ArrayList<ItemInfo> addAnimated = new ArrayList<ItemInfo>(); 590997a92348a6d6e061737399321393449c16cd4d8Winson Chung final ArrayList<ItemInfo> addNotAnimated = new ArrayList<ItemInfo>(); 59194d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung if (!addedShortcutsFinal.isEmpty()) { 59294d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung ItemInfo info = addedShortcutsFinal.get(addedShortcutsFinal.size() - 1); 59394d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung long lastScreenId = info.screenId; 59494d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung for (ItemInfo i : addedShortcutsFinal) { 59594d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung if (i.screenId == lastScreenId) { 59694d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung addAnimated.add(i); 59794d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung } else { 59894d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung addNotAnimated.add(i); 59994d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung } 600997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 601997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 602d64d1763c590b1c954b759156683abf39ff22945Winson Chung callbacks.bindAppsAdded(addedWorkspaceScreensFinal, 60376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen addNotAnimated, addAnimated, null); 604997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 60564359a53dc827797917a8d9a0697a91996789801Winson Chung } 606997a92348a6d6e061737399321393449c16cd4d8Winson Chung }); 607997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 60864359a53dc827797917a8d9a0697a91996789801Winson Chung } 60964359a53dc827797917a8d9a0697a91996789801Winson Chung }; 61064359a53dc827797917a8d9a0697a91996789801Winson Chung runOnWorkerThread(r); 61164359a53dc827797917a8d9a0697a91996789801Winson Chung } 61264359a53dc827797917a8d9a0697a91996789801Winson Chung 61381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung public void unbindItemInfosAndClearQueuedBindRunnables() { 61481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 61581b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung throw new RuntimeException("Expected unbindLauncherItemInfos() to be called from the " + 61681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung "main thread"); 61781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung } 61881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung 61981b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Clear any deferred bind runnables 620a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 621a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.clear(); 622a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 62381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Remove any queued bind runnables 62481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung mHandler.cancelAllRunnablesOfType(MAIN_THREAD_BINDING_RUNNABLE); 62581b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Unbind all the workspace items 62681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung unbindWorkspaceItemsOnMainThread(); 627603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung } 628603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung 629b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Unbinds all the sBgWorkspaceItems and sBgAppWidgets on the main thread */ 63081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung void unbindWorkspaceItemsOnMainThread() { 631603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung // Ensure that we don't use the same workspace items data structure on the main thread 632603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung // by making a copy of workspace items first. 633b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<ItemInfo> tmpWorkspaceItems = new ArrayList<ItemInfo>(); 634b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<ItemInfo> tmpAppWidgets = new ArrayList<ItemInfo>(); 6352abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 636b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung tmpWorkspaceItems.addAll(sBgWorkspaceItems); 637b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung tmpAppWidgets.addAll(sBgAppWidgets); 638b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 639b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Runnable r = new Runnable() { 640b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 641b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 642b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo item : tmpWorkspaceItems) { 643b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.unbind(); 644b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 645b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo item : tmpAppWidgets) { 646b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.unbind(); 647b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 648b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 649b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 650b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnMainThread(r); 6514eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen } 6524eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen 6539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 6549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Adds an item to the DB if it was not created previously, or move it to a new 6559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * <container, screen, cellX, cellY> 6569c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 6579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container, 658dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId, int cellX, int cellY) { 6599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (item.container == ItemInfo.NO_ID) { 6609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From all apps 661dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen addItemToDatabase(context, item, container, screenId, cellX, cellY, false); 6629c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 6639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From somewhere else 664dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen moveItemInDatabase(context, item, container, screenId, cellX, cellY); 6659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 66731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 668b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka static void checkItemInfoLocked( 669b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka final long itemId, final ItemInfo item, StackTraceElement[] stackTrace) { 670b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ItemInfo modelItem = sBgItemsIdMap.get(itemId); 671b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelItem != null && item != modelItem) { 672b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // check all the data is consistent 673b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) { 674b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ShortcutInfo modelShortcut = (ShortcutInfo) modelItem; 675b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ShortcutInfo shortcut = (ShortcutInfo) item; 676b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelShortcut.title.toString().equals(shortcut.title.toString()) && 677b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.intent.filterEquals(shortcut.intent) && 678b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.id == shortcut.id && 679b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.itemType == shortcut.itemType && 680b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.container == shortcut.container && 681dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen modelShortcut.screenId == shortcut.screenId && 682b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.cellX == shortcut.cellX && 683b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.cellY == shortcut.cellY && 684b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.spanX == shortcut.spanX && 685b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.spanY == shortcut.spanY && 686b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ((modelShortcut.dropPos == null && shortcut.dropPos == null) || 687b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka (modelShortcut.dropPos != null && 688b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka shortcut.dropPos != null && 689b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.dropPos[0] == shortcut.dropPos[0] && 690b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.dropPos[1] == shortcut.dropPos[1]))) { 691b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // For all intents and purposes, this is the same object 692b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka return; 693b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 694b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 695b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka 696b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // the modelItem needs to match up perfectly with item if our model is 697b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // to be consistent with the database-- for now, just require 698b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // modelItem == item or the equality check above 699b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka String msg = "item: " + ((item != null) ? item.toString() : "null") + 700b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka "modelItem: " + 701b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ((modelItem != null) ? modelItem.toString() : "null") + 702b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka "Error: ItemInfo passed to checkItemInfo doesn't match original"; 703b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka RuntimeException e = new RuntimeException(msg); 704b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (stackTrace != null) { 705b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka e.setStackTrace(stackTrace); 706b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 707b9ada65af30c61c5b35da9b9efac75ffe6c56fd7Adam Cohen throw e; 708b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 709b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 710b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka 711816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka static void checkItemInfo(final ItemInfo item) { 712816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 713816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka final long itemId = item.id; 714816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka Runnable r = new Runnable() { 715b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka public void run() { 716b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka synchronized (sBgLock) { 717b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka checkItemInfoLocked(itemId, item, stackTrace); 718816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka } 719b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 720b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka }; 721b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 722816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka } 723816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka 724c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka static void updateItemInDatabaseHelper(Context context, final ContentValues values, 725c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ItemInfo item, final String callingFunction) { 726c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final long itemId = item.id; 727c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final Uri uri = LauncherSettings.Favorites.getContentUri(itemId, false); 728c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ContentResolver cr = context.getContentResolver(); 729c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 730487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 731c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 732c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka public void run() { 733c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.update(uri, values, null, null); 734f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemArrays(item, itemId, stackTrace); 735f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 736f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen }; 737f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen runOnWorkerThread(r); 738f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 739c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 740f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void updateItemsInDatabaseHelper(Context context, final ArrayList<ContentValues> valuesList, 741f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ArrayList<ItemInfo> items, final String callingFunction) { 742f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ContentResolver cr = context.getContentResolver(); 743c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 744f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 745f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Runnable r = new Runnable() { 746f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen public void run() { 747f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ContentProviderOperation> ops = 748f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen new ArrayList<ContentProviderOperation>(); 749f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int count = items.size(); 750f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < count; i++) { 751f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo item = items.get(i); 752f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final long itemId = item.id; 753f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final Uri uri = LauncherSettings.Favorites.getContentUri(itemId, false); 754f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ContentValues values = valuesList.get(i); 755f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 756f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build()); 757f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemArrays(item, itemId, stackTrace); 758487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen 759f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 760f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen try { 761f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen cr.applyBatch(LauncherProvider.AUTHORITY, ops); 762f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } catch (Exception e) { 763f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen e.printStackTrace(); 764c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 765c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 766c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 767b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 768c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 769bebf042666cffe52039b875a549a582abd78a431Adam Cohen 770f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void updateItemArrays(ItemInfo item, long itemId, StackTraceElement[] stackTrace) { 771f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Lock on mBgLock *after* the db operation 772f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen synchronized (sBgLock) { 773f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen checkItemInfoLocked(itemId, item, stackTrace); 774f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 775f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP && 776f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 777f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Item is in a folder, make sure this folder exists 778f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (!sBgFolders.containsKey(item.container)) { 779f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // An items container is being set to a that of an item which is not in 780f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // the list of Folders. 781f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen String msg = "item: " + item + " container being set to: " + 782f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container + ", not in the list of folders"; 783f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Log.e(TAG, msg); 784f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 785f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 786f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 787f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Items are added/removed from the corresponding FolderInfo elsewhere, such 788f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // as in Workspace.onDrop. Here, we just add/remove them from the list of items 789f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // that are on the desktop, as appropriate 790f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo modelItem = sBgItemsIdMap.get(itemId); 79133231f587e1a6f716af68e6198df774d2847a8e5Winson Chung if (modelItem != null && 79233231f587e1a6f716af68e6198df774d2847a8e5Winson Chung (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || 79333231f587e1a6f716af68e6198df774d2847a8e5Winson Chung modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT)) { 794f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen switch (modelItem.itemType) { 795f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 796f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 797f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 798f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (!sBgWorkspaceItems.contains(modelItem)) { 799f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen sBgWorkspaceItems.add(modelItem); 800f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 801f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen break; 802f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen default: 803f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen break; 804f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 805f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } else { 806f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen sBgWorkspaceItems.remove(modelItem); 807f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 808f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 809f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 810f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 8119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 8129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Move an item in the DB to a new <container, screen, cellX, cellY> 8139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 814a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka static void moveItemInDatabase(Context context, final ItemInfo item, final long container, 815dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY) { 8169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 8179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 8189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 819c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 8203d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // We store hotseat items in canonical form which is this orientation invariant position 8213d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // in the hotseat 822dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 8233d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 824dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 8253d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } else { 826dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 8273d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } 82831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 8309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CONTAINER, item.container); 8313d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung values.put(LauncherSettings.Favorites.CELLX, item.cellX); 8323d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung values.put(LauncherSettings.Favorites.CELLY, item.cellY); 83308f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal values.put(LauncherSettings.Favorites.RANK, item.rank); 834dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 835ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 836c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka updateItemInDatabaseHelper(context, values, item, "moveItemInDatabase"); 83731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 83831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 83931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 840f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen * Move items in the DB to a new <container, screen, cellX, cellY>. We assume that the 841f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen * cellX, cellY have already been updated on the ItemInfos. 842f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen */ 843f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void moveItemsInDatabase(Context context, final ArrayList<ItemInfo> items, 844f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final long container, final int screen) { 845f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 846f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ContentValues> contentValues = new ArrayList<ContentValues>(); 847f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int count = items.size(); 848f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 849f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < count; i++) { 850f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo item = items.get(i); 851f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container = container; 852f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 853f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // We store hotseat items in canonical form which is this orientation invariant position 854f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // in the hotseat 855f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (context instanceof Launcher && screen < 0 && 856f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 857dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(item.cellX, 858f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.cellY); 859f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } else { 860dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screen; 861f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 862f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 863f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ContentValues values = new ContentValues(); 864f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CONTAINER, item.container); 865f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CELLX, item.cellX); 866f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CELLY, item.cellY); 86708f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal values.put(LauncherSettings.Favorites.RANK, item.rank); 868dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 869f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 870f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen contentValues.add(values); 871f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 872f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemsInDatabaseHelper(context, contentValues, items, "moveItemInDatabase"); 873f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 874f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 875f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen /** 876bebf042666cffe52039b875a549a582abd78a431Adam Cohen * Move and/or resize item in the DB to a new <container, screen, cellX, cellY, spanX, spanY> 877d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen */ 878bebf042666cffe52039b875a549a582abd78a431Adam Cohen static void modifyItemInDatabase(Context context, final ItemInfo item, final long container, 879dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY, final int spanX, final int spanY) { 8800f84a604563037ea65883b99d30e7ff802d986c2Winson Chung item.container = container; 881d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen item.cellX = cellX; 882d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen item.cellY = cellY; 883bebf042666cffe52039b875a549a582abd78a431Adam Cohen item.spanX = spanX; 884bebf042666cffe52039b875a549a582abd78a431Adam Cohen item.spanY = spanY; 885bebf042666cffe52039b875a549a582abd78a431Adam Cohen 886bebf042666cffe52039b875a549a582abd78a431Adam Cohen // We store hotseat items in canonical form which is this orientation invariant position 887bebf042666cffe52039b875a549a582abd78a431Adam Cohen // in the hotseat 888dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 889bebf042666cffe52039b875a549a582abd78a431Adam Cohen container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 890dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 891bebf042666cffe52039b875a549a582abd78a431Adam Cohen } else { 892dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 893bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 894d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 895d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen final ContentValues values = new ContentValues(); 896d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen values.put(LauncherSettings.Favorites.CONTAINER, item.container); 897bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.CELLX, item.cellX); 898bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.CELLY, item.cellY); 89908f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal values.put(LauncherSettings.Favorites.RANK, item.rank); 900bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.SPANX, item.spanX); 901bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.SPANY, item.spanY); 902dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 903d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 904816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka updateItemInDatabaseHelper(context, values, item, "modifyItemInDatabase"); 905bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 906c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 907c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka /** 908c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * Update an item to the database in a specified container. 909c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka */ 910c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka static void updateItemInDatabase(Context context, final ItemInfo item) { 911c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ContentValues values = new ContentValues(); 912ed13187a745866483139e2878037e1f8427ce567Kenny Guy item.onAddToDatabase(context, values); 913c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka updateItemInDatabaseHelper(context, values, item, "updateItemInDatabase"); 914d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 915d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 916d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen /** 9179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Returns true if the shortcuts already exists in the database. 9189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * we identify a shortcut by its title and intent. 919bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project */ 920e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal static boolean shortcutExists(Context context, String title, Intent intent, 921e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal UserHandleCompat user) { 9229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 9232a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal final Intent intentWithPkg, intentWithoutPkg; 9242a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal 9252a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal if (intent.getComponent() != null) { 9262a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal // If component is not null, an intent with null package will produce 9272a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal // the same result and should also be a match. 9282a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal if (intent.getPackage() != null) { 9292a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal intentWithPkg = intent; 9302a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal intentWithoutPkg = new Intent(intent).setPackage(null); 9312a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } else { 9322a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal intentWithPkg = new Intent(intent).setPackage( 9332a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal intent.getComponent().getPackageName()); 9342a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal intentWithoutPkg = intent; 9352a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } 9362a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } else { 9372a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal intentWithPkg = intent; 9382a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal intentWithoutPkg = intent; 9392a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } 940e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String userSerial = Long.toString(UserManagerCompat.getInstance(context) 941e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal .getSerialNumberForUser(user)); 9429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, 943e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal new String[] { "title", "intent", "profileId" }, 944e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal "title=? and (intent=? or intent=?) and profileId=?", 945e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal new String[] { title, intentWithPkg.toUri(0), intentWithoutPkg.toUri(0), userSerial }, 946e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal null); 9479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 948e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return c.moveToFirst(); 9499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 9509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 9519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 952bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project } 953bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 954bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project /** 9559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList. 95631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 9579c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo getFolderById(Context context, HashMap<Long,FolderInfo> folderList, long id) { 9589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 9599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null, 9609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato "_id=? and (itemType=? or itemType=?)", 9619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { String.valueOf(id), 962df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_FOLDER)}, null); 963f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 9649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 9659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (c.moveToFirst()) { 9669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); 9679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE); 9689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); 9699c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); 9709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); 9719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); 972f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 9739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = null; 9749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (c.getInt(itemTypeIndex)) { 975df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 976df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen folderInfo = findOrMakeFolder(folderList, id); 9779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 9789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 97931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.title = c.getString(titleIndex); 9819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.id = id; 9829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.container = c.getInt(containerIndex); 983dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen folderInfo.screenId = c.getInt(screenIndex); 984d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen folderInfo.cellX = c.getInt(cellXIndex); 985d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen folderInfo.cellY = c.getInt(cellYIndex); 986ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 9879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return folderInfo; 9889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 9909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 9912fcbd686d1c2a9a9e520116a541c9caae0c2dc60Romain Guy } 992ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 9939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 9949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 99531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 9979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Add an item to the database in a specified container. Sets the container, screen, cellX and 9989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * cellY fields of the item. Also assigns an ID to the item. 9999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 10003d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung static void addItemToDatabase(Context context, final ItemInfo item, final long container, 1001dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY, final boolean notify) { 10029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 10039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 10049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 10053d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // We store hotseat items in canonical form which is this orientation invariant position 10063d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // in the hotseat 1007dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 10083d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1009dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 10103d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } else { 1011dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 10123d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } 1013ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 10149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 10159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1016ed13187a745866483139e2878037e1f8427ce567Kenny Guy item.onAddToDatabase(context, values); 1017ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 1018414300a79d140f8c2c8760d9adab750f69ffeafdMichael Jurka item.id = LauncherAppState.getLauncherProvider().generateNewItemId(); 1019a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka values.put(LauncherSettings.Favorites._ID, item.id); 1020aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 10218e19cf22a4ab86f982b08e7d10b86ea7be56acccJason Monk final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 1022c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 1023a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka public void run() { 1024a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI : 1025a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values); 1026ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 1027b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 10282abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 10298e19cf22a4ab86f982b08e7d10b86ea7be56acccJason Monk checkItemInfoLocked(item.id, item, stackTrace); 1030b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(item.id, item); 1031b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (item.itemType) { 1032b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 1033b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.put(item.id, (FolderInfo) item); 1034b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Fall through 1035b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1036b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1037b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || 1038b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1039b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(item); 1040b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1041b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!sBgFolders.containsKey(item.container)) { 1042b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Adding an item to a folder that doesn't exist. 1043b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String msg = "adding item: " + item + " to a folder that " + 1044b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung " doesn't exist"; 104528b3e10fdea4d719b46d2e0da9a916bacc238fd1Adam Cohen Log.e(TAG, msg); 1046b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1047487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 1048b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1049b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 1050b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.add((LauncherAppWidgetInfo) item); 1051b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1052b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1053a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 1054a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 1055c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 1056b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 105731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 105831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1060aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * Creates a new unique child id, for a given cell span across all layouts. 1061aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung */ 1062845ba3b17b83a2b11d79c6fb076cf96ab4a737dfMichael Jurka static int getCellLayoutChildId( 1063dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long container, long screen, int localCellX, int localCellY, int spanX, int spanY) { 10643d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung return (((int) container & 0xFF) << 24) 1065dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen | ((int) screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF); 1066aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 1067aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1068349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal private static ArrayList<ItemInfo> getItemsByPackageName( 1069349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal final String pn, final UserHandleCompat user) { 1070e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal ItemInfoFilter filter = new ItemInfoFilter() { 1071e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal @Override 1072e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn) { 1073e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return cn.getPackageName().equals(pn) && info.user.equals(user); 1074e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1075e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal }; 1076349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal return filterItemInfos(sBgItemsIdMap.values(), filter); 1077349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1078349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 1079349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal /** 1080349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal * Removes all the items from the database corresponding to the specified package. 1081349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal */ 1082349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal static void deletePackageFromDatabase(Context context, final String pn, 1083349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal final UserHandleCompat user) { 1084349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal deleteItemsFromDatabase(context, getItemsByPackageName(pn, user)); 1085e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1086e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 1087e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal /** 1088c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * Removes the specified item from the database 1089c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * @param context 1090c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * @param item 10919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1092c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka static void deleteItemFromDatabase(Context context, final ItemInfo item) { 1093e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal ArrayList<ItemInfo> items = new ArrayList<ItemInfo>(); 1094e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal items.add(item); 1095e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal deleteItemsFromDatabase(context, items); 1096e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1097e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 1098e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal /** 1099e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal * Removes the specified items from the database 1100e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal * @param context 1101e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal * @param item 1102e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal */ 11034390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal static void deleteItemsFromDatabase(Context context, final ArrayList<? extends ItemInfo> items) { 11049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1105487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen 110683df188ce0822f4058406e5f2878d1cf34bf413eMichael Jurka Runnable r = new Runnable() { 1107a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka public void run() { 1108e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal for (ItemInfo item : items) { 1109e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal final Uri uri = LauncherSettings.Favorites.getContentUri(item.id, false); 1110e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal cr.delete(uri, null, null); 1111b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1112e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // Lock on mBgLock *after* the db operation 1113e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal synchronized (sBgLock) { 1114e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal switch (item.itemType) { 1115e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 1116e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgFolders.remove(item.id); 1117e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal for (ItemInfo info: sBgItemsIdMap.values()) { 1118e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal if (info.container == item.id) { 1119e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // We are deleting a folder which still contains items that 1120e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // think they are contained by that folder. 1121e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal String msg = "deleting a folder (" + item + ") which still " + 1122e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal "contains items (" + info + ")"; 1123e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal Log.e(TAG, msg); 1124e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1125b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1126e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgWorkspaceItems.remove(item); 1127e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1128e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1129e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1130e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgWorkspaceItems.remove(item); 1131e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1132e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 1133e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgAppWidgets.remove((LauncherAppWidgetInfo) item); 1134e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1135e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1136e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgItemsIdMap.remove(item.id); 1137e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgDbIconCache.remove(item); 1138b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1139a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 1140a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 114183df188ce0822f4058406e5f2878d1cf34bf413eMichael Jurka }; 1142b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 114331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 114431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1146dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen * Update the order of the workspace screens in the database. The array list contains 1147dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen * a list of screen ids in the order that they should appear. 1148dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen */ 1149c916834ad0da535f08325bcd902a60070f2f7e53Winson Chung void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) { 1150a90303bb6fdad59e4a55855edba68c9902192599Winson Chung // Log to disk 1151a90303bb6fdad59e4a55855edba68c9902192599Winson Chung Launcher.addDumpLog(TAG, "11683562 - updateWorkspaceScreenOrder()", true); 1152a90303bb6fdad59e4a55855edba68c9902192599Winson Chung Launcher.addDumpLog(TAG, "11683562 - screens: " + TextUtils.join(", ", screens), true); 1153a90303bb6fdad59e4a55855edba68c9902192599Winson Chung 115464359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<Long> screensCopy = new ArrayList<Long>(screens); 1155dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ContentResolver cr = context.getContentResolver(); 1156dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI; 1157dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1158dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Remove any negative screen ids -- these aren't persisted 115964359a53dc827797917a8d9a0697a91996789801Winson Chung Iterator<Long> iter = screensCopy.iterator(); 1160dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen while (iter.hasNext()) { 1161dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long id = iter.next(); 1162dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (id < 0) { 1163dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen iter.remove(); 1164dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1165dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1166dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1167dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Runnable r = new Runnable() { 1168dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen @Override 1169dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void run() { 1170085c853a5702c45865e9b017d21fa15cf2b151b9Yura ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 1171dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Clear the table 1172085c853a5702c45865e9b017d21fa15cf2b151b9Yura ops.add(ContentProviderOperation.newDelete(uri).build()); 117376828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung int count = screensCopy.size(); 1174dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (int i = 0; i < count; i++) { 1175dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ContentValues v = new ContentValues(); 117676828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung long screenId = screensCopy.get(i); 1177dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen v.put(LauncherSettings.WorkspaceScreens._ID, screenId); 1178dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i); 1179085c853a5702c45865e9b017d21fa15cf2b151b9Yura ops.add(ContentProviderOperation.newInsert(uri).withValues(v).build()); 1180085c853a5702c45865e9b017d21fa15cf2b151b9Yura } 1181085c853a5702c45865e9b017d21fa15cf2b151b9Yura 1182085c853a5702c45865e9b017d21fa15cf2b151b9Yura try { 1183085c853a5702c45865e9b017d21fa15cf2b151b9Yura cr.applyBatch(LauncherProvider.AUTHORITY, ops); 1184085c853a5702c45865e9b017d21fa15cf2b151b9Yura } catch (Exception ex) { 1185085c853a5702c45865e9b017d21fa15cf2b151b9Yura throw new RuntimeException(ex); 1186dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 11879e6a0a20d40675ef98c7fdb8892cf34b90152f7aWinson Chung 1188ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung synchronized (sBgLock) { 1189ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.clear(); 1190ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.addAll(screensCopy); 11914caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen } 1192dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1193dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen }; 1194dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen runOnWorkerThread(r); 1195dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1196dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1197dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen /** 11989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Remove the contents of the specified folder from the database 11999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1200a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka static void deleteFolderContentsFromDatabase(Context context, final FolderInfo info) { 12019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1202f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1203c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 1204c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka public void run() { 1205c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null); 1206b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 12072abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1208b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(info.id); 1209b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.remove(info.id); 1210b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgDbIconCache.remove(info); 1211b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.remove(info); 1212b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1213c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 1214c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.delete(LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, 1215c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka LauncherSettings.Favorites.CONTAINER + "=" + info.id, null); 1216b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 12172abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1218b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo childInfo : info.contents) { 1219b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(childInfo.id); 1220b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgDbIconCache.remove(childInfo); 1221b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1222afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1223c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 1224c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 1225b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 12269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1227f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 12289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 12299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Set this as the current Launcher activity object for the loader. 12309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 12319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void initialize(Callbacks callbacks) { 12329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 12339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mCallbacks = new WeakReference<Callbacks>(callbacks); 1234f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1235f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1236f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1237ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1238c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageChanged(String packageName, UserHandleCompat user) { 1239ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_UPDATE; 1240ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, 1241ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1242ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1243ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1244ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1245c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageRemoved(String packageName, UserHandleCompat user) { 1246ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_REMOVE; 1247ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, 1248ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1249ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1250ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1251ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1252c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageAdded(String packageName, UserHandleCompat user) { 1253ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_ADD; 1254ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, 1255ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1256ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1257ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1258ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1259c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackagesAvailable(String[] packageNames, UserHandleCompat user, 1260ed13187a745866483139e2878037e1f8427ce567Kenny Guy boolean replacing) { 1261ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!replacing) { 1262ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packageNames, 1263ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1264ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (mAppsCanBeOnRemoveableStorage) { 1265ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Only rebind if we support removable storage. It catches the 1266ed13187a745866483139e2878037e1f8427ce567Kenny Guy // case where 1267ed13187a745866483139e2878037e1f8427ce567Kenny Guy // apps on the external sd card need to be reloaded 1268ed13187a745866483139e2878037e1f8427ce567Kenny Guy startLoaderFromBackground(); 1269ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1270ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 1271ed13187a745866483139e2878037e1f8427ce567Kenny Guy // If we are replacing then just update the packages in the list 1272ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_UPDATE, 1273ed13187a745866483139e2878037e1f8427ce567Kenny Guy packageNames, user)); 1274ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1275ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1276ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1277ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1278c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackagesUnavailable(String[] packageNames, UserHandleCompat user, 1279ed13187a745866483139e2878037e1f8427ce567Kenny Guy boolean replacing) { 1280ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!replacing) { 1281ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask( 1282ed13187a745866483139e2878037e1f8427ce567Kenny Guy PackageUpdatedTask.OP_UNAVAILABLE, packageNames, 1283ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1284ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1285ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1286ed13187a745866483139e2878037e1f8427ce567Kenny Guy 12871d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato /** 12889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and 12899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * ACTION_PACKAGE_CHANGED. 12909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1291cb1a4778686a46c46d8dc88b6c83674f6fac6592Narayan Kamath @Override 1292f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato public void onReceive(Context context, Intent intent) { 1293b358f813c93ac0d6c4f31058947efd16b188cd1eChris Wren if (DEBUG_RECEIVER) Log.d(TAG, "onReceive intent=" + intent); 1294aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 12953611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String action = intent.getAction(); 1296ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (Intent.ACTION_LOCALE_CHANGED.equals(action)) { 129793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // If we have changed locale we need to clear out the labels in all apps/workspace. 129893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee forceReload(); 129993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { 130093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // Check if configuration change was an mcc/mnc change which would affect app resources 130193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // and we would need to clear out the labels in all apps/workspace. Same handling as 130293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // above for ACTION_LOCALE_CHANGED 130393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee Configuration currentConfig = context.getResources().getConfiguration(); 130499a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee if (mPreviousConfigMcc != currentConfig.mcc) { 130593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee Log.d(TAG, "Reload apps on config change. curr_mcc:" 130699a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee + currentConfig.mcc + " prevmcc:" + mPreviousConfigMcc); 130793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee forceReload(); 130893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 130993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // Update previousConfig 131099a73f31b7ebed102f393c1bc1909007d7fa8a56Reena Lee mPreviousConfigMcc = currentConfig.mcc; 1311cbf7c4d50ce2609518640c3f590f6df435edabaeWinson Chung } else if (SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED.equals(action) || 1312cbf7c4d50ce2609518640c3f590f6df435edabaeWinson Chung SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED.equals(action)) { 1313e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks callbacks = getCallback(); 1314e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (callbacks != null) { 1315e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal callbacks.bindSearchablesChanged(); 1316cfdf7ee64db8820d91a1cd82bf7b961fb2083dceWinson Chung } 1317e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1318e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1319e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato 13206cc806d678c8a44478308119c087ac9adde73b66Amith Yamasani void forceReload() { 1321f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung resetLoadedState(true, true); 1322f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 1323f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // Do this here because if the launcher activity is running it will be restarted. 1324f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // If it's not running startLoaderFromBackground will merely tell it that it needs 1325f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // to reload. 1326f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung startLoaderFromBackground(); 1327f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung } 1328f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 1329f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung public void resetLoadedState(boolean resetAllAppsLoaded, boolean resetWorkspaceLoaded) { 133093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (mLock) { 133193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // Stop any existing loaders first, so they don't set mAllAppsLoaded or 133293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // mWorkspaceLoaded to true later 133393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee stopLoaderLocked(); 1334f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung if (resetAllAppsLoaded) mAllAppsLoaded = false; 1335f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung if (resetWorkspaceLoaded) mWorkspaceLoaded = false; 133693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 133793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 133893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 1339e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato /** 1340e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * When the launcher is in the background, it's possible for it to miss paired 1341e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * configuration changes. So whenever we trigger the loader from the background 1342e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * tell the launcher that it needs to re-run the loader when it comes back instead 1343e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * of doing it now. 1344e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato */ 1345e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato public void startLoaderFromBackground() { 1346e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato boolean runLoader = false; 1347e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks callbacks = getCallback(); 1348e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (callbacks != null) { 1349e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Only actually run the loader if they're not paused. 1350e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (!callbacks.setLoadOnResume()) { 1351e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal runLoader = true; 1352e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1353e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1354e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato if (runLoader) { 13557aff399974c756930070d82d7b2df88f125dacd6Derek Prothro startLoader(false, PagedView.INVALID_RESTORE_PAGE); 1356f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 13573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1358f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 135993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // If there is already a loader task running, tell it to stop. 136093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // returns true if isLaunching() was true on the old task 136193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee private boolean stopLoaderLocked() { 136293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee boolean isLaunching = false; 136393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee LoaderTask oldTask = mLoaderTask; 136493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (oldTask != null) { 136593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (oldTask.isLaunching()) { 136693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee isLaunching = true; 136793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 136893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee oldTask.stopLocked(); 136993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 137093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee return isLaunching; 137193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 137293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 13731a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen public boolean isCurrentCallbacks(Callbacks callbacks) { 13741a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen return (mCallbacks != null && mCallbacks.get() == callbacks); 13751a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen } 13761a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen 1377b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void startLoader(boolean isLaunching, int synchronousBindPage) { 1378d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler startLoader(isLaunching, synchronousBindPage, LOADER_FLAG_NONE); 1379d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } 1380d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler 1381d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler public void startLoader(boolean isLaunching, int synchronousBindPage, int loadFlags) { 13823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 13833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 13843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "startLoader isLaunching=" + isLaunching); 13853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1386843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 1387b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Clear any deferred bind-runnables from the synchronized load process 1388b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // We must do this before any loading/binding is scheduled below. 1389a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 1390a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.clear(); 1391a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 1392b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 13933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Don't bother to start the thread if we know it's not going to do anything 13943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mCallbacks != null && mCallbacks.get() != null) { 13953611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // If there is already one running, tell it to stop. 139693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // also, don't downgrade isLaunching if we're already running 139793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee isLaunching = isLaunching || stopLoaderLocked(); 1398d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler mLoaderTask = new LoaderTask(mApp.getContext(), isLaunching, loadFlags); 13997aff399974c756930070d82d7b2df88f125dacd6Derek Prothro if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE 14007aff399974c756930070d82d7b2df88f125dacd6Derek Prothro && mAllAppsLoaded && mWorkspaceLoaded) { 1401b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mLoaderTask.runBindSynchronousPage(synchronousBindPage); 1402b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1403b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorkerThread.setPriority(Thread.NORM_PRIORITY); 1404b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorker.post(mLoaderTask); 1405b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1406b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1407b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1408b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1409b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1410b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung void bindRemainingSynchronousPages() { 1411b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Post the remaining side pages to be loaded 1412b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!mDeferredBindRunnables.isEmpty()) { 1413a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk Runnable[] deferredBindRunnables = null; 1414a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 1415a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk deferredBindRunnables = mDeferredBindRunnables.toArray( 1416a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk new Runnable[mDeferredBindRunnables.size()]); 1417a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.clear(); 1418a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 1419a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk for (final Runnable r : deferredBindRunnables) { 142081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung mHandler.post(r, MAIN_THREAD_BINDING_RUNNABLE); 1421b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 1422b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 14233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1424b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 14253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void stopLoader() { 14263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 14273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask != null) { 14283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask.stopLocked(); 14299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1430f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 14313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1432b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 1433c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal /** 1434c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal * Loads the workspace screen ids in an ordered list. 1435c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal */ 1436c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal private static ArrayList<Long> loadWorkspaceScreensDb(Context context) { 143776828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung final ContentResolver contentResolver = context.getContentResolver(); 143876828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung final Uri screensUri = LauncherSettings.WorkspaceScreens.CONTENT_URI; 143976828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 1440c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal // Get screens ordered by rank. 1441c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal final Cursor sc = contentResolver.query(screensUri, null, null, null, 1442c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal LauncherSettings.WorkspaceScreens.SCREEN_RANK); 1443c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal ArrayList<Long> screenIds = new ArrayList<Long>(); 144476828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung try { 1445c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal final int idIndex = sc.getColumnIndexOrThrow(LauncherSettings.WorkspaceScreens._ID); 144676828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung while (sc.moveToNext()) { 144776828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung try { 1448c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal screenIds.add(sc.getLong(idIndex)); 144976828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } catch (Exception e) { 1450c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal Launcher.addDumpLog(TAG, "Desktop items loading interrupted" 1451c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal + " - invalid screens: " + e, true); 145276828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 145376828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 145476828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } finally { 145576828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung sc.close(); 145676828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 1457c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal return screenIds; 145876828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 145976828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 1460c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka public boolean isAllAppsLoaded() { 1461c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka return mAllAppsLoaded; 1462c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka } 1463c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka 146436a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung boolean isLoadingWorkspace() { 146536a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung synchronized (mLock) { 146636a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung if (mLoaderTask != null) { 146736a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung return mLoaderTask.isLoadingWorkspace(); 146836a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung } 146936a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung } 147036a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung return false; 147136a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung } 147236a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 14733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato /** 14743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * Runnable for the thread that loads the contents of the launcher: 14753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - workspace icons 14763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - widgets 14773611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - all apps icons 14783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato */ 14793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private class LoaderTask implements Runnable { 14803611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private Context mContext; 14813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private boolean mIsLaunching; 148236a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung private boolean mIsLoadingAndBindingWorkspace; 14833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private boolean mStopped; 14843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private boolean mLoadAndBindStepFinished; 1485d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler private int mFlags; 1486b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1487c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung private HashMap<Object, CharSequence> mLabelCache; 14883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 1489d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler LoaderTask(Context context, boolean isLaunching, int flags) { 14903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mContext = context; 14913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mIsLaunching = isLaunching; 1492c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache = new HashMap<Object, CharSequence>(); 1493d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler mFlags = flags; 14943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1495f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 14963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato boolean isLaunching() { 14973611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return mIsLaunching; 14983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1499f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 150036a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung boolean isLoadingWorkspace() { 150136a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung return mIsLoadingAndBindingWorkspace; 150236a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung } 150336a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 1504c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung /** Returns whether this is an upgrade path */ 1505c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung private boolean loadAndBindWorkspace() { 150636a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung mIsLoadingAndBindingWorkspace = true; 150736a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 15083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Load the workspace 15093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 15103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "loadAndBindWorkspace mWorkspaceLoaded=" + mWorkspaceLoaded); 15113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1512288a36b563801a26d00084cb823435a3ba4cb76cMichael Jurka 1513c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung boolean isUpgradePath = false; 1514a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka if (!mWorkspaceLoaded) { 1515c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung isUpgradePath = loadWorkspace(); 151693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (LoaderTask.this) { 151793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (mStopped) { 1518c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung return isUpgradePath; 151993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 152093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mWorkspaceLoaded = true; 15219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 15223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1523cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 15243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Bind the workspace 1525c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung bindWorkspace(-1, isUpgradePath); 1526c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung return isUpgradePath; 15273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1528f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 15293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void waitForIdle() { 15303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Wait until the either we're stopped or the other threads are done. 15313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This way we don't start loading all apps until the workspace has settled 15323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // down. 15333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 15343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long workspaceWaitTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1535843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 15363611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.postIdle(new Runnable() { 15373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 15383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 15393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoadAndBindStepFinished = true; 15403611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 15413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "done with previous binding step"); 15429c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 15433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato LoaderTask.this.notify(); 15449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 15459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 15463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 15473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 154871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal while (!mStopped && !mLoadAndBindStepFinished) { 15493611578579b4bfb25616085dafdb1a45207394f9Joe Onorato try { 1550c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka // Just in case mFlushingWorkerThread changes but we aren't woken up, 1551c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka // wait no longer than 1sec at a time 1552c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka this.wait(1000); 15533611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } catch (InterruptedException ex) { 15543611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Ignore 15559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 15563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 15573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 15583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "waited " 1559aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung + (SystemClock.uptimeMillis()-workspaceWaitTime) 15603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + "ms for previous step to finish binding"); 15619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1562843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 15633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1564f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1565b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung void runBindSynchronousPage(int synchronousBindPage) { 15667aff399974c756930070d82d7b2df88f125dacd6Derek Prothro if (synchronousBindPage == PagedView.INVALID_RESTORE_PAGE) { 1567b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we have a valid page index to load synchronously 1568b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Should not call runBindSynchronousPage() without " + 1569b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung "valid page index"); 1570b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1571b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!mAllAppsLoaded || !mWorkspaceLoaded) { 1572b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we don't try and bind a specified page when the pages have not been 1573b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // loaded already (we should load everything asynchronously in that case) 1574b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Expecting AllApps and Workspace to be loaded"); 1575b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1576b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung synchronized (mLock) { 1577b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (mIsLoaderTaskRunning) { 1578b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we are never running the background loading at this point since 1579b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // we also touch the background collections 1580b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Error! Background loading is already running"); 1581b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1582b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1583b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1584b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: Throw an exception if we are already loading (since we touch the worker thread 1585b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // data structures, we can't allow any other thread to touch that data, but because 1586b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // this call is synchronous, we can get away with not locking). 1587b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1588cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // The LauncherModel is static in the LauncherAppState and mHandler may have queued 1589a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen // operations from the previous activity. We need to ensure that all queued operations 1590a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen // are executed before any synchronous binding work is done. 1591a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen mHandler.flush(); 1592a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen 1593b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Divide the set of loaded items into those that we are binding synchronously, and 1594b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // everything else that is to be bound normally (asynchronously). 1595c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung bindWorkspace(synchronousBindPage, false); 1596b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: For now, continue posting the binding of AllApps as there are other issues that 1597b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // arise from that. 1598b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung onlyBindAllApps(); 1599b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1600b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 16013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 1602c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung boolean isUpgrade = false; 1603c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung 1604b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung synchronized (mLock) { 1605b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mIsLoaderTaskRunning = true; 1606b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 16073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Optimize for end-user experience: if the Launcher is up and // running with the 16083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // All Apps interface in the foreground, load All Apps first. Otherwise, load the 16093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // workspace first (default). 16103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato keep_running: { 1611843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler // Elevate priority when Home launches for the first time to avoid 1612843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler // starving at boot time. Staring at a blank home is not cool. 1613dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler synchronized (mLock) { 1614aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (DEBUG_LOADERS) Log.d(TAG, "Setting thread priority to " + 1615aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung (mIsLaunching ? "DEFAULT" : "BACKGROUND")); 1616843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler android.os.Process.setThreadPriority(mIsLaunching 1617843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler ? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND); 1618dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 161964359a53dc827797917a8d9a0697a91996789801Winson Chung if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace"); 1620c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung isUpgrade = loadAndBindWorkspace(); 1621843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 16223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mStopped) { 16233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break keep_running; 16243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 16253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 16263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Whew! Hard work done. Slow us down, and wait until the UI thread has 16273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // settled down. 16289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 1629843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler if (mIsLaunching) { 1630aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (DEBUG_LOADERS) Log.d(TAG, "Setting thread priority to BACKGROUND"); 1631843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 16329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 16339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 16343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato waitForIdle(); 1635f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1636843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler // second step 163764359a53dc827797917a8d9a0697a91996789801Winson Chung if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps"); 163864359a53dc827797917a8d9a0697a91996789801Winson Chung loadAndBindAllApps(); 16397ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung 16407ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung // Restore the default thread priority after we are done loading items 16417ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung synchronized (mLock) { 16427ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); 16437ed3774638133ac603e92ca3174ecdd151269ccaWinson Chung } 16443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1645843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 1646aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung // Update the saved icons if necessary 1647aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (DEBUG_LOADERS) Log.d(TAG, "Comparing loaded icons to database icons"); 16482abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1649b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (Object key : sBgDbIconCache.keySet()) { 1650b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung updateSavedIcon(mContext, (ShortcutInfo) key, sBgDbIconCache.get(key)); 1651b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1652b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgDbIconCache.clear(); 1653aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } 1654aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung 165516f3ea870aac47292cd6cbe1a4b4343173097aa9Nilesh Agrawal if (LauncherAppState.isDisableAllApps()) { 1656c58497ee619416c4949b16eb43486c11618b69e5Winson Chung // Ensure that all the applications that are in the system are 1657c58497ee619416c4949b16eb43486c11618b69e5Winson Chung // represented on the home screen. 1658c58497ee619416c4949b16eb43486c11618b69e5Winson Chung if (!UPGRADE_USE_MORE_APPS_FOLDER || !isUpgrade) { 1659c58497ee619416c4949b16eb43486c11618b69e5Winson Chung verifyApplications(); 1660c58497ee619416c4949b16eb43486c11618b69e5Winson Chung } 1661c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 1662c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung 16633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Clear out this reference, otherwise we end up holding it until all of the 16643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // callback runnables are done. 16653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mContext = null; 1666f3d5ea926d4dd1a739b9d3816543728af723cc26Joe Onorato 16673611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 16683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // If we are still the last one to be scheduled, remove ourselves. 16693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask == this) { 16703611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask = null; 1671843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 1672b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mIsLoaderTaskRunning = false; 16733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 16743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1675f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 16763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void stopLocked() { 16773611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 16783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mStopped = true; 16793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato this.notify(); 1680f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 16813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1682f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 16833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato /** 16843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * Gets the callbacks object. If we've been stopped, or if the launcher object 16853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * has somehow been garbage collected, return null instead. Pass in the Callbacks 16863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * object that was around when the deferred message was scheduled, and if there's 16873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * a new Callbacks object around then also return null. This will save us from 16883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * calling onto it with data that will be ignored. 16893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato */ 16903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Callbacks tryGetCallbacks(Callbacks oldCallbacks) { 16913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 16923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mStopped) { 16933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 16943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1695ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato 16963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mCallbacks == null) { 16973611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 16983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1699f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 17003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = mCallbacks.get(); 17013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != oldCallbacks) { 17023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 17033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 17043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks == null) { 17053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "no mCallbacks"); 17063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 17079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 17083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 17093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return callbacks; 1710f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 17113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1712f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1713c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung private void verifyApplications() { 1714c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung final Context context = mApp.getContext(); 1715c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung 1716c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung // Cross reference all the applications in our apps list with items in the workspace 1717c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung ArrayList<ItemInfo> tmpInfos; 1718695ff6b6fada4e1037592d7c4961321e12890b7dMichael Jurka ArrayList<ItemInfo> added = new ArrayList<ItemInfo>(); 1719c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung synchronized (sBgLock) { 1720eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka for (AppInfo app : mBgAllAppsList.data) { 1721ed13187a745866483139e2878037e1f8427ce567Kenny Guy tmpInfos = getItemInfoForComponentName(app.componentName, app.user); 1722c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung if (tmpInfos.isEmpty()) { 1723c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung // We are missing an application icon, so add this to the workspace 1724c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung added.add(app); 1725c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung // This is a rare event, so lets log it 1726c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung Log.e(TAG, "Missing Application on load: " + app); 1727c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 1728c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 1729c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 1730c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung if (!added.isEmpty()) { 173176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen addAndBindAddedWorkspaceApps(context, added); 1732c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 1733c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 1734c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung 17353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // check & update map of what's occupied; used to discard overlapping/invalid items 1736fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item) { 1737892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 1738892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 1739295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler final int countX = (int) grid.numColumns; 1740295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler final int countY = (int) grid.numRows; 1741892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 1742dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long containerIndex = item.screenId; 1743f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1744a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung // Return early if we detect that an item is under the hotseat button 1745a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung if (mCallbacks == null || 1746a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung mCallbacks.get().isAllAppsButtonRank((int) item.screenId)) { 1747295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler Log.e(TAG, "Error loading shortcut into hotseat " + item 1748295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler + " into position (" + item.screenId + ":" + item.cellX + "," 1749295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler + item.cellY + ") occupied by all apps"); 1750a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung return false; 1751a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung } 1752a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung 1753295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler final ItemInfo[][] hotseatItems = 1754295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler occupied.get((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT); 1755295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler 1756ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen if (item.screenId >= grid.numHotseatIcons) { 1757ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen Log.e(TAG, "Error loading shortcut " + item 1758ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + " into hotseat position " + item.screenId 1759ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + ", position out of bounds: (0 to " + (grid.numHotseatIcons - 1) 1760ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + ")"); 1761ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen return false; 1762ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen } 1763ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 1764295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler if (hotseatItems != null) { 1765295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler if (hotseatItems[(int) item.screenId][0] != null) { 1766dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Log.e(TAG, "Error loading shortcut into hotseat " + item 1767dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + " into position (" + item.screenId + ":" + item.cellX + "," 1768dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + item.cellY + ") occupied by " 1769dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT) 1770dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen [(int) item.screenId][0]); 1771dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen return false; 1772295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler } else { 1773295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler hotseatItems[(int) item.screenId][0] = item; 1774295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler return true; 1775dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 17766ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung } else { 1777ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen final ItemInfo[][] items = new ItemInfo[(int) grid.numHotseatIcons][1]; 1778dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen items[(int) item.screenId][0] = item; 1779dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen occupied.put((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT, items); 17806ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung return true; 17816ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung } 1782f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung } else if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { 1783f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung // Skip further checking if it is not the hotseat or workspace container 17843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return true; 17853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1786f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung 1787dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (!occupied.containsKey(item.screenId)) { 1788892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung ItemInfo[][] items = new ItemInfo[countX + 1][countY + 1]; 1789dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen occupied.put(item.screenId, items); 1790dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1791dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1792295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler final ItemInfo[][] screens = occupied.get(item.screenId); 1793ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 1794ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen item.cellX < 0 || item.cellY < 0 || 1795ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen item.cellX + item.spanX > countX || item.cellY + item.spanY > countY) { 1796ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen Log.e(TAG, "Error loading shortcut " + item 1797ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + " into cell (" + containerIndex + "-" + item.screenId + ":" 1798ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + item.cellX + "," + item.cellY 1799ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + ") out of screen bounds ( " + countX + "x" + countY + ")"); 1800ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen return false; 1801ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen } 1802ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 18036ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung // Check if any workspace icons overlap with each other 18043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int x = item.cellX; x < (item.cellX+item.spanX); x++) { 18053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int y = item.cellY; y < (item.cellY+item.spanY); y++) { 1806dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (screens[x][y] != null) { 18073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.e(TAG, "Error loading shortcut " + item 1808dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + " into cell (" + containerIndex + "-" + item.screenId + ":" 18093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + x + "," + y 1810aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung + ") occupied by " 1811dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + screens[x][y]); 18123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return false; 18138802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 18148802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 18153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 18163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int x = item.cellX; x < (item.cellX+item.spanX); x++) { 18173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int y = item.cellY; y < (item.cellY+item.spanY); y++) { 1818dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen screens[x][y] = item; 18198802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 18208802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 1821f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung 18223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return true; 18233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 18248802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler 1825ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung /** Clears all the sBg data structures */ 1826ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung private void clearSBgDataStructures() { 1827ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung synchronized (sBgLock) { 1828ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceItems.clear(); 1829ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgAppWidgets.clear(); 1830ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgFolders.clear(); 1831ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgItemsIdMap.clear(); 1832ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgDbIconCache.clear(); 1833ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.clear(); 1834ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 1835ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 1836ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung 1837d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler /** Returns whether this is an upgrade path */ 1838c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung private boolean loadWorkspace() { 18399f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung // Log to disk 18409f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung Launcher.addDumpLog(TAG, "11683562 - loadWorkspace()", true); 18419f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung 18423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1843f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 18443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Context context = mContext; 18453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final ContentResolver contentResolver = context.getContentResolver(); 18463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final PackageManager manager = context.getPackageManager(); 18473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final boolean isSafeMode = manager.isSafeMode(); 1848f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 1849f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal final boolean isSdCardReady = context.registerReceiver(null, 185005e318d8f7d5ea615539d34b181ee44686f1f494Sunny Goyal new IntentFilter(StartupReceiver.SYSTEM_READY)) != null; 1851f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1852892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 1853892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 1854892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung int countX = (int) grid.numColumns; 1855892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung int countY = (int) grid.numRows; 1856892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 1857d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler if ((mFlags & LOADER_FLAG_CLEAR_WORKSPACE) != 0) { 1858d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler Launcher.addDumpLog(TAG, "loadWorkspace: resetting launcher database", true); 1859d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler LauncherAppState.getLauncherProvider().deleteDatabase(); 1860d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } 1861d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler 1862d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler if ((mFlags & LOADER_FLAG_MIGRATE_SHORTCUTS) != 0) { 1863d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler // append the user's Launcher2 shortcuts 1864d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler Launcher.addDumpLog(TAG, "loadWorkspace: migrating from launcher2", true); 1865d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler LauncherAppState.getLauncherProvider().migrateLauncher2Shortcuts(); 1866d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } else { 1867d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler // Make sure the default workspace is loaded 1868d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler Launcher.addDumpLog(TAG, "loadWorkspace: loading default favorites", false); 18690fe505bf82a265e51c556d7204976651cde7f55cSunny Goyal LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary(); 1870d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } 1871e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 187271483f417bb19f524cda41081f5ccac6084dc103Adam Cohen // This code path is for our old migration code and should no longer be exercised 187371483f417bb19f524cda41081f5ccac6084dc103Adam Cohen boolean loadedOldDb = false; 1874f0b8dacf1516e0d901c71109c906dc15ef855fc5Dan Sandler 18759f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung // Log to disk 18769f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung Launcher.addDumpLog(TAG, "11683562 - loadedOldDb: " + loadedOldDb, true); 1877b85f8a44b51258f22938773ca30dd85845345010Michael Jurka 18782abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1879ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung clearSBgDataStructures(); 18809448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal final HashSet<String> installingPkgs = PackageInstallerCompat 18819448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal .getInstance(mContext).updateAndGetActiveSessionCache(); 1882b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1883b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<Long> itemsToRemove = new ArrayList<Long>(); 1884f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren final ArrayList<Long> restoredRows = new ArrayList<Long>(); 1885c5fb59fb9a36180ce962f565d85aa92f9991da1aSunny Goyal final Uri contentUri = LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION; 1886e523e70f75ff90ca5d613fb8398d37208e6cd32dChris Wren if (DEBUG_LOADERS) Log.d(TAG, "loading model from " + contentUri); 1887e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen final Cursor c = contentResolver.query(contentUri, null, null, null, null); 1888b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1889b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // +1 for the hotseat (it can be larger than the workspace) 1890b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Load workspace in reverse order to ensure that latest items are loaded first (and 1891b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // before any earlier duplicates) 1892dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final HashMap<Long, ItemInfo[][]> occupied = new HashMap<Long, ItemInfo[][]>(); 1893b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1894b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1895b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); 1896b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int intentIndex = c.getColumnIndexOrThrow 1897b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.INTENT); 1898b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int titleIndex = c.getColumnIndexOrThrow 1899b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.TITLE); 1900b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int iconTypeIndex = c.getColumnIndexOrThrow( 1901b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ICON_TYPE); 1902b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int iconIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON); 1903b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int iconPackageIndex = c.getColumnIndexOrThrow( 1904b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ICON_PACKAGE); 1905b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int iconResourceIndex = c.getColumnIndexOrThrow( 1906b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ICON_RESOURCE); 1907b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int containerIndex = c.getColumnIndexOrThrow( 1908b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.CONTAINER); 1909b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int itemTypeIndex = c.getColumnIndexOrThrow( 1910b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ITEM_TYPE); 1911b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int appWidgetIdIndex = c.getColumnIndexOrThrow( 1912b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.APPWIDGET_ID); 1913c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren final int appWidgetProviderIndex = c.getColumnIndexOrThrow( 1914c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren LauncherSettings.Favorites.APPWIDGET_PROVIDER); 1915b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int screenIndex = c.getColumnIndexOrThrow( 1916b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.SCREEN); 1917b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int cellXIndex = c.getColumnIndexOrThrow 1918b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.CELLX); 1919b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int cellYIndex = c.getColumnIndexOrThrow 1920b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.CELLY); 1921b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int spanXIndex = c.getColumnIndexOrThrow 1922b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.SPANX); 1923b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int spanYIndex = c.getColumnIndexOrThrow( 1924b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.SPANY); 192508f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal final int rankIndex = c.getColumnIndexOrThrow( 192608f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal LauncherSettings.Favorites.RANK); 1927f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren final int restoredIndex = c.getColumnIndexOrThrow( 1928f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren LauncherSettings.Favorites.RESTORED); 1929ed13187a745866483139e2878037e1f8427ce567Kenny Guy final int profileIdIndex = c.getColumnIndexOrThrow( 1930ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherSettings.Favorites.PROFILE_ID); 1931b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung //final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI); 1932b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung //final int displayModeIndex = c.getColumnIndexOrThrow( 1933b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // LauncherSettings.Favorites.DISPLAY_MODE); 1934b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1935b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ShortcutInfo info; 1936b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String intentDescription; 1937b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherAppWidgetInfo appWidgetInfo; 1938b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int container; 1939b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung long id; 1940b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent intent; 1941ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user; 1942b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1943b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung while (!mStopped && c.moveToNext()) { 1944b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1945b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int itemType = c.getInt(itemTypeIndex); 1946f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren boolean restored = 0 != c.getInt(restoredIndex); 1947f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean allowMissingTarget = false; 1948b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1949b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (itemType) { 1950b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1951b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1952ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung id = c.getLong(idIndex); 1953b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intentDescription = c.getString(intentIndex); 19541317e2dd4a2fb097d1e54759536d515fdeca2c3eKenny Guy long serialNumber = c.getInt(profileIdIndex); 1955ed13187a745866483139e2878037e1f8427ce567Kenny Guy user = mUserManager.getUserForSerialNumber(serialNumber); 1956349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal int promiseType = c.getInt(restoredIndex); 19571a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal int disabledState = 0; 1958ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user == null) { 1959ed13187a745866483139e2878037e1f8427ce567Kenny Guy // User has been deleted remove the item. 1960ed13187a745866483139e2878037e1f8427ce567Kenny Guy itemsToRemove.add(id); 1961ed13187a745866483139e2878037e1f8427ce567Kenny Guy continue; 1962ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1963b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1964b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intent = Intent.parseUri(intentDescription, 0); 1965ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung ComponentName cn = intent.getComponent(); 1966f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (cn != null && cn.getPackageName() != null) { 1967f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean validPkg = launcherApps.isPackageEnabledForProfile( 1968f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal cn.getPackageName(), user); 1969f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean validComponent = validPkg && 1970f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal launcherApps.isActivityEnabledForProfile(cn, user); 1971f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 1972f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (validComponent) { 1973f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (restored) { 1974f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // no special handling necessary for this item 1975f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal restoredRows.add(id); 1976f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal restored = false; 1977f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 1978f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } else if (validPkg) { 1979349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent = null; 1980349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { 1981349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // We allow auto install apps to have their intent 1982349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // updated after an install. 1983349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent = manager.getLaunchIntentForPackage( 1984349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal cn.getPackageName()); 1985349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (intent != null) { 1986349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ContentValues values = new ContentValues(); 1987349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal values.put(LauncherSettings.Favorites.INTENT, 1988349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent.toUri(0)); 1989349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal String where = BaseColumns._ID + "= ?"; 1990349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal String[] args = {Long.toString(id)}; 1991349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal contentResolver.update(contentUri, values, where, args); 1992349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1993349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1994349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 1995349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (intent == null) { 1996349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // The app is installed but the component is no 1997349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // longer available. 1998349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal Launcher.addDumpLog(TAG, 1999349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal "Invalid component removed: " + cn, true); 2000349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal itemsToRemove.add(id); 2001349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal continue; 2002349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } else { 2003349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // no special handling necessary for this item 2004349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal restoredRows.add(id); 2005349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal restored = false; 2006349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 2007f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } else if (restored) { 2008f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // Package is not yet available but might be 2009f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // installed later. 2010f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren Launcher.addDumpLog(TAG, 2011f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren "package not yet restored: " + cn, true); 20129448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal 20139448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal if ((promiseType & ShortcutInfo.FLAG_RESTORE_STARTED) != 0) { 20149448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // Restore has started once. 20159448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } else if (installingPkgs.contains(cn.getPackageName())) { 20169448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // App restore has started. Update the flag 20179448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal promiseType |= ShortcutInfo.FLAG_RESTORE_STARTED; 20189448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal ContentValues values = new ContentValues(); 20199448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal values.put(LauncherSettings.Favorites.RESTORED, 20209448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal promiseType); 20219448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal String where = BaseColumns._ID + "= ?"; 20229448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal String[] args = {Long.toString(id)}; 20239448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal contentResolver.update(contentUri, values, where, args); 20249448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal 20259448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } else if (REMOVE_UNRESTORED_ICONS) { 20269448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal Launcher.addDumpLog(TAG, 20279448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal "Unrestored package removed: " + cn, true); 20289448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal itemsToRemove.add(id); 20299448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal continue; 20309448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } 20311a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else if (launcherApps.isAppEnabled( 20321a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal manager, cn.getPackageName(), 20331a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal PackageManager.GET_UNINSTALLED_PACKAGES)) { 20341a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Package is present but not available. 20351a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal allowMissingTarget = true; 20361a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal disabledState = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; 20371a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else if (!isSdCardReady) { 2038f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // SdCard is not ready yet. Package might get available, 2039f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // once it is ready. 2040f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal Launcher.addDumpLog(TAG, "Invalid package: " + cn 2041f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal + " (check again later)", true); 2042f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal HashSet<String> pkgs = sPendingPackages.get(user); 2043f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (pkgs == null) { 2044513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala pkgs = new HashSet<String>(); 2045f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal sPendingPackages.put(user, pkgs); 2046f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 2047f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal pkgs.add(cn.getPackageName()); 2048f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal allowMissingTarget = true; 2049f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // Add the icon on the workspace anyway. 20501a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 20511a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else { 20521a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Do not wait for external media load anymore. 20531a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Log the invalid package, and remove it 20541a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal Launcher.addDumpLog(TAG, 20551a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal "Invalid package removed: " + cn, true); 20561a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal itemsToRemove.add(id); 20571a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal continue; 2058ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 2059938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal } else if (cn == null) { 2060938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal // For shortcuts with no component, keep them as they are 2061938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal restoredRows.add(id); 2062938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal restored = false; 2063ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 2064b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (URISyntaxException e) { 2065f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren Launcher.addDumpLog(TAG, 2066f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren "Invalid uri: " + intentDescription, true); 2067b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung continue; 2068b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2069968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka 2070f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren if (restored) { 2071ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user.equals(UserHandleCompat.myUserHandle())) { 2072ed13187a745866483139e2878037e1f8427ce567Kenny Guy Launcher.addDumpLog(TAG, 2073ed13187a745866483139e2878037e1f8427ce567Kenny Guy "constructing info for partially restored package", 2074ed13187a745866483139e2878037e1f8427ce567Kenny Guy true); 2075349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info = getRestoredItemInfo(c, titleIndex, intent, promiseType); 2076ed13187a745866483139e2878037e1f8427ce567Kenny Guy intent = getRestoredItemIntent(c, context, intent); 2077ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 2078ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Don't restore items for other profiles. 2079ed13187a745866483139e2878037e1f8427ce567Kenny Guy itemsToRemove.add(id); 2080ed13187a745866483139e2878037e1f8427ce567Kenny Guy continue; 2081ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2082f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } else if (itemType == 2083f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 2084f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal info = getShortcutInfo(manager, intent, user, context, c, 2085f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal iconIndex, titleIndex, mLabelCache, allowMissingTarget); 2086b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2087b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info = getShortcutInfo(c, context, iconTypeIndex, 2088b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung iconPackageIndex, iconResourceIndex, iconIndex, 2089b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung titleIndex); 2090b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2091b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // App shortcuts that used to be automatically added to Launcher 2092b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // didn't always have the correct intent flags set, so do that 2093b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // here 2094b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (intent.getAction() != null && 20959ad005639e1698c94674cdfadf3ae342fb56c9b5Michael Jurka intent.getCategories() != null && 20969ad005639e1698c94674cdfadf3ae342fb56c9b5Michael Jurka intent.getAction().equals(Intent.ACTION_MAIN) && 2097968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { 2098b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intent.addFlags( 2099b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent.FLAG_ACTIVITY_NEW_TASK | 2100b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 2101b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2102968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka } 21033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 2104b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info != null) { 2105ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung info.id = id; 2106b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.intent = intent; 2107b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung container = c.getInt(containerIndex); 2108b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.container = container; 2109dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen info.screenId = c.getInt(screenIndex); 2110b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.cellX = c.getInt(cellXIndex); 2111b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.cellY = c.getInt(cellYIndex); 211208f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal info.rank = c.getInt(rankIndex); 21135f8afe6280eae34620067696173e71943e1a30a3Winson Chung info.spanX = 1; 21145f8afe6280eae34620067696173e71943e1a30a3Winson Chung info.spanY = 1; 2115ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.intent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); 21161a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal info.isDisabled = disabledState; 21171a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (isSafeMode && !Utilities.isSystemApp(context, intent)) { 21181a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE; 21191a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 2120ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 2121b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // check & update map of what's occupied 2122fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal if (!checkItemPlacement(occupied, info)) { 2123fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 2124b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2125b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2126b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2127b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (container) { 2128b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: 2129b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: 2130b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(info); 2131b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2132b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung default: 2133b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Item is in a user folder 2134b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folderInfo = 2135b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung findOrMakeFolder(sBgFolders, container); 2136b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.add(info); 2137b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2138b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2139b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(info.id, info); 2140b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2141b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // now that we've loaded everthing re-save it with the 2142b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // icon in case it disappears somehow. 2143b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung queueIconToBeChecked(sBgDbIconCache, info, c, iconIndex); 21441323b4856a2a822af77293cadeda9910a5d1ba0eWinson Chung } else { 21451323b4856a2a822af77293cadeda9910a5d1ba0eWinson Chung throw new RuntimeException("Unexpected null ShortcutInfo"); 2146b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2147b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2148b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2149b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 2150b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung id = c.getLong(idIndex); 2151b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folderInfo = findOrMakeFolder(sBgFolders, id); 2152b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2153b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.title = c.getString(titleIndex); 2154b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.id = id; 21553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato container = c.getInt(containerIndex); 2156b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.container = container; 2157dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen folderInfo.screenId = c.getInt(screenIndex); 2158b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.cellX = c.getInt(cellXIndex); 2159b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.cellY = c.getInt(cellYIndex); 21605f8afe6280eae34620067696173e71943e1a30a3Winson Chung folderInfo.spanX = 1; 21615f8afe6280eae34620067696173e71943e1a30a3Winson Chung folderInfo.spanY = 1; 21625f8afe6280eae34620067696173e71943e1a30a3Winson Chung 21633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // check & update map of what's occupied 2164fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal if (!checkItemPlacement(occupied, folderInfo)) { 2165fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 21663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 21679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 21685f8afe6280eae34620067696173e71943e1a30a3Winson Chung 21693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato switch (container) { 2170b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: 2171b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: 2172b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(folderInfo); 2173b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 21749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 217517a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato 2176f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren if (restored) { 2177f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren // no special handling required for restored folders 2178f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren restoredRows.add(id); 2179f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 2180f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 2181b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(folderInfo.id, folderInfo); 2182b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.put(folderInfo.id, folderInfo); 2183b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2184b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2185b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 21865940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: 2187b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Read all Launcher-specific widget details 21885940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen boolean customWidget = itemType == 21895940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET; 21905940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 2191b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int appWidgetId = c.getInt(appWidgetIdIndex); 2192c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren String savedProvider = c.getString(appWidgetProviderIndex); 21933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato id = c.getLong(idIndex); 2194ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final ComponentName component = 2195ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal ComponentName.unflattenFromString(savedProvider); 2196f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2197651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal final int restoreStatus = c.getInt(restoredIndex); 2198ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean isIdValid = (restoreStatus & 2199ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) == 0; 2200ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2201ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean wasProviderReady = (restoreStatus & 2202ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0; 2203ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 22045940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen final LauncherAppWidgetProviderInfo provider = 22055940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherModel.getProviderInfo(context, 22065940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen ComponentName.unflattenFromString(savedProvider)); 2207ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2208ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean isProviderReady = isValidProvider(provider); 22095940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!isSafeMode && !customWidget && 22105940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen wasProviderReady && !isProviderReady) { 2211651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal String log = "Deleting widget that isn't installed anymore: " 2212ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal + "id=" + id + " appWidgetId=" + appWidgetId; 22135940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 2214b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.e(TAG, log); 22154caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen Launcher.addDumpLog(TAG, log, false); 2216b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsToRemove.add(id); 2217b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2218ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (isProviderReady) { 2219651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, 2220651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal provider.provider); 22215940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 22225940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!customWidget) { 22235940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen int[] minSpan = 22245940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen Launcher.getMinSpanForWidget(context, provider); 22255940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.minSpanX = minSpan[0]; 22265940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.minSpanY = minSpan[1]; 22275940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 2228ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2229ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal int status = restoreStatus; 2230ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (!wasProviderReady) { 2231ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // If provider was not previously ready, update the 2232ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // status and UI flag. 2233ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2234ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // Id would be valid only if the widget restore broadcast was received. 2235ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (isIdValid) { 2236ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal status = LauncherAppWidgetInfo.RESTORE_COMPLETED; 2237ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } else { 2238ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal status &= ~LauncherAppWidgetInfo 2239ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal .FLAG_PROVIDER_NOT_READY; 2240ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } 2241ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } 2242ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal appWidgetInfo.restoreStatus = status; 2243651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } else { 2244651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal Log.v(TAG, "Widget restore pending id=" + id 2245651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal + " appWidgetId=" + appWidgetId 2246651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal + " status =" + restoreStatus); 2247651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, 2248ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal component); 2249651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo.restoreStatus = restoreStatus; 22509448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal 22519448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal if ((restoreStatus & LauncherAppWidgetInfo.FLAG_RESTORE_STARTED) != 0) { 22529448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // Restore has started once. 22539448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } else if (installingPkgs.contains(component.getPackageName())) { 22549448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // App restore has started. Update the flag 22559448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal appWidgetInfo.restoreStatus |= 22569448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; 22579b4b0812fec41c40d81d507cfdb528ba87663f5fSunny Goyal } else if (REMOVE_UNRESTORED_ICONS && !isSafeMode) { 22589448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal Launcher.addDumpLog(TAG, 2259c5fb59fb9a36180ce962f565d85aa92f9991da1aSunny Goyal "Unrestored widget removed: " + component, true); 22609448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal itemsToRemove.add(id); 22619448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal continue; 22629448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } 2263651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } 2264ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2265b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.id = id; 2266dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen appWidgetInfo.screenId = c.getInt(screenIndex); 2267b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.cellX = c.getInt(cellXIndex); 2268b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.cellY = c.getInt(cellYIndex); 2269b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.spanX = c.getInt(spanXIndex); 2270b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.spanY = c.getInt(spanYIndex); 2271b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 22725940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!customWidget) { 22735940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen int[] minSpan = Launcher.getMinSpanForWidget(context, provider); 22745940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.minSpanX = minSpan[0]; 22755940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.minSpanY = minSpan[1]; 22765940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 22775940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 2278b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung container = c.getInt(containerIndex); 2279b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && 2280b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 2281b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.e(TAG, "Widget found where container != " + 2282b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!"); 2283b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung continue; 2284b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2285b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2286e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen appWidgetInfo.container = c.getInt(containerIndex); 2287b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // check & update map of what's occupied 2288fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal if (!checkItemPlacement(occupied, appWidgetInfo)) { 2289fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 2290b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2291b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2292651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal 22935940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!customWidget) { 22945940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen String providerName = 22955940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.providerName.flattenToString(); 22965940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!providerName.equals(savedProvider) || 22975940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen (appWidgetInfo.restoreStatus != restoreStatus)) { 22985940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen ContentValues values = new ContentValues(); 22995940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen values.put( 23005940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherSettings.Favorites.APPWIDGET_PROVIDER, 23015940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen providerName); 23025940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen values.put(LauncherSettings.Favorites.RESTORED, 23035940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.restoreStatus); 23045940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen String where = BaseColumns._ID + "= ?"; 23055940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen String[] args = {Long.toString(id)}; 23065940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen contentResolver.update(contentUri, values, where, args); 23075940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 2308c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren } 2309b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(appWidgetInfo.id, appWidgetInfo); 2310b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.add(appWidgetInfo); 2311b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 23129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 23133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2314b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (Exception e) { 2315295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler Launcher.addDumpLog(TAG, "Desktop items loading interrupted", e, true); 2316b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2317b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2318b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } finally { 231947b5031c703dbee491af9f49e6e08865452d57efDaniel Sandler if (c != null) { 232047b5031c703dbee491af9f49e6e08865452d57efDaniel Sandler c.close(); 232147b5031c703dbee491af9f49e6e08865452d57efDaniel Sandler } 2322b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2323ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 2324ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung // Break early if we've stopped loading 2325ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung if (mStopped) { 2326ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung clearSBgDataStructures(); 2327ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung return false; 2328ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 2329ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung 2330b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemsToRemove.size() > 0) { 2331b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ContentProviderClient client = contentResolver.acquireContentProviderClient( 2332c5fb59fb9a36180ce962f565d85aa92f9991da1aSunny Goyal contentUri); 2333b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Remove dead items 2334b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (long id : itemsToRemove) { 2335b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (DEBUG_LOADERS) { 2336b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "Removed id = " + id); 2337b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2338b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Don't notify content observers 2339b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 2340b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung client.delete(LauncherSettings.Favorites.getContentUri(id, false), 2341b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung null, null); 2342b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (RemoteException e) { 2343b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.w(TAG, "Could not remove id = " + id); 2344b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2345b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2346b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 23478802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler 2348f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren if (restoredRows.size() > 0) { 2349f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren ContentProviderClient updater = contentResolver.acquireContentProviderClient( 2350c5fb59fb9a36180ce962f565d85aa92f9991da1aSunny Goyal contentUri); 2351f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren // Update restored items that no longer require special handling 2352f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren try { 2353f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren StringBuilder selectionBuilder = new StringBuilder(); 2354f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren selectionBuilder.append(LauncherSettings.Favorites._ID); 2355f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren selectionBuilder.append(" IN ("); 2356f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren selectionBuilder.append(TextUtils.join(", ", restoredRows)); 2357f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren selectionBuilder.append(")"); 2358f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren ContentValues values = new ContentValues(); 2359f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren values.put(LauncherSettings.Favorites.RESTORED, 0); 2360349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal updater.update(LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, 2361f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren values, selectionBuilder.toString(), null); 2362f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } catch (RemoteException e) { 2363f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren Log.w(TAG, "Could not update restored rows"); 2364f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 2365f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 2366f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 2367f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!isSdCardReady && !sPendingPackages.isEmpty()) { 2368f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal context.registerReceiver(new AppsAvailabilityCheck(), 236905e318d8f7d5ea615539d34b181ee44686f1f494Sunny Goyal new IntentFilter(StartupReceiver.SYSTEM_READY), 2370f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal null, sWorker); 2371f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2372f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 2373c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung if (loadedOldDb) { 2374dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long maxScreenId = 0; 2375dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // If we're importing we use the old screen order. 2376dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (ItemInfo item: sBgItemsIdMap.values()) { 2377dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId = item.screenId; 2378dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 2379dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen !sBgWorkspaceScreens.contains(screenId)) { 2380dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sBgWorkspaceScreens.add(screenId); 2381dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (screenId > maxScreenId) { 2382dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen maxScreenId = screenId; 2383dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2384dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2385dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2386dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Collections.sort(sBgWorkspaceScreens); 23879f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung // Log to disk 23889f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung Launcher.addDumpLog(TAG, "11683562 - maxScreenId: " + maxScreenId, true); 23899f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung Launcher.addDumpLog(TAG, "11683562 - sBgWorkspaceScreens: " + 23909f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung TextUtils.join(", ", sBgWorkspaceScreens), true); 23919e6a0a20d40675ef98c7fdb8892cf34b90152f7aWinson Chung 2392414300a79d140f8c2c8760d9adab750f69ffeafdMichael Jurka LauncherAppState.getLauncherProvider().updateMaxScreenId(maxScreenId); 2393dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); 2394c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung 2395c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung // Update the max item id after we load an old db 2396c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung long maxItemId = 0; 2397c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung // If we're importing we use the old screen order. 2398c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung for (ItemInfo item: sBgItemsIdMap.values()) { 2399c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung maxItemId = Math.max(maxItemId, item.id); 2400c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 2401414300a79d140f8c2c8760d9adab750f69ffeafdMichael Jurka LauncherAppState.getLauncherProvider().updateMaxItemId(maxItemId); 2402dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } else { 2403c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal sBgWorkspaceScreens.addAll(loadWorkspaceScreensDb(mContext)); 24049f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung // Log to disk 24059f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung Launcher.addDumpLog(TAG, "11683562 - sBgWorkspaceScreens: " + 24069f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung TextUtils.join(", ", sBgWorkspaceScreens), true); 2407dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2408dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Remove any empty screens 2409933bae6958b5333a61577edd6b57b1a7c00743a0Winson Chung ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgWorkspaceScreens); 2410dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (ItemInfo item: sBgItemsIdMap.values()) { 2411dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId = item.screenId; 2412dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 2413dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen unusedScreens.contains(screenId)) { 2414dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen unusedScreens.remove(screenId); 2415dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2416dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2417dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2418dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // If there are any empty screens remove them, and update. 2419dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (unusedScreens.size() != 0) { 24209f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung // Log to disk 24219f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung Launcher.addDumpLog(TAG, "11683562 - unusedScreens (to be removed): " + 24229f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung TextUtils.join(", ", unusedScreens), true); 24239f9f00bca673ed491e623235314a5c4c22ff28c1Winson Chung 2424dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen sBgWorkspaceScreens.removeAll(unusedScreens); 2425dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); 2426dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2427dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2428dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2429b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (DEBUG_LOADERS) { 2430b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms"); 2431b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "workspace layout: "); 2432dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen int nScreens = occupied.size(); 2433892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung for (int y = 0; y < countY; y++) { 2434b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String line = ""; 2435dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2436566da1026c33a68157bf9caf93d2071ad2870f46Daniel Sandler Iterator<Long> iter = occupied.keySet().iterator(); 2437c916834ad0da535f08325bcd902a60070f2f7e53Winson Chung while (iter.hasNext()) { 2438dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId = iter.next(); 2439c916834ad0da535f08325bcd902a60070f2f7e53Winson Chung if (screenId > 0) { 2440b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung line += " | "; 2441b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2442892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung for (int x = 0; x < countX; x++) { 2443aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren ItemInfo[][] screen = occupied.get(screenId); 2444aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren if (x < screen.length && y < screen[x].length) { 2445aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren line += (screen[x][y] != null) ? "#" : "."; 2446aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } else { 2447aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren line += "!"; 2448aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } 24499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 24509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2451b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "[ " + line + " ]"); 24529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 24539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 24543611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2455c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung return loadedOldDb; 2456e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 2457e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 2458b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of items who are directly or indirectly (via another container) on the 2459b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * specified screen. */ 24609b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung private void filterCurrentWorkspaceItems(long currentScreenId, 2461b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> allWorkspaceItems, 2462b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> currentScreenItems, 2463b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> otherScreenItems) { 24642abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung // Purge any null ItemInfos 24652abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung Iterator<ItemInfo> iter = allWorkspaceItems.iterator(); 24662abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung while (iter.hasNext()) { 24672abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung ItemInfo i = iter.next(); 24682abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (i == null) { 24692abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung iter.remove(); 24702abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung } 24712abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung } 24722abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung 2473b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Order the set of items by their containers first, this allows use to walk through the 2474b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // list sequentially, build up a list of containers that are in the specified screen, 2475b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // as well as all items in those containers. 2476b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Set<Long> itemsOnScreen = new HashSet<Long>(); 2477b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Collections.sort(allWorkspaceItems, new Comparator<ItemInfo>() { 2478b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 2479b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public int compare(ItemInfo lhs, ItemInfo rhs) { 2480b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung return (int) (lhs.container - rhs.container); 2481b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2482b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }); 2483b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo info : allWorkspaceItems) { 2484b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { 24859b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung if (info.screenId == currentScreenId) { 2486b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2487b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2488b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2489b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenItems.add(info); 24903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2491b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 2492b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2493b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2494b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2495b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemsOnScreen.contains(info.container)) { 2496b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2497b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2498b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2499b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenItems.add(info); 25005c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 25015c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 25023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2503b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 25045c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 2505b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of widgets which are on the specified screen. */ 25069b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung private void filterCurrentAppWidgets(long currentScreenId, 2507b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> appWidgets, 2508b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> currentScreenWidgets, 2509b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) { 2510b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2511b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (LauncherAppWidgetInfo widget : appWidgets) { 25122abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (widget == null) continue; 2513b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 25149b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung widget.screenId == currentScreenId) { 2515b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenWidgets.add(widget); 2516b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2517b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenWidgets.add(widget); 2518a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 25199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 25203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 252131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2522b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of folders which are on the specified screen. */ 25239b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung private void filterCurrentFolders(long currentScreenId, 2524b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, ItemInfo> itemsIdMap, 2525b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> folders, 2526b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> currentScreenFolders, 2527b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> otherScreenFolders) { 25283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 2529b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (long id : folders.keySet()) { 2530b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ItemInfo info = itemsIdMap.get(id); 2531b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folder = folders.get(id); 25322abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (info == null || folder == null) continue; 2533b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 25349b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung info.screenId == currentScreenId) { 2535b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenFolders.put(id, folder); 2536b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2537b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenFolders.put(id, folder); 2538b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 25393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2540b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 254131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2542b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to 2543b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * right) */ 2544b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) { 2545892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung final LauncherAppState app = LauncherAppState.getInstance(); 2546892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung final DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 2547b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: review this 2548b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Collections.sort(workspaceItems, new Comparator<ItemInfo>() { 2549db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung @Override 2550db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung public int compare(ItemInfo lhs, ItemInfo rhs) { 2551892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung int cellCountX = (int) grid.numColumns; 2552892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung int cellCountY = (int) grid.numRows; 2553db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int screenOffset = cellCountX * cellCountY; 2554db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int containerOffset = screenOffset * (Launcher.SCREEN_COUNT + 1); // +1 hotseat 2555dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long lr = (lhs.container * containerOffset + lhs.screenId * screenOffset + 2556db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung lhs.cellY * cellCountX + lhs.cellX); 2557dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long rr = (rhs.container * containerOffset + rhs.screenId * screenOffset + 2558db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung rhs.cellY * cellCountX + rhs.cellX); 2559db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung return (int) (lr - rr); 2560db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung } 2561db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung }); 2562b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2563db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung 2564dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen private void bindWorkspaceScreens(final Callbacks oldCallbacks, 2565dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ArrayList<Long> orderedScreens) { 2566dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Runnable r = new Runnable() { 2567dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen @Override 2568dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void run() { 2569dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2570dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (callbacks != null) { 2571dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen callbacks.bindScreens(orderedScreens); 2572dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2573dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2574dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen }; 2575dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 2576dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2577dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2578b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void bindWorkspaceItems(final Callbacks oldCallbacks, 2579b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<ItemInfo> workspaceItems, 2580b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<LauncherAppWidgetInfo> appWidgets, 2581b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final HashMap<Long, FolderInfo> folders, 2582b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<Runnable> deferredBindRunnables) { 2583b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2584b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final boolean postOnMainThread = (deferredBindRunnables != null); 2585603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung 2586b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the workspace items 2587db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int N = workspaceItems.size(); 2588b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int i = 0; i < N; i += ITEMS_CHUNK) { 25893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int start = i; 25903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i); 2591b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 2592b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 25939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 2594c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 25959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 259664359a53dc827797917a8d9a0697a91996789801Winson Chung callbacks.bindItems(workspaceItems, start, start+chunkSize, 259764359a53dc827797917a8d9a0697a91996789801Winson Chung false); 25989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 25999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2600b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2601b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 2602a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (deferredBindRunnables) { 2603a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk deferredBindRunnables.add(r); 2604a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 2605b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 260681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 26073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2608b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2609b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2610b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the folders 2611b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!folders.isEmpty()) { 2612b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 2613b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 2614b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2615b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 2616b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.bindFolders(folders); 26179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2618b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2619b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2620b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 2621a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (deferredBindRunnables) { 2622a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk deferredBindRunnables.add(r); 2623a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 2624b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 262581b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 26269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 26273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2628b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2629b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the widgets, one at a time 2630b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung N = appWidgets.size(); 2631b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int i = 0; i < N; i++) { 2632b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final LauncherAppWidgetInfo widget = appWidgets.get(i); 2633b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 2634b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 2635b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2636b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 2637b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.bindAppWidget(widget); 26383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2639b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2640b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2641b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 2642b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung deferredBindRunnables.add(r); 2643b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 264481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 26453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 26463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2647b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2648b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2649b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** 2650b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * Binds all loaded data to actual views on the main thread. 2651b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung */ 2652c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung private void bindWorkspace(int synchronizeBindPage, final boolean isUpgradePath) { 2653b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final long t = SystemClock.uptimeMillis(); 2654b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Runnable r; 2655b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2656b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Don't use these two variables in any of the callback runnables. 2657b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Otherwise we hold a reference to them. 2658b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Callbacks oldCallbacks = mCallbacks.get(); 2659b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (oldCallbacks == null) { 2660b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // This launcher has exited and nobody bothered to tell us. Just bail. 2661b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.w(TAG, "LoaderTask running with no launcher"); 2662b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung return; 2663b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2664b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 26659b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // Save a copy of all the bg-thread collections 2666b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> workspaceItems = new ArrayList<ItemInfo>(); 2667b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> appWidgets = 2668b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 2669b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> folders = new HashMap<Long, FolderInfo>(); 2670b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, ItemInfo> itemsIdMap = new HashMap<Long, ItemInfo>(); 2671dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ArrayList<Long> orderedScreenIds = new ArrayList<Long>(); 26722abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 2673b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung workspaceItems.addAll(sBgWorkspaceItems); 2674b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgets.addAll(sBgAppWidgets); 2675b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folders.putAll(sBgFolders); 2676b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsIdMap.putAll(sBgItemsIdMap); 2677dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen orderedScreenIds.addAll(sBgWorkspaceScreens); 2678b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2679b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 26807aff399974c756930070d82d7b2df88f125dacd6Derek Prothro final boolean isLoadingSynchronously = 26817aff399974c756930070d82d7b2df88f125dacd6Derek Prothro synchronizeBindPage != PagedView.INVALID_RESTORE_PAGE; 2682d8dbb46468e0a8860468661a6edfb7969bfdf0a7Adam Cohen int currScreen = isLoadingSynchronously ? synchronizeBindPage : 26839b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung oldCallbacks.getCurrentWorkspaceScreen(); 2684d8dbb46468e0a8860468661a6edfb7969bfdf0a7Adam Cohen if (currScreen >= orderedScreenIds.size()) { 2685d8dbb46468e0a8860468661a6edfb7969bfdf0a7Adam Cohen // There may be no workspace screens (just hotseat items and an empty page). 26867aff399974c756930070d82d7b2df88f125dacd6Derek Prothro currScreen = PagedView.INVALID_RESTORE_PAGE; 26879b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung } 2688d8dbb46468e0a8860468661a6edfb7969bfdf0a7Adam Cohen final int currentScreen = currScreen; 26897aff399974c756930070d82d7b2df88f125dacd6Derek Prothro final long currentScreenId = currentScreen < 0 26907aff399974c756930070d82d7b2df88f125dacd6Derek Prothro ? INVALID_SCREEN_ID : orderedScreenIds.get(currentScreen); 26919b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung 26929b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // Load all the items that are on the current page first (and in the process, unbind 26939b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // all the existing workspace items before we call startBinding() below. 26949b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung unbindWorkspaceItemsOnMainThread(); 26959b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung 26969b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // Separate the items that are on the current screen, and all the other remaining items 2697b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<ItemInfo>(); 2698b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<ItemInfo>(); 2699b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> currentAppWidgets = 2700b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 2701b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> otherAppWidgets = 2702b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 2703b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> currentFolders = new HashMap<Long, FolderInfo>(); 2704b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung HashMap<Long, FolderInfo> otherFolders = new HashMap<Long, FolderInfo>(); 2705b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 27069b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung filterCurrentWorkspaceItems(currentScreenId, workspaceItems, currentWorkspaceItems, 2707b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherWorkspaceItems); 27089b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung filterCurrentAppWidgets(currentScreenId, appWidgets, currentAppWidgets, 2709b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherAppWidgets); 27109b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung filterCurrentFolders(currentScreenId, itemsIdMap, folders, currentFolders, 2711b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherFolders); 2712b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sortWorkspaceItemsSpatially(currentWorkspaceItems); 2713b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sortWorkspaceItemsSpatially(otherWorkspaceItems); 2714b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2715b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Tell the workspace that we're about to start binding items 2716b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r = new Runnable() { 27173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 27183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 27193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != null) { 2720b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.startBinding(); 27219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 27229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2723b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 272481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 2725b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2726dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen bindWorkspaceScreens(oldCallbacks, orderedScreenIds); 2727dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2728b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Load items on the current page 2729b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, 2730b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentFolders, null); 27311462de39f01cec0ba785386532719cb0207dd827Adam Cohen if (isLoadingSynchronously) { 27321462de39f01cec0ba785386532719cb0207dd827Adam Cohen r = new Runnable() { 27331462de39f01cec0ba785386532719cb0207dd827Adam Cohen public void run() { 27341462de39f01cec0ba785386532719cb0207dd827Adam Cohen Callbacks callbacks = tryGetCallbacks(oldCallbacks); 27357aff399974c756930070d82d7b2df88f125dacd6Derek Prothro if (callbacks != null && currentScreen != PagedView.INVALID_RESTORE_PAGE) { 27361462de39f01cec0ba785386532719cb0207dd827Adam Cohen callbacks.onPageBoundSynchronously(currentScreen); 27371462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 27381462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 27391462de39f01cec0ba785386532719cb0207dd827Adam Cohen }; 274081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 27411462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 2742b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 27434a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung // Load all the remaining pages (if we are loading synchronously, we want to defer this 27444a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung // work until after the first render) 2745a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 2746a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.clear(); 2747a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 2748b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, otherFolders, 27494a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung (isLoadingSynchronously ? mDeferredBindRunnables : null)); 2750b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2751b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Tell the workspace that we're done binding items 2752b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r = new Runnable() { 27533611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2754b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2755b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 2756c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung callbacks.finishBindingItems(isUpgradePath); 2757b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2758b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 275998e030be2abc03e90e9fd9f8bf67e2e01db39cc0Winson Chung // If we're profiling, ensure this is the last thing in the queue. 27603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 27613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound workspace in " 27623611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 27639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 276436a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 276536a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung mIsLoadingAndBindingWorkspace = false; 27669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2767b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 27684a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung if (isLoadingSynchronously) { 2769a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 2770a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.add(r); 2771a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 27724a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung } else { 277381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung runOnMainThread(r, MAIN_THREAD_BINDING_RUNNABLE); 27744a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung } 27753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 27773611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void loadAndBindAllApps() { 27783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 27793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "loadAndBindAllApps mAllAppsLoaded=" + mAllAppsLoaded); 27803611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (!mAllAppsLoaded) { 278264359a53dc827797917a8d9a0697a91996789801Winson Chung loadAllApps(); 278393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (LoaderTask.this) { 278493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (mStopped) { 278593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee return; 278693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 278793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mAllAppsLoaded = true; 27883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 27903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato onlyBindAllApps(); 27913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 27943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void onlyBindAllApps() { 27953611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 27963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (oldCallbacks == null) { 27973611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 27983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "LoaderTask running with no launcher (onlyBindAllApps)"); 27993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 28003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 28013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 28023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // shallow copy 2803c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung @SuppressWarnings("unchecked") 2804eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> list 2805eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka = (ArrayList<AppInfo>) mBgAllAppsList.data.clone(); 2806c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung Runnable r = new Runnable() { 28073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 28083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = SystemClock.uptimeMillis(); 28093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = tryGetCallbacks(oldCallbacks); 28103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != null) { 28113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAllApplications(list); 28129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 28133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 28143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound all " + list.size() + " apps from cache in " 2815a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 28169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 28173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2818c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung }; 2819c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung boolean isRunningOnMainThread = !(sWorkerThread.getThreadId() == Process.myTid()); 282064359a53dc827797917a8d9a0697a91996789801Winson Chung if (isRunningOnMainThread) { 2821c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung r.run(); 2822c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung } else { 2823c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung mHandler.post(r); 2824c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung } 28253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 28263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 282764359a53dc827797917a8d9a0697a91996789801Winson Chung private void loadAllApps() { 282864359a53dc827797917a8d9a0697a91996789801Winson Chung final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 28293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 28303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 28313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (oldCallbacks == null) { 28323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 283364359a53dc827797917a8d9a0697a91996789801Winson Chung Log.w(TAG, "LoaderTask running with no launcher (loadAllApps)"); 28343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 28359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 283631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); 28383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); 2839cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 2840ed13187a745866483139e2878037e1f8427ce567Kenny Guy final List<UserHandleCompat> profiles = mUserManager.getUserProfiles(); 2841ed13187a745866483139e2878037e1f8427ce567Kenny Guy 284264359a53dc827797917a8d9a0697a91996789801Winson Chung // Clear the list of apps 284364359a53dc827797917a8d9a0697a91996789801Winson Chung mBgAllAppsList.clear(); 2844e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal SharedPreferences prefs = mContext.getSharedPreferences( 2845e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE); 2846ed13187a745866483139e2878037e1f8427ce567Kenny Guy for (UserHandleCompat user : profiles) { 2847ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Query for the set of apps 2848ed13187a745866483139e2878037e1f8427ce567Kenny Guy final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 2849ed13187a745866483139e2878037e1f8427ce567Kenny Guy List<LauncherActivityInfoCompat> apps = mLauncherApps.getActivityList(null, user); 2850ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (DEBUG_LOADERS) { 2851ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "getActivityList took " 2852ed13187a745866483139e2878037e1f8427ce567Kenny Guy + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user); 2853ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user); 2854ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2855ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Fail if we don't have any apps 2856e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // TODO: Fix this. Only fail for the current user. 2857ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (apps == null || apps.isEmpty()) { 2858ed13187a745866483139e2878037e1f8427ce567Kenny Guy return; 2859ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2860ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Sort the applications by name 2861ed13187a745866483139e2878037e1f8427ce567Kenny Guy final long sortTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 2862ed13187a745866483139e2878037e1f8427ce567Kenny Guy Collections.sort(apps, 2863ed13187a745866483139e2878037e1f8427ce567Kenny Guy new LauncherModel.ShortcutNameComparator(mLabelCache)); 2864ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (DEBUG_LOADERS) { 2865ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "sort took " 2866ed13187a745866483139e2878037e1f8427ce567Kenny Guy + (SystemClock.uptimeMillis()-sortTime) + "ms"); 2867ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2868cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 2869ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Create the ApplicationInfos 2870ed13187a745866483139e2878037e1f8427ce567Kenny Guy for (int i = 0; i < apps.size(); i++) { 2871ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherActivityInfoCompat app = apps.get(i); 2872ed13187a745866483139e2878037e1f8427ce567Kenny Guy // This builds the icon bitmaps. 2873ed13187a745866483139e2878037e1f8427ce567Kenny Guy mBgAllAppsList.add(new AppInfo(mContext, app, user, mIconCache, mLabelCache)); 2874ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2875e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 28762a66bbf3f01c2be20ecbf9df4dd9e98d50ed119fSunny Goyal if (ADD_MANAGED_PROFILE_SHORTCUTS && !user.equals(UserHandleCompat.myUserHandle())) { 2877e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Add shortcuts for packages which were installed while launcher was dead. 2878e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX 2879e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal + mUserManager.getSerialNumberForUser(user); 2880e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Set<String> packagesAdded = prefs.getStringSet(shortcutsSetKey, Collections.EMPTY_SET); 2881e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal HashSet<String> newPackageSet = new HashSet<String>(); 2882e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 2883e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal for (LauncherActivityInfoCompat info : apps) { 2884e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String packageName = info.getComponentName().getPackageName(); 2885e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (!packagesAdded.contains(packageName) 2886e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal && !newPackageSet.contains(packageName)) { 2887e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal InstallShortcutReceiver.queueInstallShortcut(info, mContext); 2888e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 2889e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal newPackageSet.add(packageName); 2890e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 2891e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 2892e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal prefs.edit().putStringSet(shortcutsSetKey, newPackageSet).commit(); 2893e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 289464359a53dc827797917a8d9a0697a91996789801Winson Chung } 289585f418d0f5607c66efef1673075a6d3486e5af83Bjorn Bringert // Huh? Shouldn't this be inside the Runnable below? 2896eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> added = mBgAllAppsList.added; 2897eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka mBgAllAppsList.added = new ArrayList<AppInfo>(); 28983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 289964359a53dc827797917a8d9a0697a91996789801Winson Chung // Post callback on main thread 290064359a53dc827797917a8d9a0697a91996789801Winson Chung mHandler.post(new Runnable() { 290164359a53dc827797917a8d9a0697a91996789801Winson Chung public void run() { 290264359a53dc827797917a8d9a0697a91996789801Winson Chung final long bindTime = SystemClock.uptimeMillis(); 290311a1a53651924b544513f1f6971a735b18d67539Winson Chung final Callbacks callbacks = tryGetCallbacks(oldCallbacks); 290464359a53dc827797917a8d9a0697a91996789801Winson Chung if (callbacks != null) { 290564359a53dc827797917a8d9a0697a91996789801Winson Chung callbacks.bindAllApplications(added); 29063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 290764359a53dc827797917a8d9a0697a91996789801Winson Chung Log.d(TAG, "bound " + added.size() + " apps in " 290864359a53dc827797917a8d9a0697a91996789801Winson Chung + (SystemClock.uptimeMillis() - bindTime) + "ms"); 29093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 291064359a53dc827797917a8d9a0697a91996789801Winson Chung } else { 291164359a53dc827797917a8d9a0697a91996789801Winson Chung Log.i(TAG, "not binding apps: no Launcher activity"); 291264359a53dc827797917a8d9a0697a91996789801Winson Chung } 29133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 291464359a53dc827797917a8d9a0697a91996789801Winson Chung }); 2915cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 29163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 291764359a53dc827797917a8d9a0697a91996789801Winson Chung Log.d(TAG, "Icons processed in " 291864359a53dc827797917a8d9a0697a91996789801Winson Chung + (SystemClock.uptimeMillis() - loadTime) + "ms"); 29193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 29203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2921dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 29223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void dumpState() { 29232abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 2924b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mLoaderTask.mContext=" + mContext); 2925b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mLoaderTask.mIsLaunching=" + mIsLaunching); 2926b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mLoaderTask.mStopped=" + mStopped); 2927b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mLoaderTask.mLoadAndBindStepFinished=" + mLoadAndBindStepFinished); 2928b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "mItems size=" + sBgWorkspaceItems.size()); 2929b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 29303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 29313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 293231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato void enqueuePackageUpdated(PackageUpdatedTask task) { 2934700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick sWorker.post(task); 29353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2936d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 2937f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal private class AppsAvailabilityCheck extends BroadcastReceiver { 2938f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 2939f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal @Override 2940f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal public void onReceive(Context context, Intent intent) { 2941f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal synchronized (sBgLock) { 2942f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal final LauncherAppsCompat launcherApps = LauncherAppsCompat 2943f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal .getInstance(mApp.getContext()); 29441a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final PackageManager manager = context.getPackageManager(); 29451a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final ArrayList<String> packagesRemoved = new ArrayList<String>(); 29461a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final ArrayList<String> packagesUnavailable = new ArrayList<String>(); 2947f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal for (Entry<UserHandleCompat, HashSet<String>> entry : sPendingPackages.entrySet()) { 2948f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal UserHandleCompat user = entry.getKey(); 29491a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesRemoved.clear(); 29501a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.clear(); 2951f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal for (String pkg : entry.getValue()) { 2952f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!launcherApps.isPackageEnabledForProfile(pkg, user)) { 29531a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal boolean packageOnSdcard = launcherApps.isAppEnabled( 29541a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal manager, pkg, PackageManager.GET_UNINSTALLED_PACKAGES); 29551a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (packageOnSdcard) { 29561a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal Launcher.addDumpLog(TAG, "Package found on sd-card: " + pkg, true); 29571a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.add(pkg); 29581a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else { 29591a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal Launcher.addDumpLog(TAG, "Package not found: " + pkg, true); 29601a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesRemoved.add(pkg); 29611a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 2962f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2963f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2964f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!packagesRemoved.isEmpty()) { 2965f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_REMOVE, 2966f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal packagesRemoved.toArray(new String[packagesRemoved.size()]), user)); 2967f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 29681a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (!packagesUnavailable.isEmpty()) { 29691a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_UNAVAILABLE, 29701a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.toArray(new String[packagesUnavailable.size()]), user)); 29711a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 2972f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2973349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal sPendingPackages.clear(); 2974f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2975f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2976f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2977f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 29783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private class PackageUpdatedTask implements Runnable { 29793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int mOp; 29803611578579b4bfb25616085dafdb1a45207394f9Joe Onorato String[] mPackages; 2981ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat mUser; 2982d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 29833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_NONE = 0; 29843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_ADD = 1; 29853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_UPDATE = 2; 29863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_REMOVE = 3; // uninstlled 29873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_UNAVAILABLE = 4; // external media unmounted 298831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2989d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 2990ed13187a745866483139e2878037e1f8427ce567Kenny Guy public PackageUpdatedTask(int op, String[] packages, UserHandleCompat user) { 29913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mOp = op; 29923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mPackages = packages; 2993ed13187a745866483139e2878037e1f8427ce567Kenny Guy mUser = user; 29943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2995d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 29963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2997cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler final Context context = mApp.getContext(); 2998dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 29993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String[] packages = mPackages; 30003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int N = packages.length; 30013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato switch (mOp) { 30023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_ADD: 30033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.addPackage " + packages[i]); 3005ed13187a745866483139e2878037e1f8427ce567Kenny Guy mIconCache.remove(packages[i], mUser); 3006ed13187a745866483139e2878037e1f8427ce567Kenny Guy mBgAllAppsList.addPackage(context, packages[i], mUser); 3007dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 3008e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 3009e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Auto add shortcuts for added packages. 30102a66bbf3f01c2be20ecbf9df4dd9e98d50ed119fSunny Goyal if (ADD_MANAGED_PROFILE_SHORTCUTS 30112a66bbf3f01c2be20ecbf9df4dd9e98d50ed119fSunny Goyal && !UserHandleCompat.myUserHandle().equals(mUser)) { 3012e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal SharedPreferences prefs = context.getSharedPreferences( 3013e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE); 3014e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX 3015e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal + mUserManager.getSerialNumberForUser(mUser); 3016e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Set<String> shortcutSet = new HashSet<String>( 3017e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal prefs.getStringSet(shortcutsSetKey,Collections.EMPTY_SET)); 3018e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 3019e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal for (int i=0; i<N; i++) { 3020e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (!shortcutSet.contains(packages[i])) { 3021e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal shortcutSet.add(packages[i]); 3022e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal List<LauncherActivityInfoCompat> activities = 3023e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal mLauncherApps.getActivityList(packages[i], mUser); 3024e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (activities != null && !activities.isEmpty()) { 3025e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal InstallShortcutReceiver.queueInstallShortcut( 3026e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal activities.get(0), context); 3027e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 3028e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 3029e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 3030e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 3031e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal prefs.edit().putStringSet(shortcutsSetKey, shortcutSet).commit(); 3032e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 30333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 30343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_UPDATE: 30353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30363611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.updatePackage " + packages[i]); 3037ed13187a745866483139e2878037e1f8427ce567Kenny Guy mBgAllAppsList.updatePackage(context, packages[i], mUser); 3038eb1bb920507fe7f27b2ecece5b67749dac7850f3Michael Jurka WidgetPreviewLoader.removePackageFromDb( 3039e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mApp.getWidgetPreviewCacheDb(), packages[i]); 30403611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 30413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 30423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_REMOVE: 3043e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Remove the packageName for the set of auto-installed shortcuts. This 3044e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // will ensure that the shortcut when the app is installed again. 30452a66bbf3f01c2be20ecbf9df4dd9e98d50ed119fSunny Goyal if (ADD_MANAGED_PROFILE_SHORTCUTS 30462a66bbf3f01c2be20ecbf9df4dd9e98d50ed119fSunny Goyal && !UserHandleCompat.myUserHandle().equals(mUser)) { 3047e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal SharedPreferences prefs = context.getSharedPreferences( 3048e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE); 3049e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX 3050e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal + mUserManager.getSerialNumberForUser(mUser); 3051e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal HashSet<String> shortcutSet = new HashSet<String>( 3052e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal prefs.getStringSet(shortcutsSetKey, Collections.EMPTY_SET)); 3053e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal shortcutSet.removeAll(Arrays.asList(mPackages)); 3054e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal prefs.edit().putStringSet(shortcutsSetKey, shortcutSet).commit(); 3055e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 3056e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Fall through 30573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_UNAVAILABLE: 30581a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal boolean clearCache = mOp == OP_REMOVE; 30593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]); 30611a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal mBgAllAppsList.removePackage(packages[i], mUser, clearCache); 3062eb1bb920507fe7f27b2ecece5b67749dac7850f3Michael Jurka WidgetPreviewLoader.removePackageFromDb( 3063e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mApp.getWidgetPreviewCacheDb(), packages[i]); 30643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 30653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 30663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3067dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 3068eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka ArrayList<AppInfo> added = null; 3069eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka ArrayList<AppInfo> modified = null; 3070eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> removedApps = new ArrayList<AppInfo>(); 30713611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 3072487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mBgAllAppsList.added.size() > 0) { 3073eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka added = new ArrayList<AppInfo>(mBgAllAppsList.added); 30745d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.added.clear(); 30753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3076487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mBgAllAppsList.modified.size() > 0) { 3077eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka modified = new ArrayList<AppInfo>(mBgAllAppsList.modified); 30785d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.modified.clear(); 30793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 30805d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung if (mBgAllAppsList.removed.size() > 0) { 308183892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung removedApps.addAll(mBgAllAppsList.removed); 30825d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.removed.clear(); 3083cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung } 3084cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung 3085e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final Callbacks callbacks = getCallback(); 30863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks == null) { 30873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "Nobody to tell about the new app. Launcher is probably loading."); 30883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 3089be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 3090be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 30914390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final HashMap<ComponentName, AppInfo> addedOrUpdatedApps = 30924390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal new HashMap<ComponentName, AppInfo>(); 30934390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 30943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (added != null) { 309564359a53dc827797917a8d9a0697a91996789801Winson Chung // Ensure that we add all the workspace applications to the db 309676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (LauncherAppState.isDisableAllApps()) { 309794d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung final ArrayList<ItemInfo> addedInfos = new ArrayList<ItemInfo>(added); 309876a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen addAndBindAddedWorkspaceApps(context, addedInfos); 309976a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } else { 310076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen addAppsToAllApps(context, added); 310194d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung } 31024390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal for (AppInfo ai : added) { 31034390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal addedOrUpdatedApps.put(ai.componentName, ai); 31044390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 310676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 31073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (modified != null) { 3108eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> modifiedFinal = modified; 31094390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal for (AppInfo ai : modified) { 31104390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal addedOrUpdatedApps.put(ai.componentName, ai); 311164359a53dc827797917a8d9a0697a91996789801Winson Chung } 311264359a53dc827797917a8d9a0697a91996789801Winson Chung 31133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 31143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 3115e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3116cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 31173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAppsUpdated(modifiedFinal); 31183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 31193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 31203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 31213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3122780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung 31234390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Update shortcut infos 3124b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (mOp == OP_ADD || mOp == OP_UPDATE) { 31254390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<ShortcutInfo> updatedShortcuts = new ArrayList<ShortcutInfo>(); 31264390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<ShortcutInfo> removedShortcuts = new ArrayList<ShortcutInfo>(); 31274390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<LauncherAppWidgetInfo> widgets = new ArrayList<LauncherAppWidgetInfo>(); 31284390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 3129b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal HashSet<String> packageSet = new HashSet<String>(Arrays.asList(packages)); 3130b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal synchronized (sBgLock) { 31314390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal for (ItemInfo info : sBgItemsIdMap.values()) { 3132b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (info instanceof ShortcutInfo && mUser.equals(info.user)) { 3133b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal ShortcutInfo si = (ShortcutInfo) info; 31344390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal boolean infoUpdated = false; 31354390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal boolean shortcutUpdated = false; 31364390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31374390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Update shortcuts which use iconResource. 3138b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if ((si.iconResource != null) 31394390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && packageSet.contains(si.iconResource.packageName)) { 3140b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal Bitmap icon = Utilities.createIconBitmap(si.iconResource.packageName, 3141b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal si.iconResource.resourceName, mIconCache, context); 3142b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (icon != null) { 3143b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal si.setIcon(icon); 3144b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal si.usingFallbackIcon = false; 31454390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 3146b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3147b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 31484390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31494390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ComponentName cn = si.getTargetComponent(); 31504390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (cn != null && packageSet.contains(cn.getPackageName())) { 31514390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal AppInfo appInfo = addedOrUpdatedApps.get(cn); 31524390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31534390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (si.isPromise()) { 31544390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal mIconCache.deletePreloadedIcon(cn, mUser); 31554390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) { 31564390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Auto install icon 31574390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal PackageManager pm = context.getPackageManager(); 31584390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ResolveInfo matched = pm.resolveActivity( 31594390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal new Intent(Intent.ACTION_MAIN) 31604390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER), 31614390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal PackageManager.MATCH_DEFAULT_ONLY); 31624390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (matched == null) { 31634390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Try to find the best match activity. 31644390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal Intent intent = pm.getLaunchIntentForPackage( 31654390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal cn.getPackageName()); 31664390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (intent != null) { 31674390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal cn = intent.getComponent(); 31684390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal appInfo = addedOrUpdatedApps.get(cn); 31694390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31704390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31714390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if ((intent == null) || (appInfo == null)) { 31724390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal removedShortcuts.add(si); 31734390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal continue; 31744390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31754390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.promisedIntent = intent; 31764390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31774390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31784390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31794390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Restore the shortcut. 31804390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.intent = si.promisedIntent; 31814390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.promisedIntent = null; 31824390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.status &= ~ShortcutInfo.FLAG_RESTORED_ICON 31834390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal & ~ShortcutInfo.FLAG_AUTOINTALL_ICON 31844390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal & ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE; 31854390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31864390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 31874390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.updateIcon(mIconCache); 31884390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31894390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31904390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction()) 31914390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 31924390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.updateIcon(mIconCache); 31934390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.title = appInfo.title.toString(); 31944390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.contentDescription = appInfo.contentDescription; 31954390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 31964390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31974390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31984390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if ((si.isDisabled & ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE) != 0) { 31994390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Since package was just updated, the target must be available now. 32004390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.isDisabled &= ~ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; 32014390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal shortcutUpdated = true; 32024390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32034390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32044390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 32054390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (infoUpdated || shortcutUpdated) { 32064390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updatedShortcuts.add(si); 32074390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32084390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (infoUpdated) { 32094390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updateItemInDatabase(context, si); 32104390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32114390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } else if (info instanceof LauncherAppWidgetInfo) { 32124390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info; 32134390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (mUser.equals(widgetInfo.user) 32144390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) 32154390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && packageSet.contains(widgetInfo.providerName.getPackageName())) { 32164390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY; 32174390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal widgets.add(widgetInfo); 32184390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updateItemInDatabase(context, widgetInfo); 32194390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 3220b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3221b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3222b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3223b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal 32244390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (!updatedShortcuts.isEmpty() || !removedShortcuts.isEmpty()) { 3225b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal mHandler.post(new Runnable() { 32264390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 3227b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal public void run() { 3228e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3229b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (callbacks == cb && cb != null) { 32304390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal callbacks.bindShortcutsChanged( 32314390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updatedShortcuts, removedShortcuts, mUser); 32324390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32334390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32344390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal }); 32354390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (!removedShortcuts.isEmpty()) { 32364390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal deleteItemsFromDatabase(context, removedShortcuts); 32374390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32384390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32394390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (!widgets.isEmpty()) { 32404390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal mHandler.post(new Runnable() { 32414390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void run() { 3242e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 32434390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (callbacks == cb && cb != null) { 32444390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal callbacks.bindWidgetsRestored(widgets); 3245b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3246b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3247b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal }); 3248b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3249b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3250b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal 3251df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung final ArrayList<String> removedPackageNames = 3252df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung new ArrayList<String>(); 32531a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (mOp == OP_REMOVE || mOp == OP_UNAVAILABLE) { 3254df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Mark all packages in the broadcast to be removed 3255df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung removedPackageNames.addAll(Arrays.asList(packages)); 3256df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } else if (mOp == OP_UPDATE) { 3257df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Mark disabled packages in the broadcast to be removed 3258df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung for (int i=0; i<N; i++) { 3259ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (isPackageDisabled(context, packages[i], mUser)) { 3260df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung removedPackageNames.add(packages[i]); 326164359a53dc827797917a8d9a0697a91996789801Winson Chung } 326264359a53dc827797917a8d9a0697a91996789801Winson Chung } 3263df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } 32641a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 3265df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung if (!removedPackageNames.isEmpty() || !removedApps.isEmpty()) { 32661a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final int removeReason; 32671a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (mOp == OP_UNAVAILABLE) { 32681a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal removeReason = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; 32691a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else { 32701a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Remove all the components associated with this package 32711a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal for (String pn : removedPackageNames) { 32721a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal deletePackageFromDatabase(context, pn, mUser); 32731a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 32741a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Remove all the specific components 32751a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal for (AppInfo a : removedApps) { 32761a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal ArrayList<ItemInfo> infos = getItemInfoForComponentName(a.componentName, mUser); 32771a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal deleteItemsFromDatabase(context, infos); 32781a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 32791a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal removeReason = 0; 32801a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 32811a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 3282df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Remove any queued items from the install queue 3283e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal InstallShortcutReceiver.removeFromInstallQueue(context, removedPackageNames, mUser); 3284df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Call the components-removed callback 32853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 32863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 3287e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3288cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 32891a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal callbacks.bindComponentsRemoved( 32901a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal removedPackageNames, removedApps, mUser, removeReason); 32913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 32923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 32933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 3294be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 329580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung 3296c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka final ArrayList<Object> widgetsAndShortcuts = 3297ed13187a745866483139e2878037e1f8427ce567Kenny Guy getSortedWidgetsAndShortcuts(context); 329880baf5a6b3c62a62265f626d43d1167783c94131Winson Chung mHandler.post(new Runnable() { 329980baf5a6b3c62a62265f626d43d1167783c94131Winson Chung @Override 330080baf5a6b3c62a62265f626d43d1167783c94131Winson Chung public void run() { 3301e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3302cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 3303c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka callbacks.bindPackagesUpdated(widgetsAndShortcuts); 330480baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 330580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung } 33064caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen }); 33074caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen 33084caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen // Write all the logs to disk 33094caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen mHandler.post(new Runnable() { 33104caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen public void run() { 3311e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 33124caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen if (callbacks == cb && cb != null) { 3313ede4129e77f8347e32c0da9c615bcff2cbc06fd8Winson Chung callbacks.dumpLogsToLocalData(); 33144caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen } 33154caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen } 331680baf5a6b3c62a62265f626d43d1167783c94131Winson Chung }); 331731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 331831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 331931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 33205940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen public static List<LauncherAppWidgetProviderInfo> getWidgetProviders(Context context) { 33215940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen synchronized (sBgLock) { 33225940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (sBgWidgetProviders != null && !sWidgetProvidersDirty) { 33235940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen return new ArrayList<LauncherAppWidgetProviderInfo>(sBgWidgetProviders.values()); 33245940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33255940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen sBgWidgetProviders = new HashMap<ComponentName, LauncherAppWidgetProviderInfo>(); 33265940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen List<AppWidgetProviderInfo> widgets = 33275940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen AppWidgetManagerCompat.getInstance(context).getAllProviders(); 33285940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherAppWidgetProviderInfo info; 33295940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen for (AppWidgetProviderInfo pInfo : widgets) { 33305940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen info = LauncherAppWidgetProviderInfo.fromProviderInfo(context, pInfo); 33315940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen sBgWidgetProviders.put(info.provider, info); 33325940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33335940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 33345940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen Collection<CustomAppWidget> customWidgets = Launcher.getCustomAppWidgets().values(); 33355940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen for (CustomAppWidget widget : customWidgets) { 33365940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen info = new LauncherAppWidgetProviderInfo(context, widget); 33375940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen sBgWidgetProviders.put(info.provider, info); 33385940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33395940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen sWidgetProvidersDirty = false; 33405940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen return new ArrayList<LauncherAppWidgetProviderInfo>(sBgWidgetProviders.values()); 33415940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33425940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33435940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 33445940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen public static LauncherAppWidgetProviderInfo getProviderInfo(Context ctx, ComponentName name) { 33455940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen synchronized (sBgLock) { 33465940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (sBgWidgetProviders == null) { 33475940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen getWidgetProviders(ctx); 33485940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33495940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen return sBgWidgetProviders.get(name); 33505940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33515940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33525940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 3353c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka // Returns a list of ResolveInfos/AppWindowInfos in sorted order 3354c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka public static ArrayList<Object> getSortedWidgetsAndShortcuts(Context context) { 3355c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka PackageManager packageManager = context.getPackageManager(); 3356c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka final ArrayList<Object> widgetsAndShortcuts = new ArrayList<Object>(); 33575940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen widgetsAndShortcuts.addAll(getWidgetProviders(context)); 3358c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); 3359c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka widgetsAndShortcuts.addAll(packageManager.queryIntentActivities(shortcutsIntent, 0)); 3360ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal Collections.sort(widgetsAndShortcuts, new WidgetAndShortcutNameComparator(context)); 3361c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka return widgetsAndShortcuts; 3362c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 3363c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka 3364ed13187a745866483139e2878037e1f8427ce567Kenny Guy private static boolean isPackageDisabled(Context context, String packageName, 3365ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user) { 3366ed13187a745866483139e2878037e1f8427ce567Kenny Guy final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3367ed13187a745866483139e2878037e1f8427ce567Kenny Guy return !launcherApps.isPackageEnabledForProfile(packageName, user); 3368df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } 3369556f6135f992dcd5bfbfffe0172627bfbf57d24eAdam Cohen 3370ed13187a745866483139e2878037e1f8427ce567Kenny Guy public static boolean isValidPackageActivity(Context context, ComponentName cn, 3371ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user) { 3372ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung if (cn == null) { 3373ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung return false; 3374ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3375ed13187a745866483139e2878037e1f8427ce567Kenny Guy final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3376ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!launcherApps.isPackageEnabledForProfile(cn.getPackageName(), user)) { 3377ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung return false; 3378ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3379ed13187a745866483139e2878037e1f8427ce567Kenny Guy return launcherApps.isActivityEnabledForProfile(cn, user); 3380ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3381ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung 3382a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen public static boolean isValidPackage(Context context, String packageName, 3383a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen UserHandleCompat user) { 3384a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen if (packageName == null) { 3385a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen return false; 3386a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen } 3387a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3388a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen return launcherApps.isPackageEnabledForProfile(packageName, user); 3389a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen } 3390a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen 33919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 3392f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * Make an ShortcutInfo object for a restored application or shortcut item that points 3393f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * to a package that is not yet installed on the system. 3394f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren */ 3395349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal public ShortcutInfo getRestoredItemInfo(Cursor cursor, int titleIndex, Intent intent, 3396349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal int promiseType) { 3397f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren final ShortcutInfo info = new ShortcutInfo(); 3398349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.user = UserHandleCompat.myUserHandle(); 3399349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal mIconCache.getTitleAndIcon(info, intent, info.user, true); 3400349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 3401349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) { 3402349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal String title = (cursor != null) ? cursor.getString(titleIndex) : null; 3403349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (!TextUtils.isEmpty(title)) { 3404349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.title = title; 3405349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 3406349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.status = ShortcutInfo.FLAG_RESTORED_ICON; 3407349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } else if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { 3408349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (TextUtils.isEmpty(info.title)) { 3409349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.title = (cursor != null) ? cursor.getString(titleIndex) : ""; 3410349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 3411349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.status = ShortcutInfo.FLAG_AUTOINTALL_ICON; 3412f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } else { 3413349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal throw new InvalidParameterException("Invalid restoreType " + promiseType); 3414f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3415349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 3416c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy info.contentDescription = mUserManager.getBadgedLabelForUser( 3417c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy info.title.toString(), info.user); 3418f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 3419349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.promisedIntent = intent; 3420f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren return info; 3421f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3422f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 3423f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren /** 3424f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * Make an Intent object for a restored application or shortcut item that points 3425f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * to the market page for the item. 3426f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren */ 3427f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren private Intent getRestoredItemIntent(Cursor c, Context context, Intent intent) { 3428f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren ComponentName componentName = intent.getComponent(); 3429e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return getMarketIntent(componentName.getPackageName()); 3430e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 3431e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 3432e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal static Intent getMarketIntent(String packageName) { 3433e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return new Intent(Intent.ACTION_VIEW) 3434e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .setData(new Uri.Builder() 3435f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren .scheme("market") 3436f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren .authority("details") 3437e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .appendQueryParameter("id", packageName) 3438e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .build()); 3439f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3440f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 3441f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren /** 344256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * This is called from the code that adds shortcuts from the intent receiver. This 344356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * doesn't have a Cursor, but 34449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 3445ed13187a745866483139e2878037e1f8427ce567Kenny Guy public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, 3446ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user, Context context) { 3447f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal return getShortcutInfo(manager, intent, user, context, null, -1, -1, null, false); 344856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 344956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 345056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato /** 345156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * Make an ShortcutInfo object for a shortcut that is an application. 345256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * 345356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * If c is not null, then it will be used to fill in missing data like the title and icon. 345456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato */ 3455ed13187a745866483139e2878037e1f8427ce567Kenny Guy public ShortcutInfo getShortcutInfo(PackageManager manager, Intent intent, 3456ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user, Context context, Cursor c, int iconIndex, int titleIndex, 3457f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal HashMap<Object, CharSequence> labelCache, boolean allowMissingTarget) { 3458ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user == null) { 3459ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "Null user found in getShortcutInfo"); 3460ed13187a745866483139e2878037e1f8427ce567Kenny Guy return null; 3461ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3462ed13187a745866483139e2878037e1f8427ce567Kenny Guy 346356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato ComponentName componentName = intent.getComponent(); 3464ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (componentName == null) { 3465ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "Missing component found in getShortcutInfo: " + componentName); 34669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 346731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 346831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3469ed13187a745866483139e2878037e1f8427ce567Kenny Guy Intent newIntent = new Intent(intent.getAction(), null); 3470ed13187a745866483139e2878037e1f8427ce567Kenny Guy newIntent.addCategory(Intent.CATEGORY_LAUNCHER); 3471ed13187a745866483139e2878037e1f8427ce567Kenny Guy newIntent.setComponent(componentName); 3472ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherActivityInfoCompat lai = mLauncherApps.resolveActivity(newIntent, user); 3473f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if ((lai == null) && !allowMissingTarget) { 3474ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "Missing activity found in getShortcutInfo: " + componentName); 3475ed13187a745866483139e2878037e1f8427ce567Kenny Guy return null; 3476ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3477ed13187a745866483139e2878037e1f8427ce567Kenny Guy 3478ed13187a745866483139e2878037e1f8427ce567Kenny Guy final ShortcutInfo info = new ShortcutInfo(); 34798ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 348056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the resource -- This may implicitly give us back the fallback icon, 348156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // but don't worry about that. All we're doing with usingFallbackIcon is 348256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // to avoid saving lots of copies of that in the database, and most apps 348356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // have icons anyway. 3484ed13187a745866483139e2878037e1f8427ce567Kenny Guy Bitmap icon = mIconCache.getIcon(componentName, lai, labelCache); 3485c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung 348656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the db 348756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 348856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (c != null) { 3489931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka icon = getIconFromCursor(c, iconIndex, context); 349056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 34919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 349256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the fallback icon 349356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 3494ed13187a745866483139e2878037e1f8427ce567Kenny Guy icon = mIconCache.getDefaultIcon(user); 349556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 349656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 349756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.setIcon(icon); 349856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 3499ed13187a745866483139e2878037e1f8427ce567Kenny Guy // From the cache. 3500ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (labelCache != null) { 3501ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.title = labelCache.get(componentName); 3502ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3503ed13187a745866483139e2878037e1f8427ce567Kenny Guy 350456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the resource 3505ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (info.title == null && lai != null) { 3506ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.title = lai.getLabel(); 3507ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (labelCache != null) { 3508ed13187a745866483139e2878037e1f8427ce567Kenny Guy labelCache.put(componentName, info.title); 3509c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 351056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 351156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the db 351256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (info.title == null) { 351356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (c != null) { 351456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = c.getString(titleIndex); 351556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 351656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 351756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // fall back to the class name of the activity 35189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (info.title == null) { 351956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = componentName.getClassName(); 35209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 35219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; 3522ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = user; 3523c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy info.contentDescription = mUserManager.getBadgedLabelForUser( 3524c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy info.title.toString(), info.user); 35259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 35269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 352731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 352864359a53dc827797917a8d9a0697a91996789801Winson Chung static ArrayList<ItemInfo> filterItemInfos(Collection<ItemInfo> infos, 352964359a53dc827797917a8d9a0697a91996789801Winson Chung ItemInfoFilter f) { 353064359a53dc827797917a8d9a0697a91996789801Winson Chung HashSet<ItemInfo> filtered = new HashSet<ItemInfo>(); 353164359a53dc827797917a8d9a0697a91996789801Winson Chung for (ItemInfo i : infos) { 353264359a53dc827797917a8d9a0697a91996789801Winson Chung if (i instanceof ShortcutInfo) { 353364359a53dc827797917a8d9a0697a91996789801Winson Chung ShortcutInfo info = (ShortcutInfo) i; 3534349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ComponentName cn = info.getTargetComponent(); 353564359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(null, info, cn)) { 353664359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(info); 353764359a53dc827797917a8d9a0697a91996789801Winson Chung } 353864359a53dc827797917a8d9a0697a91996789801Winson Chung } else if (i instanceof FolderInfo) { 353964359a53dc827797917a8d9a0697a91996789801Winson Chung FolderInfo info = (FolderInfo) i; 354064359a53dc827797917a8d9a0697a91996789801Winson Chung for (ShortcutInfo s : info.contents) { 3541349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ComponentName cn = s.getTargetComponent(); 354264359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(info, s, cn)) { 354364359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(s); 35448a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 35458a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 354664359a53dc827797917a8d9a0697a91996789801Winson Chung } else if (i instanceof LauncherAppWidgetInfo) { 354764359a53dc827797917a8d9a0697a91996789801Winson Chung LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) i; 354864359a53dc827797917a8d9a0697a91996789801Winson Chung ComponentName cn = info.providerName; 354964359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(null, info, cn)) { 355064359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(info); 355164359a53dc827797917a8d9a0697a91996789801Winson Chung } 35528a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 35538a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 355464359a53dc827797917a8d9a0697a91996789801Winson Chung return new ArrayList<ItemInfo>(filtered); 355564359a53dc827797917a8d9a0697a91996789801Winson Chung } 355664359a53dc827797917a8d9a0697a91996789801Winson Chung 3557ed13187a745866483139e2878037e1f8427ce567Kenny Guy private ArrayList<ItemInfo> getItemInfoForComponentName(final ComponentName cname, 3558ed13187a745866483139e2878037e1f8427ce567Kenny Guy final UserHandleCompat user) { 355964359a53dc827797917a8d9a0697a91996789801Winson Chung ItemInfoFilter filter = new ItemInfoFilter() { 356064359a53dc827797917a8d9a0697a91996789801Winson Chung @Override 356164359a53dc827797917a8d9a0697a91996789801Winson Chung public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn) { 3562ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (info.user == null) { 3563ed13187a745866483139e2878037e1f8427ce567Kenny Guy return cn.equals(cname); 3564ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 3565ed13187a745866483139e2878037e1f8427ce567Kenny Guy return cn.equals(cname) && info.user.equals(user); 3566ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 356764359a53dc827797917a8d9a0697a91996789801Winson Chung } 356864359a53dc827797917a8d9a0697a91996789801Winson Chung }; 356964359a53dc827797917a8d9a0697a91996789801Winson Chung return filterItemInfos(sBgItemsIdMap.values(), filter); 357064359a53dc827797917a8d9a0697a91996789801Winson Chung } 357164359a53dc827797917a8d9a0697a91996789801Winson Chung 35721a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal /** 35730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Make an ShortcutInfo object for a shortcut that isn't an application. 35749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 35750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private ShortcutInfo getShortcutInfo(Cursor c, Context context, 357656d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato int iconTypeIndex, int iconPackageIndex, int iconResourceIndex, int iconIndex, 357756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato int titleIndex) { 357831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 357956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Bitmap icon = null; 3580c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 3581ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Non-app shortcuts are only supported for current user. 3582ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = UserHandleCompat.myUserHandle(); 35839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 35847376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project 35858ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: If there's an explicit component and we can't install that, delete it. 35868ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 358756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = c.getString(titleIndex); 358856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 35899c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato int iconType = c.getInt(iconTypeIndex); 35909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (iconType) { 35919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_RESOURCE: 35929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String packageName = c.getString(iconPackageIndex); 35939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato String resourceName = c.getString(iconResourceIndex); 359456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = false; 359556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the resource 3596b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal icon = Utilities.createIconBitmap(packageName, resourceName, mIconCache, context); 359756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the db 359856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 3599931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka icon = getIconFromCursor(c, iconIndex, context); 360056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 360156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the fallback icon 360256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 3603ed13187a745866483139e2878037e1f8427ce567Kenny Guy icon = mIconCache.getDefaultIcon(info.user); 360456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 36057376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project } 36069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 36079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato case LauncherSettings.Favorites.ICON_TYPE_BITMAP: 3608931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka icon = getIconFromCursor(c, iconIndex, context); 360956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato if (icon == null) { 3610ed13187a745866483139e2878037e1f8427ce567Kenny Guy icon = mIconCache.getDefaultIcon(info.user); 361156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = false; 361256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 361356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } else { 361456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.customIcon = true; 36159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 36169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 36179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato default: 3618ed13187a745866483139e2878037e1f8427ce567Kenny Guy icon = mIconCache.getDefaultIcon(info.user); 361956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 36209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.customIcon = false; 36219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 362231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 3623d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato info.setIcon(icon); 36249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 3625f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 362631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3627931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka Bitmap getIconFromCursor(Cursor c, int iconIndex, Context context) { 36283a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka @SuppressWarnings("all") // suppress dead code warning 36293a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka final boolean debug = false; 36303a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka if (debug) { 363156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato Log.d(TAG, "getIconFromCursor app=" 363256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato + c.getString(c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE))); 363356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 363456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato byte[] data = c.getBlob(iconIndex); 363556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato try { 3636931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka return Utilities.createIconBitmap( 3637931dc9779dab5071efc21163647f5f004991bfb3Michael Jurka BitmapFactory.decodeByteArray(data, 0, data.length), context); 363856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } catch (Exception e) { 363956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato return null; 364056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 364156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 364256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 36432350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal ShortcutInfo infoFromShortcutIntent(Context context, Intent data) { 36440589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 36450589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); 36460589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON); 36470589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 3648d919882006a457d16dea46bd546472e6534b5c19Adam Cohen if (intent == null) { 3649d919882006a457d16dea46bd546472e6534b5c19Adam Cohen // If the intent is null, we can't construct a valid ShortcutInfo, so we return null 3650d919882006a457d16dea46bd546472e6534b5c19Adam Cohen Log.e(TAG, "Can't construct ShorcutInfo with null intent"); 3651d919882006a457d16dea46bd546472e6534b5c19Adam Cohen return null; 3652d919882006a457d16dea46bd546472e6534b5c19Adam Cohen } 3653d919882006a457d16dea46bd546472e6534b5c19Adam Cohen 36540589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Bitmap icon = null; 36550589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato boolean customIcon = false; 36560589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutIconResource iconResource = null; 36570589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 36582fce90c38a79d318e96a28107dea287e42509861Sunny Goyal if (bitmap instanceof Bitmap) { 36592fce90c38a79d318e96a28107dea287e42509861Sunny Goyal icon = Utilities.createIconBitmap((Bitmap) bitmap, context); 36600589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato customIcon = true; 36610589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } else { 36620589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 3663b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (extra instanceof ShortcutIconResource) { 3664b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal iconResource = (ShortcutIconResource) extra; 3665b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal icon = Utilities.createIconBitmap(iconResource.packageName, 3666b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal iconResource.resourceName, mIconCache, context); 36670589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 36680589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 36690589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 3670c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 367156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 3672ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Only support intents for current user for now. Intents sent from other 3673ed13187a745866483139e2878037e1f8427ce567Kenny Guy // users wouldn't get here without intent forwarding anyway. 3674ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = UserHandleCompat.myUserHandle(); 36750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (icon == null) { 36762350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal icon = mIconCache.getDefaultIcon(info.user); 36772350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal info.usingFallbackIcon = true; 36780589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 36790589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.setIcon(icon); 368056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 36810589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.title = name; 3682c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy info.contentDescription = mUserManager.getBadgedLabelForUser( 3683c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy info.title.toString(), info.user); 36840589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.intent = intent; 36850589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.customIcon = customIcon; 36860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.iconResource = iconResource; 36870589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 36880589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 36890589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 36900589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 3691aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung boolean queueIconToBeChecked(HashMap<Object, byte[]> cache, ShortcutInfo info, Cursor c, 3692aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung int iconIndex) { 369317a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato // If apps can't be on SD, don't even bother. 3694ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung if (!mAppsCanBeOnRemoveableStorage) { 3695aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung return false; 369617a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato } 369756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // If this icon doesn't have a custom icon, check to see 369856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // what's stored in the DB, and if it doesn't match what 369956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // we're going to show, store what we are going to show back 370056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // into the DB. We do this so when we're loading, if the 370156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // package manager can't find an icon (for example because 370256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // the app is on SD) then we can use that instead. 3703ddc9c1fb1ab426772add520d277ea9c2cd674094Joe Onorato if (!info.customIcon && !info.usingFallbackIcon) { 3704aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung cache.put(info, c.getBlob(iconIndex)); 3705aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung return true; 3706aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } 3707aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung return false; 3708aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } 3709aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung void updateSavedIcon(Context context, ShortcutInfo info, byte[] data) { 3710aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung boolean needSave = false; 3711aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung try { 3712aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (data != null) { 3713aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung Bitmap saved = BitmapFactory.decodeByteArray(data, 0, data.length); 3714aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung Bitmap loaded = info.getIcon(mIconCache); 3715aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung needSave = !saved.sameAs(loaded); 3716aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } else { 371756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato needSave = true; 371856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 3719aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } catch (Exception e) { 3720aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung needSave = true; 3721aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung } 3722aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung if (needSave) { 3723aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung Log.d(TAG, "going to save icon bitmap for info=" + info); 3724aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung // This is slower than is ideal, but this only happens once 3725aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung // or when the app is updated with a new icon. 3726aac01e1073f3deb3f543fd27cc63fd727101584eWinson Chung updateItemInDatabase(context, info); 372756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 372856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 372956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 373031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 3731df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * Return an existing FolderInfo object if we have encountered this ID previously, 37329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * or make a new one. 373331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 3734df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private static FolderInfo findOrMakeFolder(HashMap<Long, FolderInfo> folders, long id) { 37359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // See if a placeholder was created for us already 37369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = folders.get(id); 3737df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (folderInfo == null) { 37389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // No placeholder -- create a new instance 3739c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka folderInfo = new FolderInfo(); 37409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folders.put(id, folderInfo); 374131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 3742df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return folderInfo; 374331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 374431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3745eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public static final Comparator<AppInfo> getAppNameComparator() { 37461190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung final Collator collator = Collator.getInstance(); 3747eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka return new Comparator<AppInfo>() { 3748eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public final int compare(AppInfo a, AppInfo b) { 3749ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (a.user.equals(b.user)) { 3750ed13187a745866483139e2878037e1f8427ce567Kenny Guy int result = collator.compare(a.title.toString().trim(), 3751ed13187a745866483139e2878037e1f8427ce567Kenny Guy b.title.toString().trim()); 3752ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (result == 0) { 3753ed13187a745866483139e2878037e1f8427ce567Kenny Guy result = a.componentName.compareTo(b.componentName); 3754ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3755ed13187a745866483139e2878037e1f8427ce567Kenny Guy return result; 3756ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 3757ed13187a745866483139e2878037e1f8427ce567Kenny Guy // TODO Need to figure out rules for sorting 3758ed13187a745866483139e2878037e1f8427ce567Kenny Guy // profiles, this puts work second. 3759ed13187a745866483139e2878037e1f8427ce567Kenny Guy return a.user.toString().compareTo(b.user.toString()); 37601190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung } 37615b1808da75ed3e3528cb31dee56a4e363812cc21Michael Jurka } 37621190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung }; 37631190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung } 3764eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public static final Comparator<AppInfo> APP_INSTALL_TIME_COMPARATOR 3765eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka = new Comparator<AppInfo>() { 3766eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public final int compare(AppInfo a, AppInfo b) { 376778403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung if (a.firstInstallTime < b.firstInstallTime) return 1; 376878403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung if (a.firstInstallTime > b.firstInstallTime) return -1; 376978403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung return 0; 377078403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung } 377178403feedcf6d61a527cf0c904cb55ca43c0f3cbWinson Chung }; 37725308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung static ComponentName getComponentNameFromResolveInfo(ResolveInfo info) { 37735308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung if (info.activityInfo != null) { 37745308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung return new ComponentName(info.activityInfo.packageName, info.activityInfo.name); 37755308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung } else { 37765308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung return new ComponentName(info.serviceInfo.packageName, info.serviceInfo.name); 37775308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung } 37785308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung } 3779ed13187a745866483139e2878037e1f8427ce567Kenny Guy public static class ShortcutNameComparator implements Comparator<LauncherActivityInfoCompat> { 37801190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung private Collator mCollator; 3781c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung private HashMap<Object, CharSequence> mLabelCache; 3782785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung ShortcutNameComparator(PackageManager pm) { 3783c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache = new HashMap<Object, CharSequence>(); 37841190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung mCollator = Collator.getInstance(); 3785c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 3786ed13187a745866483139e2878037e1f8427ce567Kenny Guy ShortcutNameComparator(HashMap<Object, CharSequence> labelCache) { 3787c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache = labelCache; 37881190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung mCollator = Collator.getInstance(); 3789785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 3790ed13187a745866483139e2878037e1f8427ce567Kenny Guy public final int compare(LauncherActivityInfoCompat a, LauncherActivityInfoCompat b) { 37910c4a64451eb868d1f6abda45896dc2d2c4a9f2deSunny Goyal String labelA, labelB; 3792ed13187a745866483139e2878037e1f8427ce567Kenny Guy ComponentName keyA = a.getComponentName(); 3793ed13187a745866483139e2878037e1f8427ce567Kenny Guy ComponentName keyB = b.getComponentName(); 37945308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung if (mLabelCache.containsKey(keyA)) { 37950c4a64451eb868d1f6abda45896dc2d2c4a9f2deSunny Goyal labelA = mLabelCache.get(keyA).toString(); 3796c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 3797ed13187a745866483139e2878037e1f8427ce567Kenny Guy labelA = a.getLabel().toString().trim(); 3798c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung 37995308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung mLabelCache.put(keyA, labelA); 3800c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 38015308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung if (mLabelCache.containsKey(keyB)) { 38020c4a64451eb868d1f6abda45896dc2d2c4a9f2deSunny Goyal labelB = mLabelCache.get(keyB).toString(); 3803c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 3804ed13187a745866483139e2878037e1f8427ce567Kenny Guy labelB = b.getLabel().toString().trim(); 3805c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung 38065308f24d4b66b020202b88eff672f5a89096ebb6Winson Chung mLabelCache.put(keyB, labelB); 3807c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 38081190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung return mCollator.compare(labelA, labelB); 3809785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung } 3810785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung }; 38111ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung public static class WidgetAndShortcutNameComparator implements Comparator<Object> { 3812ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal private final AppWidgetManagerCompat mManager; 3813ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal private final PackageManager mPackageManager; 3814ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal private final HashMap<Object, String> mLabelCache; 3815ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal private final Collator mCollator; 3816ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal 3817ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal WidgetAndShortcutNameComparator(Context context) { 3818ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal mManager = AppWidgetManagerCompat.getInstance(context); 3819ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal mPackageManager = context.getPackageManager(); 38201ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung mLabelCache = new HashMap<Object, String>(); 38211190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung mCollator = Collator.getInstance(); 38221ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung } 38231ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung public final int compare(Object a, Object b) { 38241ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung String labelA, labelB; 3825c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung if (mLabelCache.containsKey(a)) { 3826c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung labelA = mLabelCache.get(a); 3827c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 38285940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen labelA = (a instanceof LauncherAppWidgetProviderInfo) 38295940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen ? mManager.loadLabel((LauncherAppWidgetProviderInfo) a) 3830ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal : ((ResolveInfo) a).loadLabel(mPackageManager).toString().trim(); 3831c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache.put(a, labelA); 3832c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 3833c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung if (mLabelCache.containsKey(b)) { 3834c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung labelB = mLabelCache.get(b); 3835c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } else { 38365940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen labelB = (b instanceof LauncherAppWidgetProviderInfo) 38375940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen ? mManager.loadLabel((LauncherAppWidgetProviderInfo) a) 3838ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyal : ((ResolveInfo) b).loadLabel(mPackageManager).toString().trim(); 3839c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung mLabelCache.put(b, labelB); 3840c3eecff9043759926df124483b45fe8f4436ae7cWinson Chung } 38411190487e15325e371c6c18181b1a5ef7ab2a79e6Winson Chung return mCollator.compare(labelA, labelB); 38421ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung } 38431ed747a4c07101793322c13a36dd547df4a3aa50Winson Chung }; 3844be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 3845651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal static boolean isValidProvider(AppWidgetProviderInfo provider) { 3846651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal return (provider != null) && (provider.provider != null) 3847651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal && (provider.provider.getPackageName() != null); 3848651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } 3849651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal 3850be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 3851be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mCallbacks=" + mCallbacks); 3852eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.data", mBgAllAppsList.data); 3853eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.added", mBgAllAppsList.added); 3854eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.removed", mBgAllAppsList.removed); 3855eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.modified", mBgAllAppsList.modified); 38563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask != null) { 38573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask.dumpState(); 38583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 38593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "mLoaderTask=null"); 38603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3861be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 3862e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 3863e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal public Callbacks getCallback() { 3864e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return mCallbacks != null ? mCallbacks.get() : null; 3865e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 386631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 3867