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; 202d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyalimport android.appwidget.AppWidgetManager; 21629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetProviderInfo; 22f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.BroadcastReceiver; 23f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ComponentName; 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; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.PackageManager; 32bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monkimport android.content.pm.ProviderInfo; 3331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ResolveInfo; 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.database.Cursor; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.net.Uri; 3717a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onoratoimport android.os.Environment; 383611578579b4bfb25616085dafdb1a45207394f9Joe Onoratoimport android.os.Handler; 393611578579b4bfb25616085dafdb1a45207394f9Joe Onoratoimport android.os.HandlerThread; 40756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyalimport android.os.Looper; 410589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.os.Parcelable; 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Process; 439c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.SystemClock; 443abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Songimport android.os.TransactionTooLargeException; 45c3919c0e994309982efc8779af57e2bc78dcac43Chris Wrenimport android.provider.BaseColumns; 46a90303bb6fdad59e4a55855edba68c9902192599Winson Chungimport android.text.TextUtils; 47aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.util.Log; 4871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.util.LongSparseArray; 49c916834ad0da535f08325bcd902a60070f2f7e53Winson Chungimport android.util.Pair; 5034c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurka 51ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyalimport com.android.launcher3.compat.AppWidgetManagerCompat; 52ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherActivityInfoCompat; 53ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherAppsCompat; 54349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat; 55e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo; 56ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.UserHandleCompat; 57ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.UserManagerCompat; 58e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyalimport com.android.launcher3.model.MigrateFromRestoreTask; 592bd3d7d1cb5e4d8d826982d11b456739fed6b817Hyunyoung Songimport com.android.launcher3.model.WidgetsModel; 6026ace12135a662ad864678c9fede9817e5c02b67Robin Leeimport com.android.launcher3.util.ComponentKey; 614e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyalimport com.android.launcher3.util.CursorIconInfo; 62e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyalimport com.android.launcher3.util.LongArrayMap; 6318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyalimport com.android.launcher3.util.ManagedProfileHeuristic; 64091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 65edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 66c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.lang.ref.WeakReference; 67c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.net.URISyntaxException; 68349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport java.security.InvalidParameterException; 69c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.ArrayList; 70dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohenimport java.util.Arrays; 7164359a53dc827797917a8d9a0697a91996789801Winson Chungimport java.util.Collection; 72c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.Collections; 73c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.Comparator; 74c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.HashMap; 75b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chungimport java.util.HashSet; 762abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chungimport java.util.Iterator; 77c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.List; 78f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport java.util.Map.Entry; 79b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chungimport java.util.Set; 80c2f801e770b4f80354b3edb722ec04222251990cMichael Jurka 8131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Maintains in-memory state of the Launcher. It is expected that there should be only one 8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * LauncherModel object held in a static. Also provide APIs for updating the database state 84bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project * for the Launcher. 8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 86ed13187a745866483139e2878037e1f8427ce567Kenny Guypublic class LauncherModel extends BroadcastReceiver 87c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy implements LauncherAppsCompat.OnAppsChangedCallbackCompat { 88a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato static final boolean DEBUG_LOADERS = false; 89ee52336a9ed0c98f78831a0e44b21f5a8d8c17d1Chris Wren private static final boolean DEBUG_RECEIVER = false; 909448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal private static final boolean REMOVE_UNRESTORED_ICONS = true; 91b358f813c93ac0d6c4f31058947efd16b188cd1eChris Wren 929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static final String TAG = "Launcher.Model"; 939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 94d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler public static final int LOADER_FLAG_NONE = 0; 95d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler public static final int LOADER_FLAG_CLEAR_WORKSPACE = 1 << 0; 96d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler public static final int LOADER_FLAG_MIGRATE_SHORTCUTS = 1 << 1; 97d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler 983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons 997aff399974c756930070d82d7b2df88f125dacd6Derek Prothro private static final long INVALID_SCREEN_ID = -1L; 100a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung 101091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final boolean mAppsCanBeOnRemoveableStorage; 102a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung private final boolean mOldContentProviderExists; 103dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 104091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final LauncherAppState mApp; 105091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final Object mLock = new Object(); 106091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk DeferredHandler mHandler = new DeferredHandler(); 107091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk LoaderTask mLoaderTask; 108091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk boolean mIsLoaderTaskRunning; 109756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal @Thunk boolean mHasLoaderCompletedOnce; 1109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 111bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk private static final String MIGRATE_AUTHORITY = "com.android.launcher2.settings"; 11281b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung 113091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); 114700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick static { 115700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick sWorkerThread.start(); 116700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick } 117091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper()); 118700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick 119cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // We start off with everything not loaded. After that, we assume that 120cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // our monitoring of the package manager provides all updates and we never 121cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // need to do a requery. These are only ever touched from the loader thread. 122091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk boolean mWorkspaceLoaded; 123091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk boolean mAllAppsLoaded; 124cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 125b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // When we are loading pages synchronously, we can't just post the binding of items on the side 126b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // pages as this delays the rotation process. Instead, we wait for a callback from the first 127b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // draw (in Workspace) to initiate the binding of the remaining side pages. Any time we start 128b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // a normal load, we also clear this set of Runnables. 129b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung static final ArrayList<Runnable> mDeferredBindRunnables = new ArrayList<Runnable>(); 130b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 131756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal /** 132756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal * Set of runnables to be called on the background thread after the workspace binding 133756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal * is complete. 134756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal */ 135756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal static final ArrayList<Runnable> mBindCompleteRunnables = new ArrayList<Runnable>(); 136756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal 137091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk WeakReference<Callbacks> mCallbacks; 1389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 139a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // < only access in worker thread > 1404caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen AllAppsList mBgAllAppsList; 1419110d485fa12c03df3061278717efb342f1142cfHyunyoung Song // Entire list of widgets. 1429110d485fa12c03df3061278717efb342f1142cfHyunyoung Song WidgetsModel mBgWidgetsModel; 143a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 144b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // The lock that must be acquired before referencing any static bg data structures. Unlike 145b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // other locks, this one can generally be held long-term because we never expect any of these 146b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // static data structures to be referenced outside of the worker thread except on the first 147b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // load after configuration change. 1482abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung static final Object sBgLock = new Object(); 149b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 150487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgItemsIdMap maps *all* the ItemInfos (shortcuts, folders, and widgets) created by 151a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // LauncherModel to their ids 152e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal static final LongArrayMap<ItemInfo> sBgItemsIdMap = new LongArrayMap<>(); 153a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 154487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgWorkspaceItems is passed to bindItems, which expects a list of all folders and shortcuts 155487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // created by LauncherModel that are directly on the home screen (however, no widgets or 156487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // shortcuts within folders). 157487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final ArrayList<ItemInfo> sBgWorkspaceItems = new ArrayList<ItemInfo>(); 1580589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 159487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgAppWidgets is all LauncherAppWidgetInfo created by LauncherModel. Passed to bindAppWidget() 160487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final ArrayList<LauncherAppWidgetInfo> sBgAppWidgets = 161a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka new ArrayList<LauncherAppWidgetInfo>(); 162a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 163487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgFolders is all FolderInfos created by LauncherModel. Passed to bindFolders() 164e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal static final LongArrayMap<FolderInfo> sBgFolders = new LongArrayMap<>(); 165b1094bd9630f659cc606853b8a244b6a6b6c6943Winson Chung 166dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // sBgWorkspaceScreens is the ordered set of workspace screens. 167dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen static final ArrayList<Long> sBgWorkspaceScreens = new ArrayList<Long>(); 168dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1695940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen // sBgWidgetProviders is the set of widget providers including custom internal widgets 17026ace12135a662ad864678c9fede9817e5c02b67Robin Lee public static HashMap<ComponentKey, LauncherAppWidgetProviderInfo> sBgWidgetProviders; 1715940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 172f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // sPendingPackages is a set of packages which could be on sdcard and are not available yet 173513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala static final HashMap<UserHandleCompat, HashSet<String>> sPendingPackages = 174513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala new HashMap<UserHandleCompat, HashSet<String>>(); 175f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 176a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // </ only access in worker thread > 177a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 178091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk IconCache mIconCache; 1799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 180091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final LauncherAppsCompat mLauncherApps; 181091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final UserManagerCompat mUserManager; 182ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public interface Callbacks { 184ef2efcff5e70e5900f4f10f9e46c3fa17c03b0ecJoe Onorato public boolean setLoadOnResume(); 1859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public int getCurrentWorkspaceScreen(); 1869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startBinding(); 18764359a53dc827797917a8d9a0697a91996789801Winson Chung public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end, 18864359a53dc827797917a8d9a0697a91996789801Winson Chung boolean forceAnimateIcons); 189dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void bindScreens(ArrayList<Long> orderedScreenIds); 19064359a53dc827797917a8d9a0697a91996789801Winson Chung public void bindAddScreens(ArrayList<Long> orderedScreenIds); 191e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal public void bindFolders(LongArrayMap<FolderInfo> folders); 19266cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal public void finishBindingItems(); 1939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAppWidget(LauncherAppWidgetInfo info); 194eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public void bindAllApplications(ArrayList<AppInfo> apps); 195d64d1763c590b1c954b759156683abf39ff22945Winson Chung public void bindAppsAdded(ArrayList<Long> newScreens, 196d64d1763c590b1c954b759156683abf39ff22945Winson Chung ArrayList<ItemInfo> addNotAnimated, 197c58497ee619416c4949b16eb43486c11618b69e5Winson Chung ArrayList<ItemInfo> addAnimated, 198c58497ee619416c4949b16eb43486c11618b69e5Winson Chung ArrayList<AppInfo> addedApps); 199eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public void bindAppsUpdated(ArrayList<AppInfo> apps); 2004390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated, 2014390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ArrayList<ShortcutInfo> removed, UserHandleCompat user); 2024390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets); 203756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public void bindRestoreItemsChange(HashSet<ItemInfo> updates); 20483892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung public void bindComponentsRemoved(ArrayList<String> packageNames, 2051a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal ArrayList<AppInfo> appInfos, UserHandleCompat user, int reason); 2062bd3d7d1cb5e4d8d826982d11b456739fed6b817Hyunyoung Song public void bindAllPackages(WidgetsModel model); 20788fa741e50760f9da78cba4a766172f23773bb87Winson Chung public void bindSearchProviderChanged(); 208a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung public boolean isAllAppsButtonRank(int rank); 2091462de39f01cec0ba785386532719cb0207dd827Adam Cohen public void onPageBoundSynchronously(int page); 210ede4129e77f8347e32c0da9c615bcff2cbc06fd8Winson Chung public void dumpLogsToLocalData(); 2119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21364359a53dc827797917a8d9a0697a91996789801Winson Chung public interface ItemInfoFilter { 21464359a53dc827797917a8d9a0697a91996789801Winson Chung public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn); 21564359a53dc827797917a8d9a0697a91996789801Winson Chung } 21664359a53dc827797917a8d9a0697a91996789801Winson Chung 2171307f63f8a93541bf6e2d29c11fab69778a25e42Bjorn Bringert LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) { 218a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung Context context = app.getContext(); 219e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler 220ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung mAppsCanBeOnRemoveableStorage = Environment.isExternalStorageRemovable(); 22171483f417bb19f524cda41081f5ccac6084dc103Adam Cohen String oldProvider = context.getString(R.string.old_launcher_provider_uri); 222bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk // This may be the same as MIGRATE_AUTHORITY, or it may be replaced by a different 223bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk // resource string. 224bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk String redirectAuthority = Uri.parse(oldProvider).getAuthority(); 225bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk ProviderInfo providerInfo = 226bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk context.getPackageManager().resolveContentProvider(MIGRATE_AUTHORITY, 0); 227bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk ProviderInfo redirectProvider = 228bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk context.getPackageManager().resolveContentProvider(redirectAuthority, 0); 22971483f417bb19f524cda41081f5ccac6084dc103Adam Cohen 23071483f417bb19f524cda41081f5ccac6084dc103Adam Cohen Log.d(TAG, "Old launcher provider: " + oldProvider); 231bbe1e24c5ff470a695510d23d67bcb6f2ad88d0eJason Monk mOldContentProviderExists = (providerInfo != null) && (redirectProvider != null); 23271483f417bb19f524cda41081f5ccac6084dc103Adam Cohen 23371483f417bb19f524cda41081f5ccac6084dc103Adam Cohen if (mOldContentProviderExists) { 23471483f417bb19f524cda41081f5ccac6084dc103Adam Cohen Log.d(TAG, "Old launcher provider exists."); 23571483f417bb19f524cda41081f5ccac6084dc103Adam Cohen } else { 23671483f417bb19f524cda41081f5ccac6084dc103Adam Cohen Log.d(TAG, "Old launcher provider does not exist."); 23771483f417bb19f524cda41081f5ccac6084dc103Adam Cohen } 23871483f417bb19f524cda41081f5ccac6084dc103Adam Cohen 239e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mApp = app; 2401307f63f8a93541bf6e2d29c11fab69778a25e42Bjorn Bringert mBgAllAppsList = new AllAppsList(iconCache, appFilter); 241eaf291b9feba4e332d258b6d53ff119c88dc0d39Hyunyoung Song mBgWidgetsModel = new WidgetsModel(context, iconCache, appFilter); 2420589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = iconCache; 2430589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 244ed13187a745866483139e2878037e1f8427ce567Kenny Guy mLauncherApps = LauncherAppsCompat.getInstance(context); 245ed13187a745866483139e2878037e1f8427ce567Kenny Guy mUserManager = UserManagerCompat.getInstance(context); 2460589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 2470589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 248b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Runs the specified runnable immediately if called from the main thread, otherwise it is 249b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * posted on the main thread handler. */ 250091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void runOnMainThread(Runnable r) { 251b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 252b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we are on the worker thread, post onto the main handler 253b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mHandler.post(r); 254b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 255b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r.run(); 256b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 257b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 258b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 259b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Runs the specified runnable immediately if called from the worker thread, otherwise it is 260b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * posted on the worker thread handler. */ 261639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal @Thunk static void runOnWorkerThread(Runnable r) { 262b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 263b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r.run(); 264b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 265b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we are not on the worker thread, then post to the worker handler 266b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorker.post(r); 267b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 268b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 269b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 270e43a1e788223ab5a4405c5eeb0133ff57efbc768Winson Chung boolean canMigrateFromOldLauncherDb(Launcher launcher) { 271e43a1e788223ab5a4405c5eeb0133ff57efbc768Winson Chung return mOldContentProviderExists && !launcher.isLauncherPreinstalled() ; 272a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung } 273a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung 274756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public void setPackageState(final PackageInstallInfo installInfo) { 275756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Runnable updateRunnable = new Runnable() { 276756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 277756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal @Override 278aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren public void run() { 279756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal synchronized (sBgLock) { 280756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal final HashSet<ItemInfo> updates = new HashSet<>(); 281756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 282756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) { 283756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // Ignore install success events as they are handled by Package add events. 284756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal return; 285756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 286756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 287e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo info : sBgItemsIdMap) { 288756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (info instanceof ShortcutInfo) { 289756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal ShortcutInfo si = (ShortcutInfo) info; 290756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal ComponentName cn = si.getTargetComponent(); 291756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (si.isPromise() && (cn != null) 292756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal && installInfo.packageName.equals(cn.getPackageName())) { 293756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.setInstallProgress(installInfo.progress); 294756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 295756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (installInfo.state == PackageInstallerCompat.STATUS_FAILED) { 296756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // Mark this info as broken. 297756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE; 298756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 299756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal updates.add(si); 300756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 301756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 302756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 303756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 304756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal for (LauncherAppWidgetInfo widget : sBgAppWidgets) { 305756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (widget.providerName.getPackageName().equals(installInfo.packageName)) { 306756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal widget.installProgress = installInfo.progress; 307756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal updates.add(widget); 308756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 309756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 310756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 311756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (!updates.isEmpty()) { 312756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // Push changes to the callback. 313756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Runnable r = new Runnable() { 314756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public void run() { 315756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Callbacks callbacks = getCallback(); 316756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (callbacks != null) { 317756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal callbacks.bindRestoreItemsChange(updates); 318756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 319756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 320756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal }; 321756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal mHandler.post(r); 322756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 323aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } 324aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } 325aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren }; 326756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal runOnWorkerThread(updateRunnable); 327aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } 328aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren 329756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal /** 330756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal * Updates the icons and label of all pending icons for the provided package name. 331756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal */ 332756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public void updateSessionDisplayInfo(final String packageName) { 333756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Runnable updateRunnable = new Runnable() { 334756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 335756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal @Override 336a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal public void run() { 337756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal synchronized (sBgLock) { 338756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal final ArrayList<ShortcutInfo> updates = new ArrayList<>(); 339756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal final UserHandleCompat user = UserHandleCompat.myUserHandle(); 340756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 341e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo info : sBgItemsIdMap) { 342756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (info instanceof ShortcutInfo) { 343756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal ShortcutInfo si = (ShortcutInfo) info; 344756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal ComponentName cn = si.getTargetComponent(); 345756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (si.isPromise() && (cn != null) 346756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal && packageName.equals(cn.getPackageName())) { 347756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) { 348756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // For auto install apps update the icon as well as label. 349756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal mIconCache.getTitleAndIcon(si, 350756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.promisedIntent, user, 351756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.shouldUseLowResIcon()); 352756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } else { 353756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // Only update the icon for restored apps. 354756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.updateIcon(mIconCache); 355756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 356756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal updates.add(si); 357756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 358756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 359756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 360756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 361756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (!updates.isEmpty()) { 362756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // Push changes to the callback. 363756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Runnable r = new Runnable() { 364756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public void run() { 365756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Callbacks callbacks = getCallback(); 366756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (callbacks != null) { 367756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal callbacks.bindShortcutsChanged(updates, 368756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal new ArrayList<ShortcutInfo>(), user); 369756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 370756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 371756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal }; 372756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal mHandler.post(r); 373756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 374a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 375a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 376a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal }; 377756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal runOnWorkerThread(updateRunnable); 378a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 379a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal 38076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void addAppsToAllApps(final Context ctx, final ArrayList<AppInfo> allAppsApps) { 381e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final Callbacks callbacks = getCallback(); 38276a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 38376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (allAppsApps == null) { 38476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen throw new RuntimeException("allAppsApps must not be null"); 38576a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 38676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (allAppsApps.isEmpty()) { 38776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen return; 38876a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 38976a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 39076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen // Process the newly added applications and add them to the database first 39176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen Runnable r = new Runnable() { 39276a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void run() { 39376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen runOnMainThread(new Runnable() { 39476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void run() { 395e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 39676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (callbacks == cb && cb != null) { 3976d0dde01f307051ee1849481c989d9e87774b894Chris Wren callbacks.bindAppsAdded(null, null, null, allAppsApps); 39876a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 39976a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 40076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen }); 40176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 40276a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen }; 40376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen runOnWorkerThread(r); 404997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 40576a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 406a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal private static boolean findNextAvailableIconSpaceInScreen(ArrayList<ItemInfo> occupiedPos, 40771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] xy, int spanX, int spanY) { 40871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherAppState app = LauncherAppState.getInstance(); 4092e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); 4102e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen final int xCount = (int) profile.numColumns; 4112e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen final int yCount = (int) profile.numRows; 41271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal boolean[][] occupied = new boolean[xCount][yCount]; 41371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (occupiedPos != null) { 414a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal for (ItemInfo r : occupiedPos) { 415a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal int right = r.cellX + r.spanX; 416a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal int bottom = r.cellY + r.spanY; 417a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal for (int x = r.cellX; 0 <= x && x < right && x < xCount; x++) { 418a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal for (int y = r.cellY; 0 <= y && y < bottom && y < yCount; y++) { 41971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal occupied[x][y] = true; 42071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 42171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 42271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 42371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 424f7a29e83f06909b378dba39c83a522375682710aSunny Goyal return Utilities.findVacantCell(xy, spanX, spanY, xCount, yCount, occupied); 42571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 42671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 42771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal /** 42871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * Find a position on the screen for the given size or adds a new screen. 42971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * @return screenId and the coordinates for the item. 43071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal */ 431756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal @Thunk Pair<Long, int[]> findSpaceForItem( 43271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal Context context, 43371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal ArrayList<Long> workspaceScreens, 43471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal ArrayList<Long> addedWorkspaceScreensFinal, 43571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int spanX, int spanY) { 436a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal LongSparseArray<ArrayList<ItemInfo>> screenItems = new LongSparseArray<>(); 437a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal 438a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal // Use sBgItemsIdMap as all the items are already loaded. 439756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal assertWorkspaceLoaded(); 440a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal synchronized (sBgLock) { 441a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal for (ItemInfo info : sBgItemsIdMap) { 442a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { 443a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal ArrayList<ItemInfo> items = screenItems.get(info.screenId); 444a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal if (items == null) { 445a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal items = new ArrayList<>(); 446a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal screenItems.put(info.screenId, items); 447a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal } 448a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal items.add(info); 44971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 45071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 45171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 45271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 45371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Find appropriate space for the item. 45471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal long screenId = 0; 45571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] cordinates = new int[2]; 45671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal boolean found = false; 45771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 45871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int screenCount = workspaceScreens.size(); 45971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // First check the preferred screen. 460a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal int preferredScreenIndex = workspaceScreens.isEmpty() ? 0 : 1; 46171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (preferredScreenIndex < screenCount) { 46271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId = workspaceScreens.get(preferredScreenIndex); 46371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal found = findNextAvailableIconSpaceInScreen( 46471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY); 46571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 46671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 46771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!found) { 468a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal // Search on any of the screens starting from the first screen. 469a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal for (int screen = 1; screen < screenCount; screen++) { 47071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId = workspaceScreens.get(screen); 47171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (findNextAvailableIconSpaceInScreen( 47271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY)) { 47371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // We found a space for it 47471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal found = true; 47571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal break; 47671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 47771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 47871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 47971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 48071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!found) { 48171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Still no position found. Add a new screen to the end. 48271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId = LauncherAppState.getLauncherProvider().generateNewScreenId(); 48371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 48471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Save the screen id for binding in the workspace 48571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal workspaceScreens.add(screenId); 48671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal addedWorkspaceScreensFinal.add(screenId); 48776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 48871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // If we still can't find an empty space, then God help us all!!! 48971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!findNextAvailableIconSpaceInScreen( 49071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY)) { 49171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal throw new RuntimeException("Can't find space to add the item"); 49271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 493fe9d96a39651de99819208e95c7ec7d432a402e0Winson Chung } 49471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal return Pair.create(screenId, cordinates); 49571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 49671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 49771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal /** 49871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * Adds the provided items to the workspace. 49971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal */ 50018bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal public void addAndBindAddedWorkspaceItems(final Context context, 501a214a63bfe365a0e81bc3082d56896c6df24d0b4Sunny Goyal final ArrayList<? extends ItemInfo> workspaceApps) { 50271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final Callbacks callbacks = getCallback(); 50376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (workspaceApps.isEmpty()) { 5049e6a0a20d40675ef98c7fdb8892cf34b90152f7aWinson Chung return; 505997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 50664359a53dc827797917a8d9a0697a91996789801Winson Chung // Process the newly added applications and add them to the database first 50764359a53dc827797917a8d9a0697a91996789801Winson Chung Runnable r = new Runnable() { 50864359a53dc827797917a8d9a0697a91996789801Winson Chung public void run() { 50964359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>(); 51064359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>(); 51164359a53dc827797917a8d9a0697a91996789801Winson Chung 51276828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // Get the list of workspace screens. We need to append to this list and 51376828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // can not use sBgWorkspaceScreens because loadWorkspace() may not have been 51476828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // called. 515c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal ArrayList<Long> workspaceScreens = loadWorkspaceScreensDb(context); 51664359a53dc827797917a8d9a0697a91996789801Winson Chung synchronized(sBgLock) { 51771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal for (ItemInfo item : workspaceApps) { 518a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal if (item instanceof ShortcutInfo) { 51971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Short-circuit this logic if the icon exists somewhere on the workspace 520756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (shortcutExists(context, item.getIntent(), item.user)) { 52171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal continue; 522c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 52364359a53dc827797917a8d9a0697a91996789801Winson Chung } 52464359a53dc827797917a8d9a0697a91996789801Winson Chung 52571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Find appropriate space for the item. 526a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal Pair<Long, int[]> coords = findSpaceForItem(context, 527a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal workspaceScreens, addedWorkspaceScreensFinal, 52871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 1, 1); 52971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal long screenId = coords.first; 53071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] cordinates = coords.second; 53171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 53218bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal ItemInfo itemInfo; 53318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal if (item instanceof ShortcutInfo || item instanceof FolderInfo) { 53418bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal itemInfo = item; 53571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } else if (item instanceof AppInfo) { 53618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal itemInfo = ((AppInfo) item).makeShortcut(); 537997a92348a6d6e061737399321393449c16cd4d8Winson Chung } else { 538997a92348a6d6e061737399321393449c16cd4d8Winson Chung throw new RuntimeException("Unexpected info type"); 539997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 54094d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung 54164359a53dc827797917a8d9a0697a91996789801Winson Chung // Add the shortcut to the db 54218bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal addItemToDatabase(context, itemInfo, 54364359a53dc827797917a8d9a0697a91996789801Winson Chung LauncherSettings.Favorites.CONTAINER_DESKTOP, 5441d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal screenId, cordinates[0], cordinates[1]); 54564359a53dc827797917a8d9a0697a91996789801Winson Chung // Save the ShortcutInfo for binding in the workspace 54618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal addedShortcutsFinal.add(itemInfo); 54764359a53dc827797917a8d9a0697a91996789801Winson Chung } 54864359a53dc827797917a8d9a0697a91996789801Winson Chung } 54964359a53dc827797917a8d9a0697a91996789801Winson Chung 55076828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // Update the workspace screens 55176828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung updateWorkspaceScreenOrder(context, workspaceScreens); 55276828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 55376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (!addedShortcutsFinal.isEmpty()) { 554997a92348a6d6e061737399321393449c16cd4d8Winson Chung runOnMainThread(new Runnable() { 555997a92348a6d6e061737399321393449c16cd4d8Winson Chung public void run() { 556e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 557997a92348a6d6e061737399321393449c16cd4d8Winson Chung if (callbacks == cb && cb != null) { 558997a92348a6d6e061737399321393449c16cd4d8Winson Chung final ArrayList<ItemInfo> addAnimated = new ArrayList<ItemInfo>(); 559997a92348a6d6e061737399321393449c16cd4d8Winson Chung final ArrayList<ItemInfo> addNotAnimated = new ArrayList<ItemInfo>(); 56094d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung if (!addedShortcutsFinal.isEmpty()) { 56194d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung ItemInfo info = addedShortcutsFinal.get(addedShortcutsFinal.size() - 1); 56294d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung long lastScreenId = info.screenId; 56394d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung for (ItemInfo i : addedShortcutsFinal) { 56494d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung if (i.screenId == lastScreenId) { 56594d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung addAnimated.add(i); 56694d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung } else { 56794d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung addNotAnimated.add(i); 56894d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung } 569997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 570997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 571d64d1763c590b1c954b759156683abf39ff22945Winson Chung callbacks.bindAppsAdded(addedWorkspaceScreensFinal, 57276a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen addNotAnimated, addAnimated, null); 573997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 57464359a53dc827797917a8d9a0697a91996789801Winson Chung } 575997a92348a6d6e061737399321393449c16cd4d8Winson Chung }); 576997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 57764359a53dc827797917a8d9a0697a91996789801Winson Chung } 57864359a53dc827797917a8d9a0697a91996789801Winson Chung }; 57964359a53dc827797917a8d9a0697a91996789801Winson Chung runOnWorkerThread(r); 58064359a53dc827797917a8d9a0697a91996789801Winson Chung } 58164359a53dc827797917a8d9a0697a91996789801Winson Chung 582d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal private void unbindItemInfosAndClearQueuedBindRunnables() { 58381b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 58481b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung throw new RuntimeException("Expected unbindLauncherItemInfos() to be called from the " + 58581b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung "main thread"); 58681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung } 58781b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung 58881b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Clear any deferred bind runnables 589a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 590a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.clear(); 591a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 592d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal 593d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal // Remove any queued UI runnables 594d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal mHandler.cancelAll(); 59581b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung // Unbind all the workspace items 59681b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung unbindWorkspaceItemsOnMainThread(); 597603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung } 598603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung 599b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Unbinds all the sBgWorkspaceItems and sBgAppWidgets on the main thread */ 60081b52252796625dcbadc9f8b908f8d8a284565c0Winson Chung void unbindWorkspaceItemsOnMainThread() { 601603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung // Ensure that we don't use the same workspace items data structure on the main thread 602603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung // by making a copy of workspace items first. 603d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal final ArrayList<ItemInfo> tmpItems = new ArrayList<ItemInfo>(); 6042abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 605d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal tmpItems.addAll(sBgWorkspaceItems); 606d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal tmpItems.addAll(sBgAppWidgets); 607b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 608b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Runnable r = new Runnable() { 609b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 610b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 611d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal for (ItemInfo item : tmpItems) { 612b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.unbind(); 613b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 614b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 615b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 616b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnMainThread(r); 6174eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen } 6184eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen 6199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 6209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Adds an item to the DB if it was not created previously, or move it to a new 6219c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * <container, screen, cellX, cellY> 6229c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 6239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container, 624dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId, int cellX, int cellY) { 6259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (item.container == ItemInfo.NO_ID) { 6269c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From all apps 6271d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal addItemToDatabase(context, item, container, screenId, cellX, cellY); 6289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 6299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From somewhere else 630dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen moveItemInDatabase(context, item, container, screenId, cellX, cellY); 6319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 6329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 63331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 634b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka static void checkItemInfoLocked( 635b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka final long itemId, final ItemInfo item, StackTraceElement[] stackTrace) { 636b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ItemInfo modelItem = sBgItemsIdMap.get(itemId); 637b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelItem != null && item != modelItem) { 638b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // check all the data is consistent 639b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) { 640b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ShortcutInfo modelShortcut = (ShortcutInfo) modelItem; 641b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ShortcutInfo shortcut = (ShortcutInfo) item; 642b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelShortcut.title.toString().equals(shortcut.title.toString()) && 643b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.intent.filterEquals(shortcut.intent) && 644b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.id == shortcut.id && 645b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.itemType == shortcut.itemType && 646b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.container == shortcut.container && 647dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen modelShortcut.screenId == shortcut.screenId && 648b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.cellX == shortcut.cellX && 649b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.cellY == shortcut.cellY && 650b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.spanX == shortcut.spanX && 651b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.spanY == shortcut.spanY && 652b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ((modelShortcut.dropPos == null && shortcut.dropPos == null) || 653b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka (modelShortcut.dropPos != null && 654b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka shortcut.dropPos != null && 655b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.dropPos[0] == shortcut.dropPos[0] && 656b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.dropPos[1] == shortcut.dropPos[1]))) { 657b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // For all intents and purposes, this is the same object 658b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka return; 659b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 660b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 661b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka 662b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // the modelItem needs to match up perfectly with item if our model is 663b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // to be consistent with the database-- for now, just require 664b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // modelItem == item or the equality check above 665b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka String msg = "item: " + ((item != null) ? item.toString() : "null") + 666b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka "modelItem: " + 667b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ((modelItem != null) ? modelItem.toString() : "null") + 668b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka "Error: ItemInfo passed to checkItemInfo doesn't match original"; 669b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka RuntimeException e = new RuntimeException(msg); 670b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (stackTrace != null) { 671b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka e.setStackTrace(stackTrace); 672b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 673b9ada65af30c61c5b35da9b9efac75ffe6c56fd7Adam Cohen throw e; 674b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 675b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 676b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka 677816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka static void checkItemInfo(final ItemInfo item) { 678816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 679816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka final long itemId = item.id; 680816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka Runnable r = new Runnable() { 681b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka public void run() { 682b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka synchronized (sBgLock) { 683b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka checkItemInfoLocked(itemId, item, stackTrace); 684816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka } 685b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 686b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka }; 687b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 688816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka } 689816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka 690c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka static void updateItemInDatabaseHelper(Context context, final ContentValues values, 691c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ItemInfo item, final String callingFunction) { 692c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final long itemId = item.id; 6931d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final Uri uri = LauncherSettings.Favorites.getContentUri(itemId); 694c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ContentResolver cr = context.getContentResolver(); 695c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 696487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 697c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 698c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka public void run() { 699c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.update(uri, values, null, null); 700f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemArrays(item, itemId, stackTrace); 701f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 702f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen }; 703f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen runOnWorkerThread(r); 704f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 705c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 706f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void updateItemsInDatabaseHelper(Context context, final ArrayList<ContentValues> valuesList, 707f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ArrayList<ItemInfo> items, final String callingFunction) { 708f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ContentResolver cr = context.getContentResolver(); 709c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 710f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 711f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Runnable r = new Runnable() { 712f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen public void run() { 713f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ContentProviderOperation> ops = 714f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen new ArrayList<ContentProviderOperation>(); 715f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int count = items.size(); 716f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < count; i++) { 717f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo item = items.get(i); 718f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final long itemId = item.id; 7191d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final Uri uri = LauncherSettings.Favorites.getContentUri(itemId); 720f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ContentValues values = valuesList.get(i); 721f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 722f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build()); 723f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemArrays(item, itemId, stackTrace); 724487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen 725f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 726f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen try { 727f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen cr.applyBatch(LauncherProvider.AUTHORITY, ops); 728f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } catch (Exception e) { 729f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen e.printStackTrace(); 730c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 731c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 732c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 733b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 734c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 735bebf042666cffe52039b875a549a582abd78a431Adam Cohen 736f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void updateItemArrays(ItemInfo item, long itemId, StackTraceElement[] stackTrace) { 737f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Lock on mBgLock *after* the db operation 738f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen synchronized (sBgLock) { 739f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen checkItemInfoLocked(itemId, item, stackTrace); 740f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 741f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP && 742f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 743f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Item is in a folder, make sure this folder exists 744f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (!sBgFolders.containsKey(item.container)) { 745f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // An items container is being set to a that of an item which is not in 746f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // the list of Folders. 747f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen String msg = "item: " + item + " container being set to: " + 748f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container + ", not in the list of folders"; 749f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Log.e(TAG, msg); 750f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 751f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 752f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 753f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Items are added/removed from the corresponding FolderInfo elsewhere, such 754f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // as in Workspace.onDrop. Here, we just add/remove them from the list of items 755f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // that are on the desktop, as appropriate 756f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo modelItem = sBgItemsIdMap.get(itemId); 75733231f587e1a6f716af68e6198df774d2847a8e5Winson Chung if (modelItem != null && 75833231f587e1a6f716af68e6198df774d2847a8e5Winson Chung (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || 75933231f587e1a6f716af68e6198df774d2847a8e5Winson Chung modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT)) { 760f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen switch (modelItem.itemType) { 761f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 762f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 763f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 764f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (!sBgWorkspaceItems.contains(modelItem)) { 765f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen sBgWorkspaceItems.add(modelItem); 766f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 767f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen break; 768f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen default: 769f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen break; 770f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 771f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } else { 772f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen sBgWorkspaceItems.remove(modelItem); 773f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 774f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 775f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 776f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 7779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 7789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Move an item in the DB to a new <container, screen, cellX, cellY> 7799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 78083a8f042adda926489494dff217c15ab696139b4Sunny Goyal public static void moveItemInDatabase(Context context, final ItemInfo item, final long container, 781dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY) { 7829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 7839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 7849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 785c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 7863d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // We store hotseat items in canonical form which is this orientation invariant position 7873d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // in the hotseat 788dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 7893d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 790dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 7913d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } else { 792dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 7933d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } 79431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7959c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 7969c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CONTAINER, item.container); 7973d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung values.put(LauncherSettings.Favorites.CELLX, item.cellX); 7983d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung values.put(LauncherSettings.Favorites.CELLY, item.cellY); 79908f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal values.put(LauncherSettings.Favorites.RANK, item.rank); 800dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 801ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 802c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka updateItemInDatabaseHelper(context, values, item, "moveItemInDatabase"); 80331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 80431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 80531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 806f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen * Move items in the DB to a new <container, screen, cellX, cellY>. We assume that the 807f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen * cellX, cellY have already been updated on the ItemInfos. 808f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen */ 809f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void moveItemsInDatabase(Context context, final ArrayList<ItemInfo> items, 810f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final long container, final int screen) { 811f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 812f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ContentValues> contentValues = new ArrayList<ContentValues>(); 813f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int count = items.size(); 814f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 815f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < count; i++) { 816f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo item = items.get(i); 817f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container = container; 818f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 819f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // We store hotseat items in canonical form which is this orientation invariant position 820f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // in the hotseat 821f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (context instanceof Launcher && screen < 0 && 822f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 823dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(item.cellX, 824f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.cellY); 825f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } else { 826dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screen; 827f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 828f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 829f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ContentValues values = new ContentValues(); 830f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CONTAINER, item.container); 831f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CELLX, item.cellX); 832f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 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); 835f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 836f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen contentValues.add(values); 837f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 838f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemsInDatabaseHelper(context, contentValues, items, "moveItemInDatabase"); 839f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 840f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 841f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen /** 842bebf042666cffe52039b875a549a582abd78a431Adam Cohen * Move and/or resize item in the DB to a new <container, screen, cellX, cellY, spanX, spanY> 843d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen */ 844bebf042666cffe52039b875a549a582abd78a431Adam Cohen static void modifyItemInDatabase(Context context, final ItemInfo item, final long container, 845dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY, final int spanX, final int spanY) { 8460f84a604563037ea65883b99d30e7ff802d986c2Winson Chung item.container = container; 847d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen item.cellX = cellX; 848d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen item.cellY = cellY; 849bebf042666cffe52039b875a549a582abd78a431Adam Cohen item.spanX = spanX; 850bebf042666cffe52039b875a549a582abd78a431Adam Cohen item.spanY = spanY; 851bebf042666cffe52039b875a549a582abd78a431Adam Cohen 852bebf042666cffe52039b875a549a582abd78a431Adam Cohen // We store hotseat items in canonical form which is this orientation invariant position 853bebf042666cffe52039b875a549a582abd78a431Adam Cohen // in the hotseat 854dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 855bebf042666cffe52039b875a549a582abd78a431Adam Cohen container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 856dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 857bebf042666cffe52039b875a549a582abd78a431Adam Cohen } else { 858dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 859bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 860d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 861d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen final ContentValues values = new ContentValues(); 862d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen values.put(LauncherSettings.Favorites.CONTAINER, item.container); 863bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.CELLX, item.cellX); 864bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.CELLY, item.cellY); 86508f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal values.put(LauncherSettings.Favorites.RANK, item.rank); 866bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.SPANX, item.spanX); 867bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.SPANY, item.spanY); 868dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 869d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 870816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka updateItemInDatabaseHelper(context, values, item, "modifyItemInDatabase"); 871bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 872c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 873c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka /** 874c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * Update an item to the database in a specified container. 875c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka */ 87683a8f042adda926489494dff217c15ab696139b4Sunny Goyal public static void updateItemInDatabase(Context context, final ItemInfo item) { 877c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ContentValues values = new ContentValues(); 878ed13187a745866483139e2878037e1f8427ce567Kenny Guy item.onAddToDatabase(context, values); 879c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka updateItemInDatabaseHelper(context, values, item, "updateItemInDatabase"); 880d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 881d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 882756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal private void assertWorkspaceLoaded() { 883639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal if (LauncherAppState.isDogfoodBuild()) { 884639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal synchronized (mLock) { 885639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal if (!mHasLoaderCompletedOnce || 886639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal (mLoaderTask != null && mLoaderTask.mIsLoadingAndBindingWorkspace)) { 887639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal throw new RuntimeException("Trying to add shortcut while loader is running"); 888639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 889639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 890756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal } 891756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal } 892756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal 893d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen /** 894756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal * Returns true if the shortcuts already exists on the workspace. This must be called after 895756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal * the workspace has been loaded. We identify a shortcut by its intent. 896bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project */ 897756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal @Thunk boolean shortcutExists(Context context, Intent intent, UserHandleCompat user) { 898756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal assertWorkspaceLoaded(); 899dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal final String intentWithPkg, intentWithoutPkg; 9002a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal if (intent.getComponent() != null) { 9012a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal // If component is not null, an intent with null package will produce 9022a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal // the same result and should also be a match. 9034e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal String packageName = intent.getComponent().getPackageName(); 9042a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal if (intent.getPackage() != null) { 905dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithPkg = intent.toUri(0); 906dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithoutPkg = new Intent(intent).setPackage(null).toUri(0); 9072a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } else { 908dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithPkg = new Intent(intent).setPackage(packageName).toUri(0); 909dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithoutPkg = intent.toUri(0); 9102a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } 9112a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } else { 912dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithPkg = intent.toUri(0); 913dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithoutPkg = intent.toUri(0); 9142a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } 915756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 916756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal synchronized (sBgLock) { 917e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo item : sBgItemsIdMap) { 918756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (item instanceof ShortcutInfo) { 919756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal ShortcutInfo info = (ShortcutInfo) item; 9204e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal Intent targetIntent = info.promisedIntent == null 9214e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal ? info.intent : info.promisedIntent; 9224e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (targetIntent != null && info.user.equals(user)) { 9234e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal String s = targetIntent.toUri(0); 924dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal if (intentWithPkg.equals(s) || intentWithoutPkg.equals(s)) { 925dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal return true; 926dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal } 927756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 928756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 929756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 9309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 931756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal return false; 932bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project } 933bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 934bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project /** 9359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList. 93631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 937e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal FolderInfo getFolderById(Context context, LongArrayMap<FolderInfo> folderList, long id) { 9389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 9399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null, 9409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato "_id=? and (itemType=? or itemType=?)", 9419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato new String[] { String.valueOf(id), 942df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_FOLDER)}, null); 943f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 9449c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato try { 9459c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (c.moveToFirst()) { 9469c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); 9479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int titleIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.TITLE); 9489c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); 9499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); 9509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); 9519c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); 9525d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal final int optionsIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.OPTIONS); 953f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 9549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = null; 9559c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato switch (c.getInt(itemTypeIndex)) { 956df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 957df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen folderInfo = findOrMakeFolder(folderList, id); 9589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 9599c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 96031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 961a508e4f804c2bddf9e2cdfa3d0bd4a8202ff2151Sunny Goyal // Do not trim the folder label, as is was set by the user. 962a508e4f804c2bddf9e2cdfa3d0bd4a8202ff2151Sunny Goyal folderInfo.title = c.getString(titleIndex); 9639c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.id = id; 9649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folderInfo.container = c.getInt(containerIndex); 965dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen folderInfo.screenId = c.getInt(screenIndex); 966d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen folderInfo.cellX = c.getInt(cellXIndex); 967d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen folderInfo.cellY = c.getInt(cellYIndex); 9685d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal folderInfo.options = c.getInt(optionsIndex); 969ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 9709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return folderInfo; 9719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 9729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } finally { 9739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato c.close(); 9742fcbd686d1c2a9a9e520116a541c9caae0c2dc60Romain Guy } 975ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 9769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 9779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 97831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 9809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Add an item to the database in a specified container. Sets the container, screen, cellX and 9819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * cellY fields of the item. Also assigns an ID to the item. 9829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 98318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal public static void addItemToDatabase(Context context, final ItemInfo item, final long container, 9841d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final long screenId, final int cellX, final int cellY) { 9859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 9869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 9879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 9883d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // We store hotseat items in canonical form which is this orientation invariant position 9893d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // in the hotseat 990dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 9913d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 992dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); 9933d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } else { 994dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 9953d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } 996ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 9979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 9989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 999ed13187a745866483139e2878037e1f8427ce567Kenny Guy item.onAddToDatabase(context, values); 1000ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 1001414300a79d140f8c2c8760d9adab750f69ffeafdMichael Jurka item.id = LauncherAppState.getLauncherProvider().generateNewItemId(); 1002a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka values.put(LauncherSettings.Favorites._ID, item.id); 1003aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 10048e19cf22a4ab86f982b08e7d10b86ea7be56acccJason Monk final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 1005c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 1006a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka public void run() { 10071d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal cr.insert(LauncherSettings.Favorites.CONTENT_URI, values); 1008ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 1009b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 10102abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 10118e19cf22a4ab86f982b08e7d10b86ea7be56acccJason Monk checkItemInfoLocked(item.id, item, stackTrace); 1012b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(item.id, item); 1013b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (item.itemType) { 1014b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 1015b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.put(item.id, (FolderInfo) item); 1016b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Fall through 1017b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1018b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1019b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || 1020b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1021b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(item); 1022b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1023b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!sBgFolders.containsKey(item.container)) { 1024b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Adding an item to a folder that doesn't exist. 1025b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String msg = "adding item: " + item + " to a folder that " + 1026b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung " doesn't exist"; 102728b3e10fdea4d719b46d2e0da9a916bacc238fd1Adam Cohen Log.e(TAG, msg); 1028b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1029487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 1030b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1031b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 1032b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.add((LauncherAppWidgetInfo) item); 1033b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 1034b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1035a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 1036a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 1037c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 1038b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 103931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 104031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1042aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * Creates a new unique child id, for a given cell span across all layouts. 1043aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung */ 1044845ba3b17b83a2b11d79c6fb076cf96ab4a737dfMichael Jurka static int getCellLayoutChildId( 1045dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long container, long screen, int localCellX, int localCellY, int spanX, int spanY) { 10463d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung return (((int) container & 0xFF) << 24) 1047dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen | ((int) screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF); 1048aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 1049aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1050349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal private static ArrayList<ItemInfo> getItemsByPackageName( 1051349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal final String pn, final UserHandleCompat user) { 1052e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal ItemInfoFilter filter = new ItemInfoFilter() { 1053e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal @Override 1054e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn) { 1055e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return cn.getPackageName().equals(pn) && info.user.equals(user); 1056e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1057e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal }; 1058e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal return filterItemInfos(sBgItemsIdMap, filter); 1059349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1060349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 1061349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal /** 1062349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal * Removes all the items from the database corresponding to the specified package. 1063349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal */ 1064349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal static void deletePackageFromDatabase(Context context, final String pn, 1065349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal final UserHandleCompat user) { 1066349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal deleteItemsFromDatabase(context, getItemsByPackageName(pn, user)); 1067e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1068e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 1069e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal /** 1070c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * Removes the specified item from the database 1071c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * @param context 1072c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * @param item 10739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1074fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal public static void deleteItemFromDatabase(Context context, final ItemInfo item) { 1075e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal ArrayList<ItemInfo> items = new ArrayList<ItemInfo>(); 1076e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal items.add(item); 1077e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal deleteItemsFromDatabase(context, items); 1078e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1079e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 1080e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal /** 1081e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal * Removes the specified items from the database 1082e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal * @param context 1083e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal * @param item 1084e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal */ 10854390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal static void deleteItemsFromDatabase(Context context, final ArrayList<? extends ItemInfo> items) { 10869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 108783df188ce0822f4058406e5f2878d1cf34bf413eMichael Jurka Runnable r = new Runnable() { 1088a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka public void run() { 1089e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal for (ItemInfo item : items) { 10901d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final Uri uri = LauncherSettings.Favorites.getContentUri(item.id); 1091e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal cr.delete(uri, null, null); 1092b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1093e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // Lock on mBgLock *after* the db operation 1094e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal synchronized (sBgLock) { 1095e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal switch (item.itemType) { 1096e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 1097e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgFolders.remove(item.id); 1098e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo info: sBgItemsIdMap) { 1099e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal if (info.container == item.id) { 1100e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // We are deleting a folder which still contains items that 1101e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // think they are contained by that folder. 1102e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal String msg = "deleting a folder (" + item + ") which still " + 1103e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal "contains items (" + info + ")"; 1104e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal Log.e(TAG, msg); 1105e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1106b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1107e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgWorkspaceItems.remove(item); 1108e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1109e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1110e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1111e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgWorkspaceItems.remove(item); 1112e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1113e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 1114e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgAppWidgets.remove((LauncherAppWidgetInfo) item); 1115e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1116e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1117e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgItemsIdMap.remove(item.id); 1118b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1119a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 1120a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 112183df188ce0822f4058406e5f2878d1cf34bf413eMichael Jurka }; 1122b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 112331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 112431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1126dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen * Update the order of the workspace screens in the database. The array list contains 1127dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen * a list of screen ids in the order that they should appear. 1128dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen */ 1129e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal public void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) { 113064359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<Long> screensCopy = new ArrayList<Long>(screens); 1131dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ContentResolver cr = context.getContentResolver(); 1132dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI; 1133dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1134dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Remove any negative screen ids -- these aren't persisted 113564359a53dc827797917a8d9a0697a91996789801Winson Chung Iterator<Long> iter = screensCopy.iterator(); 1136dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen while (iter.hasNext()) { 1137dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long id = iter.next(); 1138dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (id < 0) { 1139dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen iter.remove(); 1140dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1141dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1142dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1143dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Runnable r = new Runnable() { 1144dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen @Override 1145dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void run() { 1146085c853a5702c45865e9b017d21fa15cf2b151b9Yura ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 1147dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Clear the table 1148085c853a5702c45865e9b017d21fa15cf2b151b9Yura ops.add(ContentProviderOperation.newDelete(uri).build()); 114976828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung int count = screensCopy.size(); 1150dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (int i = 0; i < count; i++) { 1151dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ContentValues v = new ContentValues(); 115276828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung long screenId = screensCopy.get(i); 1153dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen v.put(LauncherSettings.WorkspaceScreens._ID, screenId); 1154dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i); 1155085c853a5702c45865e9b017d21fa15cf2b151b9Yura ops.add(ContentProviderOperation.newInsert(uri).withValues(v).build()); 1156085c853a5702c45865e9b017d21fa15cf2b151b9Yura } 1157085c853a5702c45865e9b017d21fa15cf2b151b9Yura 1158085c853a5702c45865e9b017d21fa15cf2b151b9Yura try { 1159085c853a5702c45865e9b017d21fa15cf2b151b9Yura cr.applyBatch(LauncherProvider.AUTHORITY, ops); 1160085c853a5702c45865e9b017d21fa15cf2b151b9Yura } catch (Exception ex) { 1161085c853a5702c45865e9b017d21fa15cf2b151b9Yura throw new RuntimeException(ex); 1162dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 11639e6a0a20d40675ef98c7fdb8892cf34b90152f7aWinson Chung 1164ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung synchronized (sBgLock) { 1165ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.clear(); 1166ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.addAll(screensCopy); 11674caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen } 1168dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1169dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen }; 1170dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen runOnWorkerThread(r); 1171dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1172dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1173dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen /** 11749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Remove the contents of the specified folder from the database 11759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1176fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal public static void deleteFolderContentsFromDatabase(Context context, final FolderInfo info) { 11779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1178f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1179c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 1180c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka public void run() { 11811d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null); 1182b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 11832abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1184b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(info.id); 1185b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.remove(info.id); 1186b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.remove(info); 1187b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1188c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 11891d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal cr.delete(LauncherSettings.Favorites.CONTENT_URI, 1190c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka LauncherSettings.Favorites.CONTAINER + "=" + info.id, null); 1191b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 11922abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1193b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo childInfo : info.contents) { 1194b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(childInfo.id); 1195b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1196afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1197c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 1198c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 1199b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 12009c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1201f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 12029c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 12039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Set this as the current Launcher activity object for the loader. 12049c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 12059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void initialize(Callbacks callbacks) { 12069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 1207d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal // Disconnect any of the callbacks and drawables associated with ItemInfos on the 1208d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal // workspace to prevent leaking Launcher activities on orientation change. 1209d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal unbindItemInfosAndClearQueuedBindRunnables(); 12109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato mCallbacks = new WeakReference<Callbacks>(callbacks); 1211f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1212f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1213f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1214ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1215c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageChanged(String packageName, UserHandleCompat user) { 1216ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_UPDATE; 1217ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, 1218ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1219ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1220ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1221ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1222c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageRemoved(String packageName, UserHandleCompat user) { 1223ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_REMOVE; 1224ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, 1225ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1226ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1227ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1228ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1229c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageAdded(String packageName, UserHandleCompat user) { 1230ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_ADD; 1231ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName }, 1232ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1233ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1234ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1235ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1236c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackagesAvailable(String[] packageNames, UserHandleCompat user, 1237ed13187a745866483139e2878037e1f8427ce567Kenny Guy boolean replacing) { 1238ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!replacing) { 1239ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packageNames, 1240ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1241ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (mAppsCanBeOnRemoveableStorage) { 1242ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Only rebind if we support removable storage. It catches the 1243ed13187a745866483139e2878037e1f8427ce567Kenny Guy // case where 1244ed13187a745866483139e2878037e1f8427ce567Kenny Guy // apps on the external sd card need to be reloaded 1245ed13187a745866483139e2878037e1f8427ce567Kenny Guy startLoaderFromBackground(); 1246ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1247ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 1248ed13187a745866483139e2878037e1f8427ce567Kenny Guy // If we are replacing then just update the packages in the list 1249ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_UPDATE, 1250ed13187a745866483139e2878037e1f8427ce567Kenny Guy packageNames, user)); 1251ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1252ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1253ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1254ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1255c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackagesUnavailable(String[] packageNames, UserHandleCompat user, 1256ed13187a745866483139e2878037e1f8427ce567Kenny Guy boolean replacing) { 1257ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!replacing) { 1258ed13187a745866483139e2878037e1f8427ce567Kenny Guy enqueuePackageUpdated(new PackageUpdatedTask( 1259ed13187a745866483139e2878037e1f8427ce567Kenny Guy PackageUpdatedTask.OP_UNAVAILABLE, packageNames, 1260ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1261ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1262ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1263ed13187a745866483139e2878037e1f8427ce567Kenny Guy 12641d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato /** 12659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and 12669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * ACTION_PACKAGE_CHANGED. 12679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1268cb1a4778686a46c46d8dc88b6c83674f6fac6592Narayan Kamath @Override 1269f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato public void onReceive(Context context, Intent intent) { 1270b358f813c93ac0d6c4f31058947efd16b188cd1eChris Wren if (DEBUG_RECEIVER) Log.d(TAG, "onReceive intent=" + intent); 1271aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 12723611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String action = intent.getAction(); 1273ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (Intent.ACTION_LOCALE_CHANGED.equals(action)) { 127493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // If we have changed locale we need to clear out the labels in all apps/workspace. 127593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee forceReload(); 127688fa741e50760f9da78cba4a766172f23773bb87Winson Chung } else if (SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED.equals(action)) { 1277e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks callbacks = getCallback(); 1278e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (callbacks != null) { 127988fa741e50760f9da78cba4a766172f23773bb87Winson Chung callbacks.bindSearchProviderChanged(); 1280cfdf7ee64db8820d91a1cd82bf7b961fb2083dceWinson Chung } 1281957c13f032fc4088b3273cec08603c67c069e2c6Sunny Goyal } else if (LauncherAppsCompat.ACTION_MANAGED_PROFILE_ADDED.equals(action) 1282957c13f032fc4088b3273cec08603c67c069e2c6Sunny Goyal || LauncherAppsCompat.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) { 1283823fd5090209017a029460e7dbd8ab9d51d013ddSunny Goyal UserManagerCompat.getInstance(context).enableAndResetCache(); 1284957c13f032fc4088b3273cec08603c67c069e2c6Sunny Goyal forceReload(); 1285e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1286e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1287e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato 12886cc806d678c8a44478308119c087ac9adde73b66Amith Yamasani void forceReload() { 1289f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung resetLoadedState(true, true); 1290f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 1291f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // Do this here because if the launcher activity is running it will be restarted. 1292f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // If it's not running startLoaderFromBackground will merely tell it that it needs 1293f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // to reload. 1294f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung startLoaderFromBackground(); 1295f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung } 1296f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 1297f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung public void resetLoadedState(boolean resetAllAppsLoaded, boolean resetWorkspaceLoaded) { 129893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (mLock) { 129993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // Stop any existing loaders first, so they don't set mAllAppsLoaded or 130093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // mWorkspaceLoaded to true later 130193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee stopLoaderLocked(); 1302f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung if (resetAllAppsLoaded) mAllAppsLoaded = false; 1303f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung if (resetWorkspaceLoaded) mWorkspaceLoaded = false; 130493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 130593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 130693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 1307e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato /** 1308e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * When the launcher is in the background, it's possible for it to miss paired 1309e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * configuration changes. So whenever we trigger the loader from the background 1310e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * tell the launcher that it needs to re-run the loader when it comes back instead 1311e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * of doing it now. 1312e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato */ 1313e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato public void startLoaderFromBackground() { 1314e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato boolean runLoader = false; 1315e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks callbacks = getCallback(); 1316e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (callbacks != null) { 1317e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Only actually run the loader if they're not paused. 1318e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (!callbacks.setLoadOnResume()) { 1319e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal runLoader = true; 1320e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1321e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1322e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato if (runLoader) { 13232bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal startLoader(PagedView.INVALID_RESTORE_PAGE); 1324f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 13253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1326f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 13272bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal /** 13282bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal * If there is already a loader task running, tell it to stop. 13292bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal */ 13302bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal private void stopLoaderLocked() { 133193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee LoaderTask oldTask = mLoaderTask; 133293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (oldTask != null) { 133393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee oldTask.stopLocked(); 133493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 133593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 133693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 13371a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen public boolean isCurrentCallbacks(Callbacks callbacks) { 13381a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen return (mCallbacks != null && mCallbacks.get() == callbacks); 13391a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen } 13401a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen 13412bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal public void startLoader(int synchronousBindPage) { 13422bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal startLoader(synchronousBindPage, LOADER_FLAG_NONE); 1343d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } 1344d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler 13452bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal public void startLoader(int synchronousBindPage, int loadFlags) { 1346756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems 1347756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal InstallShortcutReceiver.enableInstallQueue(); 13483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 1349b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Clear any deferred bind-runnables from the synchronized load process 1350b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // We must do this before any loading/binding is scheduled below. 1351a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 1352a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.clear(); 1353a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 1354b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 13553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Don't bother to start the thread if we know it's not going to do anything 13563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mCallbacks != null && mCallbacks.get() != null) { 13573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // If there is already one running, tell it to stop. 13582bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal stopLoaderLocked(); 13592bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal mLoaderTask = new LoaderTask(mApp.getContext(), loadFlags); 13607aff399974c756930070d82d7b2df88f125dacd6Derek Prothro if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE 1361f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal && mAllAppsLoaded && mWorkspaceLoaded && !mIsLoaderTaskRunning) { 1362b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mLoaderTask.runBindSynchronousPage(synchronousBindPage); 1363b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1364b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorkerThread.setPriority(Thread.NORM_PRIORITY); 1365b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorker.post(mLoaderTask); 1366b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1367b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1368b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1369b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1370b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1371b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung void bindRemainingSynchronousPages() { 1372b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Post the remaining side pages to be loaded 1373b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!mDeferredBindRunnables.isEmpty()) { 1374a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk Runnable[] deferredBindRunnables = null; 1375a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 1376a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk deferredBindRunnables = mDeferredBindRunnables.toArray( 1377a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk new Runnable[mDeferredBindRunnables.size()]); 1378a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.clear(); 1379a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 1380a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk for (final Runnable r : deferredBindRunnables) { 1381d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal mHandler.post(r); 1382b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 1383b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy } 13843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1385b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 13863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void stopLoader() { 13873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 13883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask != null) { 13893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask.stopLocked(); 13909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1391f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 13923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1393b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 1394c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal /** 1395c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal * Loads the workspace screen ids in an ordered list. 1396c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal */ 1397e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal public static ArrayList<Long> loadWorkspaceScreensDb(Context context) { 139876828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung final ContentResolver contentResolver = context.getContentResolver(); 139976828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung final Uri screensUri = LauncherSettings.WorkspaceScreens.CONTENT_URI; 140076828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 1401c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal // Get screens ordered by rank. 1402c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal final Cursor sc = contentResolver.query(screensUri, null, null, null, 1403c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal LauncherSettings.WorkspaceScreens.SCREEN_RANK); 1404c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal ArrayList<Long> screenIds = new ArrayList<Long>(); 140576828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung try { 1406c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal final int idIndex = sc.getColumnIndexOrThrow(LauncherSettings.WorkspaceScreens._ID); 140776828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung while (sc.moveToNext()) { 140876828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung try { 1409c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal screenIds.add(sc.getLong(idIndex)); 141076828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } catch (Exception e) { 1411c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal Launcher.addDumpLog(TAG, "Desktop items loading interrupted" 1412c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal + " - invalid screens: " + e, true); 141376828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 141476828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 141576828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } finally { 141676828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung sc.close(); 141776828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 1418c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal return screenIds; 141976828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 142076828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 1421c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka public boolean isAllAppsLoaded() { 1422c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka return mAllAppsLoaded; 1423c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka } 1424c57b7a8233d32c6dd8de5057c570afe3f50e3ef2Michael Jurka 14253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato /** 14263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * Runnable for the thread that loads the contents of the launcher: 14273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - workspace icons 14283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - widgets 14293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - all apps icons 14303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato */ 14313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private class LoaderTask implements Runnable { 14323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private Context mContext; 1433091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk boolean mIsLoadingAndBindingWorkspace; 14343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private boolean mStopped; 1435091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk boolean mLoadAndBindStepFinished; 1436d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler private int mFlags; 1437b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 14382bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal LoaderTask(Context context, int flags) { 14393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mContext = context; 1440d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler mFlags = flags; 14413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1442f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 144366cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal private void loadAndBindWorkspace() { 144436a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung mIsLoadingAndBindingWorkspace = true; 144536a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 14463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Load the workspace 14473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 14483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "loadAndBindWorkspace mWorkspaceLoaded=" + mWorkspaceLoaded); 14493611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1450288a36b563801a26d00084cb823435a3ba4cb76cMichael Jurka 1451a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka if (!mWorkspaceLoaded) { 145266cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal loadWorkspace(); 145393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (LoaderTask.this) { 145493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (mStopped) { 145566cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal return; 145693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 145793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mWorkspaceLoaded = true; 14589c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1460cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 14613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Bind the workspace 146266cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal bindWorkspace(-1); 14633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1464f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 14653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void waitForIdle() { 14663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Wait until the either we're stopped or the other threads are done. 14673611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This way we don't start loading all apps until the workspace has settled 14683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // down. 14693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 14703611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long workspaceWaitTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1471843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 14723611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.postIdle(new Runnable() { 14733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 14743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 14753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoadAndBindStepFinished = true; 14763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 14773611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "done with previous binding step"); 14789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato LoaderTask.this.notify(); 14809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 14833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 148471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal while (!mStopped && !mLoadAndBindStepFinished) { 14853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato try { 1486c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka // Just in case mFlushingWorkerThread changes but we aren't woken up, 1487c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka // wait no longer than 1sec at a time 1488c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka this.wait(1000); 14893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } catch (InterruptedException ex) { 14903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Ignore 14919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 14933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 14943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "waited " 1495aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung + (SystemClock.uptimeMillis()-workspaceWaitTime) 14963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + "ms for previous step to finish binding"); 14979c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1498843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 14993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1500f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1501b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung void runBindSynchronousPage(int synchronousBindPage) { 15027aff399974c756930070d82d7b2df88f125dacd6Derek Prothro if (synchronousBindPage == PagedView.INVALID_RESTORE_PAGE) { 1503b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we have a valid page index to load synchronously 1504b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Should not call runBindSynchronousPage() without " + 1505b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung "valid page index"); 1506b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1507b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!mAllAppsLoaded || !mWorkspaceLoaded) { 1508b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we don't try and bind a specified page when the pages have not been 1509b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // loaded already (we should load everything asynchronously in that case) 1510b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Expecting AllApps and Workspace to be loaded"); 1511b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1512b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung synchronized (mLock) { 1513b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (mIsLoaderTaskRunning) { 1514b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we are never running the background loading at this point since 1515b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // we also touch the background collections 1516b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Error! Background loading is already running"); 1517b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1518b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1519b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1520b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: Throw an exception if we are already loading (since we touch the worker thread 1521b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // data structures, we can't allow any other thread to touch that data, but because 1522b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // this call is synchronous, we can get away with not locking). 1523b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1524cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // The LauncherModel is static in the LauncherAppState and mHandler may have queued 1525a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen // operations from the previous activity. We need to ensure that all queued operations 1526a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen // are executed before any synchronous binding work is done. 1527a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen mHandler.flush(); 1528a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen 1529b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Divide the set of loaded items into those that we are binding synchronously, and 1530b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // everything else that is to be bound normally (asynchronously). 153166cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal bindWorkspace(synchronousBindPage); 1532b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: For now, continue posting the binding of AllApps as there are other issues that 1533b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // arise from that. 1534b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung onlyBindAllApps(); 1535b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1536b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 15373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 1538b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung synchronized (mLock) { 1539f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal if (mStopped) { 1540f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal return; 1541f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal } 1542b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mIsLoaderTaskRunning = true; 1543b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 15443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Optimize for end-user experience: if the Launcher is up and // running with the 15453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // All Apps interface in the foreground, load All Apps first. Otherwise, load the 15463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // workspace first (default). 15473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato keep_running: { 154864359a53dc827797917a8d9a0697a91996789801Winson Chung if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace"); 154966cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal loadAndBindWorkspace(); 1550843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 15513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mStopped) { 15523611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break keep_running; 15533611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 15543611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 15553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato waitForIdle(); 1556f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1557843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler // second step 155864359a53dc827797917a8d9a0697a91996789801Winson Chung if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps"); 155964359a53dc827797917a8d9a0697a91996789801Winson Chung loadAndBindAllApps(); 15603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1561843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 15623611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Clear out this reference, otherwise we end up holding it until all of the 15633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // callback runnables are done. 15643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mContext = null; 1565f3d5ea926d4dd1a739b9d3816543728af723cc26Joe Onorato 15663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 15673611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // If we are still the last one to be scheduled, remove ourselves. 15683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask == this) { 15693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask = null; 1570843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 1571b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mIsLoaderTaskRunning = false; 1572756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal mHasLoaderCompletedOnce = true; 15733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 15743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1575f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 15763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void stopLocked() { 15773611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 15783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mStopped = true; 15793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato this.notify(); 1580f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 15813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1582f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 15833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato /** 15843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * Gets the callbacks object. If we've been stopped, or if the launcher object 15853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * has somehow been garbage collected, return null instead. Pass in the Callbacks 15863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * object that was around when the deferred message was scheduled, and if there's 15873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * a new Callbacks object around then also return null. This will save us from 15883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * calling onto it with data that will be ignored. 15893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato */ 15903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Callbacks tryGetCallbacks(Callbacks oldCallbacks) { 15913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 15923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mStopped) { 15933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 15943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1595ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato 15963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mCallbacks == null) { 15973611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 15983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1599f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 16003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = mCallbacks.get(); 16013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != oldCallbacks) { 16023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 16033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 16043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks == null) { 16053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "no mCallbacks"); 16063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 16079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 16083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 16093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return callbacks; 1610f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 16113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1612f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 16133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // check & update map of what's occupied; used to discard overlapping/invalid items 161441cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal private boolean checkItemPlacement(LongArrayMap<ItemInfo[][]> occupied, ItemInfo item, 161541cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal ArrayList<Long> workspaceScreens) { 1616892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 16172e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); 161841cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal final int countX = profile.numColumns; 161941cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal final int countY = profile.numRows; 1620892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 1621dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long containerIndex = item.screenId; 1622f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1623a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung // Return early if we detect that an item is under the hotseat button 1624a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung if (mCallbacks == null || 1625a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung mCallbacks.get().isAllAppsButtonRank((int) item.screenId)) { 1626295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler Log.e(TAG, "Error loading shortcut into hotseat " + item 1627295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler + " into position (" + item.screenId + ":" + item.cellX + "," 1628295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler + item.cellY + ") occupied by all apps"); 1629a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung return false; 1630a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung } 1631a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung 1632295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler final ItemInfo[][] hotseatItems = 1633295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler occupied.get((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT); 1634295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler 16352e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen if (item.screenId >= profile.numHotseatIcons) { 1636ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen Log.e(TAG, "Error loading shortcut " + item 1637ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + " into hotseat position " + item.screenId 16382e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen + ", position out of bounds: (0 to " + (profile.numHotseatIcons - 1) 1639ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + ")"); 1640ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen return false; 1641ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen } 1642ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 1643295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler if (hotseatItems != null) { 1644295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler if (hotseatItems[(int) item.screenId][0] != null) { 1645dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Log.e(TAG, "Error loading shortcut into hotseat " + item 1646dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + " into position (" + item.screenId + ":" + item.cellX + "," 1647dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + item.cellY + ") occupied by " 1648dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + occupied.get(LauncherSettings.Favorites.CONTAINER_HOTSEAT) 1649dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen [(int) item.screenId][0]); 1650dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen return false; 1651295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler } else { 1652295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler hotseatItems[(int) item.screenId][0] = item; 1653295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler return true; 1654dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 16556ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung } else { 16562e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen final ItemInfo[][] items = new ItemInfo[(int) profile.numHotseatIcons][1]; 1657dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen items[(int) item.screenId][0] = item; 1658dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen occupied.put((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT, items); 16596ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung return true; 16606ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung } 166141cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal } else if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { 166241cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal if (!workspaceScreens.contains((Long) item.screenId)) { 166341cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal // The item has an invalid screen id. 166441cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal return false; 166541cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal } 166641cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal } else { 1667f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung // Skip further checking if it is not the hotseat or workspace container 16683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return true; 16693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1670f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung 1671dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (!occupied.containsKey(item.screenId)) { 1672892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung ItemInfo[][] items = new ItemInfo[countX + 1][countY + 1]; 1673dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen occupied.put(item.screenId, items); 1674dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1675dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1676295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler final ItemInfo[][] screens = occupied.get(item.screenId); 1677ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 1678ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen item.cellX < 0 || item.cellY < 0 || 1679ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen item.cellX + item.spanX > countX || item.cellY + item.spanY > countY) { 1680ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen Log.e(TAG, "Error loading shortcut " + item 1681ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + " into cell (" + containerIndex + "-" + item.screenId + ":" 1682ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + item.cellX + "," + item.cellY 1683ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + ") out of screen bounds ( " + countX + "x" + countY + ")"); 1684ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen return false; 1685ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen } 1686ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 16876ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung // Check if any workspace icons overlap with each other 16883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int x = item.cellX; x < (item.cellX+item.spanX); x++) { 16893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int y = item.cellY; y < (item.cellY+item.spanY); y++) { 1690dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (screens[x][y] != null) { 16913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.e(TAG, "Error loading shortcut " + item 1692dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + " into cell (" + containerIndex + "-" + item.screenId + ":" 16933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + x + "," + y 1694aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung + ") occupied by " 1695dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + screens[x][y]); 16963611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return false; 16978802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 16988802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 16993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 17003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int x = item.cellX; x < (item.cellX+item.spanX); x++) { 17013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int y = item.cellY; y < (item.cellY+item.spanY); y++) { 1702dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen screens[x][y] = item; 17038802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 17048802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 1705f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung 17063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return true; 17073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 17088802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler 1709ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung /** Clears all the sBg data structures */ 1710ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung private void clearSBgDataStructures() { 1711ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung synchronized (sBgLock) { 1712ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceItems.clear(); 1713ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgAppWidgets.clear(); 1714ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgFolders.clear(); 1715ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgItemsIdMap.clear(); 1716ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.clear(); 1717ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 1718ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 1719ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung 172066cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal private void loadWorkspace() { 17213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1722f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 17233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Context context = mContext; 17243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final ContentResolver contentResolver = context.getContentResolver(); 17253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final PackageManager manager = context.getPackageManager(); 17263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final boolean isSafeMode = manager.isSafeMode(); 1727f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 1728f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal final boolean isSdCardReady = context.registerReceiver(null, 172905e318d8f7d5ea615539d34b181ee44686f1f494Sunny Goyal new IntentFilter(StartupReceiver.SYSTEM_READY)) != null; 1730f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1731892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 17322e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); 173341cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal int countX = profile.numColumns; 173441cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal int countY = profile.numRows; 1735892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 17366579e1eee8a6fce44f020d40c3bbdbf245d6c12cSunny Goyal if (MigrateFromRestoreTask.ENABLED && MigrateFromRestoreTask.shouldRunTask(mContext)) { 1737d934e0b0b7b60c9457fd0eb615355c16bac1a285Sunny Goyal long migrationStartTime = System.currentTimeMillis(); 1738d934e0b0b7b60c9457fd0eb615355c16bac1a285Sunny Goyal Log.v(TAG, "Starting workspace migration after restore"); 1739e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal try { 1740e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal MigrateFromRestoreTask task = new MigrateFromRestoreTask(mContext); 1741e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal // Clear the flags before starting the task, so that we do not run the task 1742e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal // again, in case there was an uncaught error. 1743e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal MigrateFromRestoreTask.clearFlags(mContext); 1744e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal task.execute(); 1745e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal } catch (Exception e) { 1746e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal Log.e(TAG, "Error during grid migration", e); 1747e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal 1748e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal // Clear workspace. 1749e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal mFlags = mFlags | LOADER_FLAG_CLEAR_WORKSPACE; 1750e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal } 1751d934e0b0b7b60c9457fd0eb615355c16bac1a285Sunny Goyal Log.v(TAG, "Workspace migration completed in " 1752d934e0b0b7b60c9457fd0eb615355c16bac1a285Sunny Goyal + (System.currentTimeMillis() - migrationStartTime)); 1753e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal } 1754e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal 1755d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler if ((mFlags & LOADER_FLAG_CLEAR_WORKSPACE) != 0) { 1756d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler Launcher.addDumpLog(TAG, "loadWorkspace: resetting launcher database", true); 1757d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler LauncherAppState.getLauncherProvider().deleteDatabase(); 1758d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } 1759d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler 1760d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler if ((mFlags & LOADER_FLAG_MIGRATE_SHORTCUTS) != 0) { 1761d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler // append the user's Launcher2 shortcuts 1762d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler Launcher.addDumpLog(TAG, "loadWorkspace: migrating from launcher2", true); 1763d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler LauncherAppState.getLauncherProvider().migrateLauncher2Shortcuts(); 1764d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } else { 1765d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler // Make sure the default workspace is loaded 1766d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler Launcher.addDumpLog(TAG, "loadWorkspace: loading default favorites", false); 17670fe505bf82a265e51c556d7204976651cde7f55cSunny Goyal LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary(); 1768d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } 1769e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 17702abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1771ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung clearSBgDataStructures(); 1772756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal final HashMap<String, Integer> installingPkgs = PackageInstallerCompat 17739448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal .getInstance(mContext).updateAndGetActiveSessionCache(); 177441cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal sBgWorkspaceScreens.addAll(loadWorkspaceScreensDb(mContext)); 1775b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1776b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<Long> itemsToRemove = new ArrayList<Long>(); 1777f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren final ArrayList<Long> restoredRows = new ArrayList<Long>(); 17781d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final Uri contentUri = LauncherSettings.Favorites.CONTENT_URI; 1779e523e70f75ff90ca5d613fb8398d37208e6cd32dChris Wren if (DEBUG_LOADERS) Log.d(TAG, "loading model from " + contentUri); 1780e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen final Cursor c = contentResolver.query(contentUri, null, null, null, null); 1781b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1782b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // +1 for the hotseat (it can be larger than the workspace) 1783b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Load workspace in reverse order to ensure that latest items are loaded first (and 1784b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // before any earlier duplicates) 1785e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal final LongArrayMap<ItemInfo[][]> occupied = new LongArrayMap<>(); 1786b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1787b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1788b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); 1789b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int intentIndex = c.getColumnIndexOrThrow 1790b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.INTENT); 1791b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int titleIndex = c.getColumnIndexOrThrow 1792b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.TITLE); 1793b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int containerIndex = c.getColumnIndexOrThrow( 1794b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.CONTAINER); 1795b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int itemTypeIndex = c.getColumnIndexOrThrow( 1796b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ITEM_TYPE); 1797b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int appWidgetIdIndex = c.getColumnIndexOrThrow( 1798b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.APPWIDGET_ID); 1799c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren final int appWidgetProviderIndex = c.getColumnIndexOrThrow( 1800c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren LauncherSettings.Favorites.APPWIDGET_PROVIDER); 1801b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int screenIndex = c.getColumnIndexOrThrow( 1802b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.SCREEN); 1803b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int cellXIndex = c.getColumnIndexOrThrow 1804b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.CELLX); 1805b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int cellYIndex = c.getColumnIndexOrThrow 1806b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.CELLY); 1807b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int spanXIndex = c.getColumnIndexOrThrow 1808b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.SPANX); 1809b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int spanYIndex = c.getColumnIndexOrThrow( 1810b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.SPANY); 181108f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal final int rankIndex = c.getColumnIndexOrThrow( 181208f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal LauncherSettings.Favorites.RANK); 1813f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren final int restoredIndex = c.getColumnIndexOrThrow( 1814f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren LauncherSettings.Favorites.RESTORED); 1815ed13187a745866483139e2878037e1f8427ce567Kenny Guy final int profileIdIndex = c.getColumnIndexOrThrow( 1816ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherSettings.Favorites.PROFILE_ID); 18175d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal final int optionsIndex = c.getColumnIndexOrThrow( 18185d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal LauncherSettings.Favorites.OPTIONS); 18194e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal final CursorIconInfo cursorIconInfo = new CursorIconInfo(c); 1820b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 18217f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal final LongSparseArray<UserHandleCompat> allUsers = new LongSparseArray<>(); 18227f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal for (UserHandleCompat user : mUserManager.getUserProfiles()) { 18237f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal allUsers.put(mUserManager.getSerialNumberForUser(user), user); 18247f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal } 18257f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal 1826b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ShortcutInfo info; 1827b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String intentDescription; 1828b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherAppWidgetInfo appWidgetInfo; 1829b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int container; 1830b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung long id; 183126ace12135a662ad864678c9fede9817e5c02b67Robin Lee long serialNumber; 1832b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent intent; 1833ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user; 1834b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1835b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung while (!mStopped && c.moveToNext()) { 1836b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1837b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int itemType = c.getInt(itemTypeIndex); 1838f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren boolean restored = 0 != c.getInt(restoredIndex); 1839f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean allowMissingTarget = false; 1840b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal container = c.getInt(containerIndex); 1841b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1842b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (itemType) { 1843b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1844b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1845ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung id = c.getLong(idIndex); 1846b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intentDescription = c.getString(intentIndex); 184726ace12135a662ad864678c9fede9817e5c02b67Robin Lee serialNumber = c.getInt(profileIdIndex); 18487f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal user = allUsers.get(serialNumber); 1849349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal int promiseType = c.getInt(restoredIndex); 18501a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal int disabledState = 0; 1851bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal boolean itemReplaced = false; 1852ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user == null) { 1853ed13187a745866483139e2878037e1f8427ce567Kenny Guy // User has been deleted remove the item. 1854ed13187a745866483139e2878037e1f8427ce567Kenny Guy itemsToRemove.add(id); 1855ed13187a745866483139e2878037e1f8427ce567Kenny Guy continue; 1856ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1857b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1858b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intent = Intent.parseUri(intentDescription, 0); 1859ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung ComponentName cn = intent.getComponent(); 1860f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (cn != null && cn.getPackageName() != null) { 1861f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean validPkg = launcherApps.isPackageEnabledForProfile( 1862f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal cn.getPackageName(), user); 1863f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean validComponent = validPkg && 1864f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal launcherApps.isActivityEnabledForProfile(cn, user); 1865f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 1866f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (validComponent) { 1867f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (restored) { 1868f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // no special handling necessary for this item 1869f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal restoredRows.add(id); 1870f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal restored = false; 1871f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 1872f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } else if (validPkg) { 1873349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent = null; 1874349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { 1875349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // We allow auto install apps to have their intent 1876349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // updated after an install. 1877349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent = manager.getLaunchIntentForPackage( 1878349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal cn.getPackageName()); 1879349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (intent != null) { 1880349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ContentValues values = new ContentValues(); 1881349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal values.put(LauncherSettings.Favorites.INTENT, 1882349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent.toUri(0)); 1883bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal updateItem(id, values); 1884349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1885349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1886349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 1887349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (intent == null) { 1888349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // The app is installed but the component is no 1889349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // longer available. 1890349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal Launcher.addDumpLog(TAG, 1891349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal "Invalid component removed: " + cn, true); 1892349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal itemsToRemove.add(id); 1893349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal continue; 1894349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } else { 1895349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // no special handling necessary for this item 1896349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal restoredRows.add(id); 1897349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal restored = false; 1898349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1899f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } else if (restored) { 1900f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // Package is not yet available but might be 1901f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // installed later. 1902f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren Launcher.addDumpLog(TAG, 1903f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren "package not yet restored: " + cn, true); 19049448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal 19059448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal if ((promiseType & ShortcutInfo.FLAG_RESTORE_STARTED) != 0) { 19069448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // Restore has started once. 1907756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } else if (installingPkgs.containsKey(cn.getPackageName())) { 19089448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // App restore has started. Update the flag 19099448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal promiseType |= ShortcutInfo.FLAG_RESTORE_STARTED; 19109448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal ContentValues values = new ContentValues(); 19119448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal values.put(LauncherSettings.Favorites.RESTORED, 19129448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal promiseType); 1913bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal updateItem(id, values); 1914bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } else if ((promiseType & ShortcutInfo.FLAG_RESTORED_APP_TYPE) != 0) { 1915bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal // This is a common app. Try to replace this. 1916bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal int appType = CommonAppTypeParser.decodeItemTypeFromFlag(promiseType); 1917bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal CommonAppTypeParser parser = new CommonAppTypeParser(id, appType, context); 1918bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal if (parser.findDefaultApp()) { 1919bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal // Default app found. Replace it. 1920bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal intent = parser.parsedIntent; 1921bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal cn = intent.getComponent(); 1922bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal ContentValues values = parser.parsedValues; 1923bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal values.put(LauncherSettings.Favorites.RESTORED, 0); 1924bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal updateItem(id, values); 1925bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal restored = false; 1926bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal itemReplaced = true; 1927bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal 1928bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } else if (REMOVE_UNRESTORED_ICONS) { 1929bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal Launcher.addDumpLog(TAG, 1930bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal "Unrestored package removed: " + cn, true); 1931bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal itemsToRemove.add(id); 1932bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal continue; 1933bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } 19349448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } else if (REMOVE_UNRESTORED_ICONS) { 19359448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal Launcher.addDumpLog(TAG, 19369448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal "Unrestored package removed: " + cn, true); 19379448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal itemsToRemove.add(id); 19389448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal continue; 19399448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } 19401a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else if (launcherApps.isAppEnabled( 19411a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal manager, cn.getPackageName(), 19421a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal PackageManager.GET_UNINSTALLED_PACKAGES)) { 19431a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Package is present but not available. 19441a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal allowMissingTarget = true; 19451a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal disabledState = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; 19461a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else if (!isSdCardReady) { 1947f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // SdCard is not ready yet. Package might get available, 1948f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // once it is ready. 1949f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal Launcher.addDumpLog(TAG, "Invalid package: " + cn 1950f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal + " (check again later)", true); 1951f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal HashSet<String> pkgs = sPendingPackages.get(user); 1952f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (pkgs == null) { 1953513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala pkgs = new HashSet<String>(); 1954f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal sPendingPackages.put(user, pkgs); 1955f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 1956f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal pkgs.add(cn.getPackageName()); 1957f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal allowMissingTarget = true; 1958f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // Add the icon on the workspace anyway. 19591a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 19601a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else { 19611a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Do not wait for external media load anymore. 19621a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Log the invalid package, and remove it 19631a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal Launcher.addDumpLog(TAG, 19641a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal "Invalid package removed: " + cn, true); 19651a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal itemsToRemove.add(id); 19661a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal continue; 1967ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 1968938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal } else if (cn == null) { 1969938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal // For shortcuts with no component, keep them as they are 1970938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal restoredRows.add(id); 1971938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal restored = false; 1972ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 1973b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (URISyntaxException e) { 1974f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren Launcher.addDumpLog(TAG, 1975f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren "Invalid uri: " + intentDescription, true); 197641cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal itemsToRemove.add(id); 1977b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung continue; 1978b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1979968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka 198034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal boolean useLowResIcon = container >= 0 && 198134b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW; 198234b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 1983bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal if (itemReplaced) { 1984bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal if (user.equals(UserHandleCompat.myUserHandle())) { 19854fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal info = getAppShortcutInfo(manager, intent, user, context, null, 19864e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal cursorIconInfo.iconIndex, titleIndex, 19874e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal false, useLowResIcon); 1988bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } else { 1989bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal // Don't replace items for other profiles. 1990bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal itemsToRemove.add(id); 1991bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal continue; 1992bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } 1993bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } else if (restored) { 1994ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user.equals(UserHandleCompat.myUserHandle())) { 1995ed13187a745866483139e2878037e1f8427ce567Kenny Guy Launcher.addDumpLog(TAG, 1996ed13187a745866483139e2878037e1f8427ce567Kenny Guy "constructing info for partially restored package", 1997ed13187a745866483139e2878037e1f8427ce567Kenny Guy true); 199834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal info = getRestoredItemInfo(c, titleIndex, intent, 1999c22841bfd1961781a84cfccb98d1c2937a9adee4Sunny Goyal promiseType, itemType, cursorIconInfo, context); 2000ed13187a745866483139e2878037e1f8427ce567Kenny Guy intent = getRestoredItemIntent(c, context, intent); 2001ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 2002ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Don't restore items for other profiles. 2003ed13187a745866483139e2878037e1f8427ce567Kenny Guy itemsToRemove.add(id); 2004ed13187a745866483139e2878037e1f8427ce567Kenny Guy continue; 2005ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2006f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } else if (itemType == 2007f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 20084fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal info = getAppShortcutInfo(manager, intent, user, context, c, 20094e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal cursorIconInfo.iconIndex, titleIndex, 20104e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal allowMissingTarget, useLowResIcon); 2011b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 20124e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal info = getShortcutInfo(c, context, titleIndex, cursorIconInfo); 2013b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2014b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // App shortcuts that used to be automatically added to Launcher 2015b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // didn't always have the correct intent flags set, so do that 2016b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // here 2017b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (intent.getAction() != null && 20189ad005639e1698c94674cdfadf3ae342fb56c9b5Michael Jurka intent.getCategories() != null && 20199ad005639e1698c94674cdfadf3ae342fb56c9b5Michael Jurka intent.getAction().equals(Intent.ACTION_MAIN) && 2020968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { 2021b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intent.addFlags( 2022b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent.FLAG_ACTIVITY_NEW_TASK | 2023b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 2024b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2025968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka } 20263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 2027b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info != null) { 2028ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung info.id = id; 2029b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.intent = intent; 2030b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.container = container; 2031dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen info.screenId = c.getInt(screenIndex); 2032b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.cellX = c.getInt(cellXIndex); 2033b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.cellY = c.getInt(cellYIndex); 203408f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal info.rank = c.getInt(rankIndex); 20355f8afe6280eae34620067696173e71943e1a30a3Winson Chung info.spanX = 1; 20365f8afe6280eae34620067696173e71943e1a30a3Winson Chung info.spanY = 1; 2037ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.intent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); 20384e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (info.promisedIntent != null) { 20394e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal info.promisedIntent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); 20404e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 20411a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal info.isDisabled = disabledState; 20421a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (isSafeMode && !Utilities.isSystemApp(context, intent)) { 20431a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE; 20441a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 2045ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 2046b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // check & update map of what's occupied 204741cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal if (!checkItemPlacement(occupied, info, sBgWorkspaceScreens)) { 2048fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 2049b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2050b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2051b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2052756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (restored) { 2053756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal ComponentName cn = info.getTargetComponent(); 2054756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (cn != null) { 2055756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Integer progress = installingPkgs.get(cn.getPackageName()); 2056756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (progress != null) { 2057756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal info.setInstallProgress(progress); 2058756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } else { 2059756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE; 2060756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 2061756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 2062756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 2063756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 2064b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (container) { 2065b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: 2066b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: 2067b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(info); 2068b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2069b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung default: 2070b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Item is in a user folder 2071b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folderInfo = 2072b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung findOrMakeFolder(sBgFolders, container); 2073b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.add(info); 2074b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2075b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2076b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(info.id, info); 20771323b4856a2a822af77293cadeda9910a5d1ba0eWinson Chung } else { 20781323b4856a2a822af77293cadeda9910a5d1ba0eWinson Chung throw new RuntimeException("Unexpected null ShortcutInfo"); 2079b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2080b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2081b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2082b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 2083b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung id = c.getLong(idIndex); 2084b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folderInfo = findOrMakeFolder(sBgFolders, id); 2085b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2086a508e4f804c2bddf9e2cdfa3d0bd4a8202ff2151Sunny Goyal // Do not trim the folder label, as is was set by the user. 2087a508e4f804c2bddf9e2cdfa3d0bd4a8202ff2151Sunny Goyal folderInfo.title = c.getString(titleIndex); 2088b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.id = id; 2089b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.container = container; 2090dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen folderInfo.screenId = c.getInt(screenIndex); 2091b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.cellX = c.getInt(cellXIndex); 2092b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.cellY = c.getInt(cellYIndex); 20935f8afe6280eae34620067696173e71943e1a30a3Winson Chung folderInfo.spanX = 1; 20945f8afe6280eae34620067696173e71943e1a30a3Winson Chung folderInfo.spanY = 1; 20955d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal folderInfo.options = c.getInt(optionsIndex); 20965f8afe6280eae34620067696173e71943e1a30a3Winson Chung 20973611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // check & update map of what's occupied 209841cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal if (!checkItemPlacement(occupied, folderInfo, sBgWorkspaceScreens)) { 2099fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 21003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 21019c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 21025f8afe6280eae34620067696173e71943e1a30a3Winson Chung 21033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato switch (container) { 2104b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: 2105b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: 2106b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(folderInfo); 2107b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 21089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 210917a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato 2110f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren if (restored) { 2111f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren // no special handling required for restored folders 2112f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren restoredRows.add(id); 2113f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 2114f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 2115b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(folderInfo.id, folderInfo); 2116b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.put(folderInfo.id, folderInfo); 2117b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2118b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2119b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 21205940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: 2121b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Read all Launcher-specific widget details 21225940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen boolean customWidget = itemType == 21235940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET; 21245940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 2125b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int appWidgetId = c.getInt(appWidgetIdIndex); 21267f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal serialNumber = c.getLong(profileIdIndex); 2127c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren String savedProvider = c.getString(appWidgetProviderIndex); 21283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato id = c.getLong(idIndex); 21297f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal user = allUsers.get(serialNumber); 21307f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal if (user == null) { 21317f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal itemsToRemove.add(id); 21327f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal continue; 21337f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal } 21347f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal 2135ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final ComponentName component = 2136ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal ComponentName.unflattenFromString(savedProvider); 2137f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2138651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal final int restoreStatus = c.getInt(restoredIndex); 2139ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean isIdValid = (restoreStatus & 2140ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) == 0; 2141ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean wasProviderReady = (restoreStatus & 2142ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0; 2143ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 21445940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen final LauncherAppWidgetProviderInfo provider = 21455940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherModel.getProviderInfo(context, 214626ace12135a662ad864678c9fede9817e5c02b67Robin Lee ComponentName.unflattenFromString(savedProvider), 21477f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal user); 2148ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2149ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean isProviderReady = isValidProvider(provider); 21505940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!isSafeMode && !customWidget && 21515940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen wasProviderReady && !isProviderReady) { 2152651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal String log = "Deleting widget that isn't installed anymore: " 2153ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal + "id=" + id + " appWidgetId=" + appWidgetId; 21545940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 2155b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.e(TAG, log); 21564caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen Launcher.addDumpLog(TAG, log, false); 2157b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsToRemove.add(id); 2158b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2159ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (isProviderReady) { 2160651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, 2161651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal provider.provider); 21625940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 216353f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal // The provider is available. So the widget is either 216453f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal // available or not available. We do not need to track 216553f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal // any future restore updates. 216653f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal int status = restoreStatus & 216753f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; 2168ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (!wasProviderReady) { 2169ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // If provider was not previously ready, update the 2170ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // status and UI flag. 2171ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2172ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // Id would be valid only if the widget restore broadcast was received. 2173ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (isIdValid) { 217484b4adc3fb2301466468828ccbd742209619e597Sunny Goyal status = LauncherAppWidgetInfo.FLAG_UI_NOT_READY; 2175ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } else { 2176ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal status &= ~LauncherAppWidgetInfo 2177ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal .FLAG_PROVIDER_NOT_READY; 2178ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } 2179ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } 2180ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal appWidgetInfo.restoreStatus = status; 2181651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } else { 2182651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal Log.v(TAG, "Widget restore pending id=" + id 2183651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal + " appWidgetId=" + appWidgetId 2184651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal + " status =" + restoreStatus); 2185651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, 2186ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal component); 2187651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo.restoreStatus = restoreStatus; 2188756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Integer installProgress = installingPkgs.get(component.getPackageName()); 21899448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal 21909448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal if ((restoreStatus & LauncherAppWidgetInfo.FLAG_RESTORE_STARTED) != 0) { 21919448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // Restore has started once. 2192756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } else if (installProgress != null) { 21939448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // App restore has started. Update the flag 21949448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal appWidgetInfo.restoreStatus |= 21959448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; 21969b4b0812fec41c40d81d507cfdb528ba87663f5fSunny Goyal } else if (REMOVE_UNRESTORED_ICONS && !isSafeMode) { 21979448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal Launcher.addDumpLog(TAG, 2198c5fb59fb9a36180ce962f565d85aa92f9991da1aSunny Goyal "Unrestored widget removed: " + component, true); 21999448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal itemsToRemove.add(id); 22009448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal continue; 22019448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } 2202756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 2203756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal appWidgetInfo.installProgress = 2204756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal installProgress == null ? 0 : installProgress; 2205651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } 2206ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2207b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.id = id; 2208dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen appWidgetInfo.screenId = c.getInt(screenIndex); 2209b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.cellX = c.getInt(cellXIndex); 2210b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.cellY = c.getInt(cellYIndex); 2211b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.spanX = c.getInt(spanXIndex); 2212b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.spanY = c.getInt(spanYIndex); 2213ab7a4fe206b4ca1c18457738d5068df473a01ea5Sunny Goyal appWidgetInfo.user = user; 2214b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2215b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && 2216b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 2217b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.e(TAG, "Widget found where container != " + 221841cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!"); 221941cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal itemsToRemove.add(id); 2220b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung continue; 2221b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2222b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2223b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal appWidgetInfo.container = container; 2224b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // check & update map of what's occupied 222541cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal if (!checkItemPlacement(occupied, appWidgetInfo, sBgWorkspaceScreens)) { 2226fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 2227b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2228b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2229651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal 22305940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!customWidget) { 22315940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen String providerName = 22325940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.providerName.flattenToString(); 22335940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!providerName.equals(savedProvider) || 22345940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen (appWidgetInfo.restoreStatus != restoreStatus)) { 22355940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen ContentValues values = new ContentValues(); 22365940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen values.put( 22375940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherSettings.Favorites.APPWIDGET_PROVIDER, 22385940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen providerName); 22395940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen values.put(LauncherSettings.Favorites.RESTORED, 22405940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.restoreStatus); 2241bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal updateItem(id, values); 22425940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 2243c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren } 2244b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(appWidgetInfo.id, appWidgetInfo); 2245b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.add(appWidgetInfo); 2246b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 22479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 22483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2249b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (Exception e) { 2250295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler Launcher.addDumpLog(TAG, "Desktop items loading interrupted", e, true); 2251b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2252b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2253b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } finally { 225447b5031c703dbee491af9f49e6e08865452d57efDaniel Sandler if (c != null) { 225547b5031c703dbee491af9f49e6e08865452d57efDaniel Sandler c.close(); 225647b5031c703dbee491af9f49e6e08865452d57efDaniel Sandler } 2257b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2258ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 2259ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung // Break early if we've stopped loading 2260ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung if (mStopped) { 2261ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung clearSBgDataStructures(); 226266cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal return; 2263ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 2264ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung 2265b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemsToRemove.size() > 0) { 2266b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Remove dead items 2267b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal contentResolver.delete(LauncherSettings.Favorites.CONTENT_URI, 2268b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal Utilities.createDbSelectionQuery( 2269b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal LauncherSettings.Favorites._ID, itemsToRemove), null); 2270b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal if (DEBUG_LOADERS) { 2271b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal Log.d(TAG, "Removed = " + Utilities.createDbSelectionQuery( 2272b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal LauncherSettings.Favorites._ID, itemsToRemove)); 2273b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal } 2274b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal 2275b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal // Remove any empty folder 2276b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal for (long folderId : LauncherAppState.getLauncherProvider() 2277b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal .deleteEmptyFolders()) { 2278b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal sBgWorkspaceItems.remove(sBgFolders.get(folderId)); 2279b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal sBgFolders.remove(folderId); 2280b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal sBgItemsIdMap.remove(folderId); 2281b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2282b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 22838802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler 2284317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal // Sort all the folder items and make sure the first 3 items are high resolution. 2285317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal for (FolderInfo folder : sBgFolders) { 2286317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR); 2287317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal int pos = 0; 2288317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal for (ShortcutInfo info : folder.contents) { 2289317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal if (info.usingLowResIcon) { 2290317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal info.updateIcon(mIconCache, false); 2291317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal } 2292317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal pos ++; 2293317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal if (pos >= FolderIcon.NUM_ITEMS_IN_PREVIEW) { 2294317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal break; 2295317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal } 2296317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal } 2297317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal } 2298317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal 2299f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren if (restoredRows.size() > 0) { 2300f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren // Update restored items that no longer require special handling 2301b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal ContentValues values = new ContentValues(); 2302b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal values.put(LauncherSettings.Favorites.RESTORED, 0); 2303b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal contentResolver.update(LauncherSettings.Favorites.CONTENT_URI, values, 2304b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal Utilities.createDbSelectionQuery( 2305b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal LauncherSettings.Favorites._ID, restoredRows), null); 2306f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 2307f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 2308f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!isSdCardReady && !sPendingPackages.isEmpty()) { 2309f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal context.registerReceiver(new AppsAvailabilityCheck(), 231005e318d8f7d5ea615539d34b181ee44686f1f494Sunny Goyal new IntentFilter(StartupReceiver.SYSTEM_READY), 2311f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal null, sWorker); 2312f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2313f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 231466cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal // Remove any empty screens 231566cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgWorkspaceScreens); 2316e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo item: sBgItemsIdMap) { 231766cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal long screenId = item.screenId; 231866cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 231966cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal unusedScreens.contains(screenId)) { 232066cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal unusedScreens.remove(screenId); 2321dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 232266cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal } 2323dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 232466cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal // If there are any empty screens remove them, and update. 232566cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal if (unusedScreens.size() != 0) { 232666cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal sBgWorkspaceScreens.removeAll(unusedScreens); 232766cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); 2328dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2329dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2330b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (DEBUG_LOADERS) { 2331b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms"); 2332b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "workspace layout: "); 2333dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen int nScreens = occupied.size(); 2334892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung for (int y = 0; y < countY; y++) { 2335b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String line = ""; 2336dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2337e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (int i = 0; i < nScreens; i++) { 2338e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal long screenId = occupied.keyAt(i); 2339c916834ad0da535f08325bcd902a60070f2f7e53Winson Chung if (screenId > 0) { 2340b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung line += " | "; 2341b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2342e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal ItemInfo[][] screen = occupied.valueAt(i); 2343892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung for (int x = 0; x < countX; x++) { 2344aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren if (x < screen.length && y < screen[x].length) { 2345aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren line += (screen[x][y] != null) ? "#" : "."; 2346aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } else { 2347aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren line += "!"; 2348aeff7ea43409d817490fbb8c22b8d4b9725bb54fChris Wren } 23499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 23509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2351b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "[ " + line + " ]"); 23529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 23539c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 23543611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2355e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 2356e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 2357bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal /** 2358bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal * Partially updates the item without any notification. Must be called on the worker thread. 2359bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal */ 2360bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal private void updateItem(long itemId, ContentValues update) { 2361bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal mContext.getContentResolver().update( 23621d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal LauncherSettings.Favorites.CONTENT_URI, 2363bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal update, 2364bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal BaseColumns._ID + "= ?", 2365bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal new String[]{Long.toString(itemId)}); 2366bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } 2367bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal 2368b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of items who are directly or indirectly (via another container) on the 2369b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * specified screen. */ 23709b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung private void filterCurrentWorkspaceItems(long currentScreenId, 2371b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> allWorkspaceItems, 2372b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> currentScreenItems, 2373b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> otherScreenItems) { 23742abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung // Purge any null ItemInfos 23752abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung Iterator<ItemInfo> iter = allWorkspaceItems.iterator(); 23762abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung while (iter.hasNext()) { 23772abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung ItemInfo i = iter.next(); 23782abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (i == null) { 23792abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung iter.remove(); 23802abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung } 23812abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung } 23822abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung 2383b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Order the set of items by their containers first, this allows use to walk through the 2384b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // list sequentially, build up a list of containers that are in the specified screen, 2385b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // as well as all items in those containers. 2386b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Set<Long> itemsOnScreen = new HashSet<Long>(); 2387b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Collections.sort(allWorkspaceItems, new Comparator<ItemInfo>() { 2388b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 2389b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public int compare(ItemInfo lhs, ItemInfo rhs) { 2390b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung return (int) (lhs.container - rhs.container); 2391b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2392b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }); 2393b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo info : allWorkspaceItems) { 2394b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { 23959b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung if (info.screenId == currentScreenId) { 2396b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2397b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2398b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2399b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenItems.add(info); 24003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2401b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 2402b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2403b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2404b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2405b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemsOnScreen.contains(info.container)) { 2406b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2407b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2408b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2409b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenItems.add(info); 24105c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 24115c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 24123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2413b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 24145c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 2415b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of widgets which are on the specified screen. */ 24169b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung private void filterCurrentAppWidgets(long currentScreenId, 2417b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> appWidgets, 2418b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> currentScreenWidgets, 2419b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) { 2420b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2421b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (LauncherAppWidgetInfo widget : appWidgets) { 24222abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (widget == null) continue; 2423b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 24249b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung widget.screenId == currentScreenId) { 2425b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenWidgets.add(widget); 2426b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2427b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenWidgets.add(widget); 2428a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 24299c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 24303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 243131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2432b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of folders which are on the specified screen. */ 24339b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung private void filterCurrentFolders(long currentScreenId, 2434e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal LongArrayMap<ItemInfo> itemsIdMap, 2435e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal LongArrayMap<FolderInfo> folders, 2436e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal LongArrayMap<FolderInfo> currentScreenFolders, 2437e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal LongArrayMap<FolderInfo> otherScreenFolders) { 2438e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal 2439e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal int total = folders.size(); 2440e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (int i = 0; i < total; i++) { 2441e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal long id = folders.keyAt(i); 2442e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal FolderInfo folder = folders.valueAt(i); 24433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 2444b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ItemInfo info = itemsIdMap.get(id); 24452abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (info == null || folder == null) continue; 2446b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 24479b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung info.screenId == currentScreenId) { 2448b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenFolders.put(id, folder); 2449b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2450b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenFolders.put(id, folder); 2451b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 24523611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2453b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 245431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2455b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to 2456b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * right) */ 2457b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) { 2458892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung final LauncherAppState app = LauncherAppState.getInstance(); 24592e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen final InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); 2460b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: review this 2461b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Collections.sort(workspaceItems, new Comparator<ItemInfo>() { 2462db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung @Override 2463db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung public int compare(ItemInfo lhs, ItemInfo rhs) { 24642e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int cellCountX = (int) profile.numColumns; 24652e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen int cellCountY = (int) profile.numRows; 2466db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int screenOffset = cellCountX * cellCountY; 2467db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int containerOffset = screenOffset * (Launcher.SCREEN_COUNT + 1); // +1 hotseat 2468dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long lr = (lhs.container * containerOffset + lhs.screenId * screenOffset + 2469db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung lhs.cellY * cellCountX + lhs.cellX); 2470dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long rr = (rhs.container * containerOffset + rhs.screenId * screenOffset + 2471db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung rhs.cellY * cellCountX + rhs.cellX); 2472db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung return (int) (lr - rr); 2473db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung } 2474db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung }); 2475b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2476db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung 2477dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen private void bindWorkspaceScreens(final Callbacks oldCallbacks, 2478dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ArrayList<Long> orderedScreens) { 2479dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Runnable r = new Runnable() { 2480dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen @Override 2481dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void run() { 2482dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2483dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (callbacks != null) { 2484dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen callbacks.bindScreens(orderedScreens); 2485dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2486dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2487dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen }; 2488d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 2489dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2490dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2491b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void bindWorkspaceItems(final Callbacks oldCallbacks, 2492b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<ItemInfo> workspaceItems, 2493b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<LauncherAppWidgetInfo> appWidgets, 2494e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal final LongArrayMap<FolderInfo> folders, 2495b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<Runnable> deferredBindRunnables) { 2496b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2497b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final boolean postOnMainThread = (deferredBindRunnables != null); 2498603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung 2499b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the workspace items 2500db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int N = workspaceItems.size(); 2501b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int i = 0; i < N; i += ITEMS_CHUNK) { 25023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int start = i; 25033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i); 2504b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 2505b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 25069c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 2507c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 25089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 250964359a53dc827797917a8d9a0697a91996789801Winson Chung callbacks.bindItems(workspaceItems, start, start+chunkSize, 251064359a53dc827797917a8d9a0697a91996789801Winson Chung false); 25119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 25129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2513b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2514b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 2515a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (deferredBindRunnables) { 2516a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk deferredBindRunnables.add(r); 2517a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 2518b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2519d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 25203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2521b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2522b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2523b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the folders 2524b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!folders.isEmpty()) { 2525b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 2526b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 2527b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2528b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 2529b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.bindFolders(folders); 25309c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2531b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2532b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2533b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 2534a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (deferredBindRunnables) { 2535a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk deferredBindRunnables.add(r); 2536a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 2537b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2538d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 25399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 25403611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2541b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2542b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the widgets, one at a time 2543b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung N = appWidgets.size(); 2544b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int i = 0; i < N; i++) { 2545b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final LauncherAppWidgetInfo widget = appWidgets.get(i); 2546b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 2547b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 2548b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2549b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 2550b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.bindAppWidget(widget); 25513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2552b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2553b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2554b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (postOnMainThread) { 2555b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung deferredBindRunnables.add(r); 2556b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2557d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 25583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 25593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2560b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2561b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2562b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** 2563b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * Binds all loaded data to actual views on the main thread. 2564b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung */ 256566cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal private void bindWorkspace(int synchronizeBindPage) { 2566b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final long t = SystemClock.uptimeMillis(); 2567b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Runnable r; 2568b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2569b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Don't use these two variables in any of the callback runnables. 2570b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Otherwise we hold a reference to them. 2571b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Callbacks oldCallbacks = mCallbacks.get(); 2572b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (oldCallbacks == null) { 2573b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // This launcher has exited and nobody bothered to tell us. Just bail. 2574b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.w(TAG, "LoaderTask running with no launcher"); 2575b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung return; 2576b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2577b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 25789b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // Save a copy of all the bg-thread collections 2579b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> workspaceItems = new ArrayList<ItemInfo>(); 2580b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> appWidgets = 2581b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 2582dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ArrayList<Long> orderedScreenIds = new ArrayList<Long>(); 2583e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal 2584e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal final LongArrayMap<FolderInfo> folders; 2585e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal final LongArrayMap<ItemInfo> itemsIdMap; 2586e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal 25872abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 2588b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung workspaceItems.addAll(sBgWorkspaceItems); 2589b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgets.addAll(sBgAppWidgets); 2590dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen orderedScreenIds.addAll(sBgWorkspaceScreens); 2591e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal 2592e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal folders = sBgFolders.clone(); 2593e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal itemsIdMap = sBgItemsIdMap.clone(); 2594b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2595b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 25967aff399974c756930070d82d7b2df88f125dacd6Derek Prothro final boolean isLoadingSynchronously = 25977aff399974c756930070d82d7b2df88f125dacd6Derek Prothro synchronizeBindPage != PagedView.INVALID_RESTORE_PAGE; 2598d8dbb46468e0a8860468661a6edfb7969bfdf0a7Adam Cohen int currScreen = isLoadingSynchronously ? synchronizeBindPage : 25999b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung oldCallbacks.getCurrentWorkspaceScreen(); 2600d8dbb46468e0a8860468661a6edfb7969bfdf0a7Adam Cohen if (currScreen >= orderedScreenIds.size()) { 2601d8dbb46468e0a8860468661a6edfb7969bfdf0a7Adam Cohen // There may be no workspace screens (just hotseat items and an empty page). 26027aff399974c756930070d82d7b2df88f125dacd6Derek Prothro currScreen = PagedView.INVALID_RESTORE_PAGE; 26039b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung } 2604d8dbb46468e0a8860468661a6edfb7969bfdf0a7Adam Cohen final int currentScreen = currScreen; 26057aff399974c756930070d82d7b2df88f125dacd6Derek Prothro final long currentScreenId = currentScreen < 0 26067aff399974c756930070d82d7b2df88f125dacd6Derek Prothro ? INVALID_SCREEN_ID : orderedScreenIds.get(currentScreen); 26079b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung 26089b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // Load all the items that are on the current page first (and in the process, unbind 26099b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // all the existing workspace items before we call startBinding() below. 26109b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung unbindWorkspaceItemsOnMainThread(); 26119b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung 26129b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // Separate the items that are on the current screen, and all the other remaining items 2613b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<ItemInfo>(); 2614b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<ItemInfo>(); 2615b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> currentAppWidgets = 2616b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 2617b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> otherAppWidgets = 2618b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung new ArrayList<LauncherAppWidgetInfo>(); 2619e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal LongArrayMap<FolderInfo> currentFolders = new LongArrayMap<>(); 2620e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal LongArrayMap<FolderInfo> otherFolders = new LongArrayMap<>(); 2621b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 26229b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung filterCurrentWorkspaceItems(currentScreenId, workspaceItems, currentWorkspaceItems, 2623b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherWorkspaceItems); 26249b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung filterCurrentAppWidgets(currentScreenId, appWidgets, currentAppWidgets, 2625b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherAppWidgets); 26269b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung filterCurrentFolders(currentScreenId, itemsIdMap, folders, currentFolders, 2627b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherFolders); 2628b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sortWorkspaceItemsSpatially(currentWorkspaceItems); 2629b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sortWorkspaceItemsSpatially(otherWorkspaceItems); 2630b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2631b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Tell the workspace that we're about to start binding items 2632b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r = new Runnable() { 26333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 26343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 26353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != null) { 2636b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.startBinding(); 26379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 26389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2639b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2640d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 2641b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2642dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen bindWorkspaceScreens(oldCallbacks, orderedScreenIds); 2643dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2644b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Load items on the current page 2645b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, 2646b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentFolders, null); 26471462de39f01cec0ba785386532719cb0207dd827Adam Cohen if (isLoadingSynchronously) { 26481462de39f01cec0ba785386532719cb0207dd827Adam Cohen r = new Runnable() { 26491462de39f01cec0ba785386532719cb0207dd827Adam Cohen public void run() { 26501462de39f01cec0ba785386532719cb0207dd827Adam Cohen Callbacks callbacks = tryGetCallbacks(oldCallbacks); 26517aff399974c756930070d82d7b2df88f125dacd6Derek Prothro if (callbacks != null && currentScreen != PagedView.INVALID_RESTORE_PAGE) { 26521462de39f01cec0ba785386532719cb0207dd827Adam Cohen callbacks.onPageBoundSynchronously(currentScreen); 26531462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 26541462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 26551462de39f01cec0ba785386532719cb0207dd827Adam Cohen }; 2656d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 26571462de39f01cec0ba785386532719cb0207dd827Adam Cohen } 2658b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 26594a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung // Load all the remaining pages (if we are loading synchronously, we want to defer this 26604a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung // work until after the first render) 2661a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 2662a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.clear(); 2663a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 2664b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, otherFolders, 26654a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung (isLoadingSynchronously ? mDeferredBindRunnables : null)); 2666b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2667b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Tell the workspace that we're done binding items 2668b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r = new Runnable() { 26693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2670b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2671b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 267266cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal callbacks.finishBindingItems(); 2673b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2674b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2675639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal mIsLoadingAndBindingWorkspace = false; 2676639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal 2677639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal // Run all the bind complete runnables after workspace is bound. 2678639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal if (!mBindCompleteRunnables.isEmpty()) { 2679639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal synchronized (mBindCompleteRunnables) { 2680639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal for (final Runnable r : mBindCompleteRunnables) { 2681639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal runOnWorkerThread(r); 2682639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2683639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal mBindCompleteRunnables.clear(); 2684639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2685639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2686639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal 268798e030be2abc03e90e9fd9f8bf67e2e01db39cc0Winson Chung // If we're profiling, ensure this is the last thing in the queue. 26883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 26893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound workspace in " 26903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 26919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 269236a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 26939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2694b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 26954a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung if (isLoadingSynchronously) { 2696a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk synchronized (mDeferredBindRunnables) { 2697a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk mDeferredBindRunnables.add(r); 2698a0a7a7440e860c61c8261c5009dbe351869896b3Jason Monk } 26994a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung } else { 2700d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 27014a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung } 27023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 27043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void loadAndBindAllApps() { 27053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 27063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "loadAndBindAllApps mAllAppsLoaded=" + mAllAppsLoaded); 27073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (!mAllAppsLoaded) { 270964359a53dc827797917a8d9a0697a91996789801Winson Chung loadAllApps(); 2710f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal synchronized (LoaderTask.this) { 2711f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal if (mStopped) { 2712f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal return; 2713f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal } 2714f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal } 27154e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal updateIconCache(); 271693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (LoaderTask.this) { 271793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (mStopped) { 271893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee return; 271993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 272093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mAllAppsLoaded = true; 27213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 27233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato onlyBindAllApps(); 27243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 27274e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal private void updateIconCache() { 27284e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal // Ignore packages which have a promise icon. 27294e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal HashSet<String> packagesToIgnore = new HashSet<>(); 27304e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal synchronized (sBgLock) { 27314e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal for (ItemInfo info : sBgItemsIdMap) { 27324e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (info instanceof ShortcutInfo) { 27334e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal ShortcutInfo si = (ShortcutInfo) info; 27344e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (si.isPromise() && si.getTargetComponent() != null) { 27354e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal packagesToIgnore.add(si.getTargetComponent().getPackageName()); 27364e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 27374e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } else if (info instanceof LauncherAppWidgetInfo) { 27384e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal LauncherAppWidgetInfo lawi = (LauncherAppWidgetInfo) info; 27394e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (lawi.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) { 27404e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal packagesToIgnore.add(lawi.providerName.getPackageName()); 27414e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 27424e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 27434e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 27444e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 27454e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal mIconCache.updateDbIcons(packagesToIgnore); 27464e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 27474e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal 27483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void onlyBindAllApps() { 27493611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 27503611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (oldCallbacks == null) { 27513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 27523611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "LoaderTask running with no launcher (onlyBindAllApps)"); 27533611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 27543611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 27563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // shallow copy 2757c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung @SuppressWarnings("unchecked") 2758eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> list 2759eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka = (ArrayList<AppInfo>) mBgAllAppsList.data.clone(); 27609110d485fa12c03df3061278717efb342f1142cfHyunyoung Song final WidgetsModel widgetList = mBgWidgetsModel.clone(); 2761c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung Runnable r = new Runnable() { 27623611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 27633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = SystemClock.uptimeMillis(); 27643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = tryGetCallbacks(oldCallbacks); 27653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != null) { 27663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAllApplications(list); 27679110d485fa12c03df3061278717efb342f1142cfHyunyoung Song callbacks.bindAllPackages(widgetList); 27689c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 27693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 27703611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound all " + list.size() + " apps from cache in " 2771a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 27729c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 27733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2774c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung }; 2775c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung boolean isRunningOnMainThread = !(sWorkerThread.getThreadId() == Process.myTid()); 277664359a53dc827797917a8d9a0697a91996789801Winson Chung if (isRunningOnMainThread) { 2777c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung r.run(); 2778c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung } else { 2779c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung mHandler.post(r); 2780c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung } 27813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 278364359a53dc827797917a8d9a0697a91996789801Winson Chung private void loadAllApps() { 278464359a53dc827797917a8d9a0697a91996789801Winson Chung final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 27853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 27863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 27873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (oldCallbacks == null) { 27883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 278964359a53dc827797917a8d9a0697a91996789801Winson Chung Log.w(TAG, "LoaderTask running with no launcher (loadAllApps)"); 27903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 27919c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 279231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2793ed13187a745866483139e2878037e1f8427ce567Kenny Guy final List<UserHandleCompat> profiles = mUserManager.getUserProfiles(); 2794ed13187a745866483139e2878037e1f8427ce567Kenny Guy 279564359a53dc827797917a8d9a0697a91996789801Winson Chung // Clear the list of apps 279664359a53dc827797917a8d9a0697a91996789801Winson Chung mBgAllAppsList.clear(); 2797ed13187a745866483139e2878037e1f8427ce567Kenny Guy for (UserHandleCompat user : profiles) { 2798ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Query for the set of apps 2799ed13187a745866483139e2878037e1f8427ce567Kenny Guy final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 2800756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal final List<LauncherActivityInfoCompat> apps = mLauncherApps.getActivityList(null, user); 2801ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (DEBUG_LOADERS) { 2802ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "getActivityList took " 2803ed13187a745866483139e2878037e1f8427ce567Kenny Guy + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user); 2804ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user); 2805ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2806ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Fail if we don't have any apps 2807e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // TODO: Fix this. Only fail for the current user. 2808ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (apps == null || apps.isEmpty()) { 2809ed13187a745866483139e2878037e1f8427ce567Kenny Guy return; 2810ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 28114fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 2812ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Create the ApplicationInfos 2813ed13187a745866483139e2878037e1f8427ce567Kenny Guy for (int i = 0; i < apps.size(); i++) { 2814ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherActivityInfoCompat app = apps.get(i); 2815ed13187a745866483139e2878037e1f8427ce567Kenny Guy // This builds the icon bitmaps. 28164fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mBgAllAppsList.add(new AppInfo(mContext, app, user, mIconCache)); 2817ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2818e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 2819756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal final ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(mContext, user); 2820756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal if (heuristic != null) { 2821639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal final Runnable r = new Runnable() { 2822756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal 2823756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal @Override 2824756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal public void run() { 2825756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal heuristic.processUserApps(apps); 2826756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal } 2827639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal }; 2828639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal runOnMainThread(new Runnable() { 2829639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal 2830639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal @Override 2831639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal public void run() { 2832639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal // Check isLoadingWorkspace on the UI thread, as it is updated on 2833639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal // the UI thread. 2834639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal if (mIsLoadingAndBindingWorkspace) { 2835639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal synchronized (mBindCompleteRunnables) { 2836639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal mBindCompleteRunnables.add(r); 2837639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2838639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } else { 2839639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal runOnWorkerThread(r); 2840639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2841639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2842756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal }); 2843e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 284464359a53dc827797917a8d9a0697a91996789801Winson Chung } 284585f418d0f5607c66efef1673075a6d3486e5af83Bjorn Bringert // Huh? Shouldn't this be inside the Runnable below? 2846eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> added = mBgAllAppsList.added; 2847eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka mBgAllAppsList.added = new ArrayList<AppInfo>(); 28483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 284964359a53dc827797917a8d9a0697a91996789801Winson Chung // Post callback on main thread 285064359a53dc827797917a8d9a0697a91996789801Winson Chung mHandler.post(new Runnable() { 285164359a53dc827797917a8d9a0697a91996789801Winson Chung public void run() { 28529892e5874061233dec57107d1d3d7d5d8e1f5d93Hyunyoung Song 285364359a53dc827797917a8d9a0697a91996789801Winson Chung final long bindTime = SystemClock.uptimeMillis(); 285411a1a53651924b544513f1f6971a735b18d67539Winson Chung final Callbacks callbacks = tryGetCallbacks(oldCallbacks); 285564359a53dc827797917a8d9a0697a91996789801Winson Chung if (callbacks != null) { 285664359a53dc827797917a8d9a0697a91996789801Winson Chung callbacks.bindAllApplications(added); 28573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 285864359a53dc827797917a8d9a0697a91996789801Winson Chung Log.d(TAG, "bound " + added.size() + " apps in " 285964359a53dc827797917a8d9a0697a91996789801Winson Chung + (SystemClock.uptimeMillis() - bindTime) + "ms"); 28603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 286164359a53dc827797917a8d9a0697a91996789801Winson Chung } else { 286264359a53dc827797917a8d9a0697a91996789801Winson Chung Log.i(TAG, "not binding apps: no Launcher activity"); 286364359a53dc827797917a8d9a0697a91996789801Winson Chung } 28643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 286564359a53dc827797917a8d9a0697a91996789801Winson Chung }); 286618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal // Cleanup any data stored for a deleted user. 286718bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal ManagedProfileHeuristic.processAllUsers(profiles, mContext); 2868cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 28692d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal loadAndBindWidgetsAndShortcuts(tryGetCallbacks(oldCallbacks), true /* refresh */); 28703611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 287164359a53dc827797917a8d9a0697a91996789801Winson Chung Log.d(TAG, "Icons processed in " 287264359a53dc827797917a8d9a0697a91996789801Winson Chung + (SystemClock.uptimeMillis() - loadTime) + "ms"); 28733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 28743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2875dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 287675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void dumpState() { 287775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal synchronized (sBgLock) { 287875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Log.d(TAG, "mLoaderTask.mContext=" + mContext); 287975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Log.d(TAG, "mLoaderTask.mStopped=" + mStopped); 288075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Log.d(TAG, "mLoaderTask.mLoadAndBindStepFinished=" + mLoadAndBindStepFinished); 288175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Log.d(TAG, "mItems size=" + sBgWorkspaceItems.size()); 288275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 288375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 288475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 288577919b93b98f5afa1b39546861197d6065847224Sunny Goyal 288675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal /** 288775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal * Called when the icons for packages have been updated in the icon cache. 288875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal */ 288975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void onPackageIconsUpdated(HashSet<String> updatedPackages, UserHandleCompat user) { 289075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal final Callbacks callbacks = getCallback(); 289175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal final ArrayList<AppInfo> updatedApps = new ArrayList<>(); 289275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal final ArrayList<ShortcutInfo> updatedShortcuts = new ArrayList<>(); 289377919b93b98f5afa1b39546861197d6065847224Sunny Goyal 289475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // If any package icon has changed (app was updated while launcher was dead), 289575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // update the corresponding shortcuts. 289675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal synchronized (sBgLock) { 289775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal for (ItemInfo info : sBgItemsIdMap) { 289875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (info instanceof ShortcutInfo && user.equals(info.user) 289975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 290075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal ShortcutInfo si = (ShortcutInfo) info; 290175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal ComponentName cn = si.getTargetComponent(); 290275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (cn != null && updatedPackages.contains(cn.getPackageName())) { 290375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal si.updateIcon(mIconCache); 290475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal updatedShortcuts.add(si); 290577919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 290677919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 290777919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 290875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mBgAllAppsList.updateIconsAndLabels(updatedPackages, user, updatedApps); 290975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 291077919b93b98f5afa1b39546861197d6065847224Sunny Goyal 291175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (!updatedShortcuts.isEmpty()) { 291275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal final UserHandleCompat userFinal = user; 291375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mHandler.post(new Runnable() { 291475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 291575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void run() { 291675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Callbacks cb = getCallback(); 291775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (cb != null && callbacks == cb) { 291875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal cb.bindShortcutsChanged(updatedShortcuts, 291975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal new ArrayList<ShortcutInfo>(), userFinal); 292077919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 292175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 292275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal }); 292377919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 292477919b93b98f5afa1b39546861197d6065847224Sunny Goyal 292575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (!updatedApps.isEmpty()) { 292675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mHandler.post(new Runnable() { 292775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 292875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void run() { 292975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Callbacks cb = getCallback(); 293075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (cb != null && callbacks == cb) { 293175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal cb.bindAppsUpdated(updatedApps); 293275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 293375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 293475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal }); 29353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2936091f0ffd929f7a0a9a6af7d202eae13c48c07daaSunny Goyal 2937091f0ffd929f7a0a9a6af7d202eae13c48c07daaSunny Goyal // Reload widget list. No need to refresh, as we only want to update the icons and labels. 29382d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal loadAndBindWidgetsAndShortcuts(callbacks, false); 29393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 294031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato void enqueuePackageUpdated(PackageUpdatedTask task) { 2942700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick sWorker.post(task); 29433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2944d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 2945091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk class AppsAvailabilityCheck extends BroadcastReceiver { 2946f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 2947f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal @Override 2948f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal public void onReceive(Context context, Intent intent) { 2949f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal synchronized (sBgLock) { 2950f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal final LauncherAppsCompat launcherApps = LauncherAppsCompat 2951f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal .getInstance(mApp.getContext()); 29521a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final PackageManager manager = context.getPackageManager(); 29531a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final ArrayList<String> packagesRemoved = new ArrayList<String>(); 29541a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final ArrayList<String> packagesUnavailable = new ArrayList<String>(); 2955f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal for (Entry<UserHandleCompat, HashSet<String>> entry : sPendingPackages.entrySet()) { 2956f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal UserHandleCompat user = entry.getKey(); 29571a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesRemoved.clear(); 29581a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.clear(); 2959f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal for (String pkg : entry.getValue()) { 2960f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!launcherApps.isPackageEnabledForProfile(pkg, user)) { 29611a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal boolean packageOnSdcard = launcherApps.isAppEnabled( 29621a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal manager, pkg, PackageManager.GET_UNINSTALLED_PACKAGES); 29631a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (packageOnSdcard) { 29641a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal Launcher.addDumpLog(TAG, "Package found on sd-card: " + pkg, true); 29651a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.add(pkg); 29661a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else { 29671a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal Launcher.addDumpLog(TAG, "Package not found: " + pkg, true); 29681a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesRemoved.add(pkg); 29691a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 2970f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2971f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2972f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!packagesRemoved.isEmpty()) { 2973f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_REMOVE, 2974f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal packagesRemoved.toArray(new String[packagesRemoved.size()]), user)); 2975f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 29761a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (!packagesUnavailable.isEmpty()) { 29771a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_UNAVAILABLE, 29781a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.toArray(new String[packagesUnavailable.size()]), user)); 29791a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 2980f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2981349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal sPendingPackages.clear(); 2982f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2983f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2984f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2985f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 29863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private class PackageUpdatedTask implements Runnable { 29873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int mOp; 29883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato String[] mPackages; 2989ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat mUser; 2990d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 29913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_NONE = 0; 29923611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_ADD = 1; 29933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_UPDATE = 2; 29943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_REMOVE = 3; // uninstlled 29953611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_UNAVAILABLE = 4; // external media unmounted 299631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2997d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 2998ed13187a745866483139e2878037e1f8427ce567Kenny Guy public PackageUpdatedTask(int op, String[] packages, UserHandleCompat user) { 29993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mOp = op; 30003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mPackages = packages; 3001ed13187a745866483139e2878037e1f8427ce567Kenny Guy mUser = user; 30023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3003d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 30043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 3005c905efc89cd8a391ae73f36d356c907b4aaf1bf0Sunny Goyal if (!mHasLoaderCompletedOnce) { 3006c905efc89cd8a391ae73f36d356c907b4aaf1bf0Sunny Goyal // Loader has not yet run. 3007c905efc89cd8a391ae73f36d356c907b4aaf1bf0Sunny Goyal return; 3008c905efc89cd8a391ae73f36d356c907b4aaf1bf0Sunny Goyal } 3009cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler final Context context = mApp.getContext(); 3010dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 30113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String[] packages = mPackages; 30123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int N = packages.length; 30133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato switch (mOp) { 301418bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal case OP_ADD: { 30153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.addPackage " + packages[i]); 30174fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mIconCache.updateIconsForPkg(packages[i], mUser); 3018ed13187a745866483139e2878037e1f8427ce567Kenny Guy mBgAllAppsList.addPackage(context, packages[i], mUser); 3019dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 3020e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 302118bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(context, mUser); 302218bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal if (heuristic != null) { 302318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal heuristic.processPackageAdd(mPackages); 3024e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 30253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 302618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal } 30273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_UPDATE: 30283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.updatePackage " + packages[i]); 30304fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mIconCache.updateIconsForPkg(packages[i], mUser); 3031ed13187a745866483139e2878037e1f8427ce567Kenny Guy mBgAllAppsList.updatePackage(context, packages[i], mUser); 30325b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal mApp.getWidgetCache().removePackage(packages[i], mUser); 30333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 30343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 303518bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal case OP_REMOVE: { 303618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(context, mUser); 303718bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal if (heuristic != null) { 303818bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal heuristic.processPackageRemoved(mPackages); 3039e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 30404fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal for (int i=0; i<N; i++) { 30414fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]); 30424fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mIconCache.removeIconsForPkg(packages[i], mUser); 30434fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3044e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Fall through 304518bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal } 30463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_UNAVAILABLE: 30473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]); 30494fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mBgAllAppsList.removePackage(packages[i], mUser); 30505b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal mApp.getWidgetCache().removePackage(packages[i], mUser); 30513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 30523611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 30533611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3054dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 3055eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka ArrayList<AppInfo> added = null; 3056eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka ArrayList<AppInfo> modified = null; 3057eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> removedApps = new ArrayList<AppInfo>(); 30583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 3059487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mBgAllAppsList.added.size() > 0) { 3060eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka added = new ArrayList<AppInfo>(mBgAllAppsList.added); 30615d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.added.clear(); 30623611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3063487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mBgAllAppsList.modified.size() > 0) { 3064eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka modified = new ArrayList<AppInfo>(mBgAllAppsList.modified); 30655d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.modified.clear(); 30663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 30675d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung if (mBgAllAppsList.removed.size() > 0) { 306883892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung removedApps.addAll(mBgAllAppsList.removed); 30695d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.removed.clear(); 3070cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung } 3071cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung 3072e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final Callbacks callbacks = getCallback(); 30733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks == null) { 30743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "Nobody to tell about the new app. Launcher is probably loading."); 30753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 3076be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 3077be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 30784390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final HashMap<ComponentName, AppInfo> addedOrUpdatedApps = 30794390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal new HashMap<ComponentName, AppInfo>(); 30804390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 30813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (added != null) { 3082c9acdd51c40c1b397adae6ba62c4acd01914b473Sunny Goyal addAppsToAllApps(context, added); 30834390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal for (AppInfo ai : added) { 30844390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal addedOrUpdatedApps.put(ai.componentName, ai); 30854390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 30863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 308776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 30883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (modified != null) { 3089eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> modifiedFinal = modified; 30904390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal for (AppInfo ai : modified) { 30914390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal addedOrUpdatedApps.put(ai.componentName, ai); 309264359a53dc827797917a8d9a0697a91996789801Winson Chung } 309364359a53dc827797917a8d9a0697a91996789801Winson Chung 30943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 30953611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 3096e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3097cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 30983611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAppsUpdated(modifiedFinal); 30993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 31003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 31013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 31023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3103780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung 31044390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Update shortcut infos 3105b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (mOp == OP_ADD || mOp == OP_UPDATE) { 31064390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<ShortcutInfo> updatedShortcuts = new ArrayList<ShortcutInfo>(); 31074390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<ShortcutInfo> removedShortcuts = new ArrayList<ShortcutInfo>(); 31084390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<LauncherAppWidgetInfo> widgets = new ArrayList<LauncherAppWidgetInfo>(); 31094390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 3110b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal HashSet<String> packageSet = new HashSet<String>(Arrays.asList(packages)); 3111b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal synchronized (sBgLock) { 3112e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo info : sBgItemsIdMap) { 3113b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (info instanceof ShortcutInfo && mUser.equals(info.user)) { 3114b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal ShortcutInfo si = (ShortcutInfo) info; 31154390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal boolean infoUpdated = false; 31164390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal boolean shortcutUpdated = false; 31174390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31184390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Update shortcuts which use iconResource. 3119b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if ((si.iconResource != null) 31204390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && packageSet.contains(si.iconResource.packageName)) { 312153d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal Bitmap icon = Utilities.createIconBitmap( 312253d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal si.iconResource.packageName, 312353d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal si.iconResource.resourceName, context); 3124b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (icon != null) { 3125b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal si.setIcon(icon); 3126b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal si.usingFallbackIcon = false; 31274390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 3128b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3129b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 31304390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31314390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ComponentName cn = si.getTargetComponent(); 31324390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (cn != null && packageSet.contains(cn.getPackageName())) { 31334390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal AppInfo appInfo = addedOrUpdatedApps.get(cn); 31344390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31354390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (si.isPromise()) { 31364390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) { 31374390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Auto install icon 31384390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal PackageManager pm = context.getPackageManager(); 31394390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ResolveInfo matched = pm.resolveActivity( 31404390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal new Intent(Intent.ACTION_MAIN) 31414390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER), 31424390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal PackageManager.MATCH_DEFAULT_ONLY); 31434390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (matched == null) { 31444390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Try to find the best match activity. 31454390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal Intent intent = pm.getLaunchIntentForPackage( 31464390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal cn.getPackageName()); 31474390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (intent != null) { 31484390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal cn = intent.getComponent(); 31494390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal appInfo = addedOrUpdatedApps.get(cn); 31504390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31514390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31524390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if ((intent == null) || (appInfo == null)) { 31534390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal removedShortcuts.add(si); 31544390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal continue; 31554390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31564390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.promisedIntent = intent; 31574390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31584390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31594390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31604390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Restore the shortcut. 3161fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal if (appInfo != null) { 3162fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal si.flags = appInfo.flags; 3163fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal } 31644390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 3165756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.intent = si.promisedIntent; 3166756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.promisedIntent = null; 3167756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.status = ShortcutInfo.DEFAULT; 31684390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 31694390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.updateIcon(mIconCache); 31704390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31714390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31724390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction()) 31734390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 31744390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.updateIcon(mIconCache); 317582b016cb56540fe26213e817dd0dd668099c8e20Winson Chung si.title = Utilities.trim(appInfo.title); 31764390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.contentDescription = appInfo.contentDescription; 31774390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 31784390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31794390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31804390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if ((si.isDisabled & ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE) != 0) { 31814390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Since package was just updated, the target must be available now. 31824390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.isDisabled &= ~ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; 31834390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal shortcutUpdated = true; 31844390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31854390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31864390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31874390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (infoUpdated || shortcutUpdated) { 31884390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updatedShortcuts.add(si); 31894390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31904390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (infoUpdated) { 31914390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updateItemInDatabase(context, si); 31924390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31934390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } else if (info instanceof LauncherAppWidgetInfo) { 31944390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info; 31954390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (mUser.equals(widgetInfo.user) 31964390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) 31974390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && packageSet.contains(widgetInfo.providerName.getPackageName())) { 319853f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal widgetInfo.restoreStatus &= 319953f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY & 320053f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; 320184b4adc3fb2301466468828ccbd742209619e597Sunny Goyal 320284b4adc3fb2301466468828ccbd742209619e597Sunny Goyal // adding this flag ensures that launcher shows 'click to setup' 320384b4adc3fb2301466468828ccbd742209619e597Sunny Goyal // if the widget has a config activity. In case there is no config 320484b4adc3fb2301466468828ccbd742209619e597Sunny Goyal // activity, it will be marked as 'restored' during bind. 320584b4adc3fb2301466468828ccbd742209619e597Sunny Goyal widgetInfo.restoreStatus |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY; 320684b4adc3fb2301466468828ccbd742209619e597Sunny Goyal 32074390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal widgets.add(widgetInfo); 32084390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updateItemInDatabase(context, widgetInfo); 32094390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 3210b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3211b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3212b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3213b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal 32144390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (!updatedShortcuts.isEmpty() || !removedShortcuts.isEmpty()) { 3215b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal mHandler.post(new Runnable() { 32164390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 3217b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal public void run() { 3218e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3219b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (callbacks == cb && cb != null) { 32204390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal callbacks.bindShortcutsChanged( 32214390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updatedShortcuts, removedShortcuts, mUser); 32224390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32234390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32244390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal }); 32254390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (!removedShortcuts.isEmpty()) { 32264390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal deleteItemsFromDatabase(context, removedShortcuts); 32274390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32284390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32294390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (!widgets.isEmpty()) { 32304390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal mHandler.post(new Runnable() { 32314390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void run() { 3232e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 32334390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (callbacks == cb && cb != null) { 32344390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal callbacks.bindWidgetsRestored(widgets); 3235b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3236b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3237b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal }); 3238b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3239b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3240b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal 3241df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung final ArrayList<String> removedPackageNames = 3242df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung new ArrayList<String>(); 32431a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (mOp == OP_REMOVE || mOp == OP_UNAVAILABLE) { 3244df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Mark all packages in the broadcast to be removed 3245df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung removedPackageNames.addAll(Arrays.asList(packages)); 3246df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } else if (mOp == OP_UPDATE) { 3247df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Mark disabled packages in the broadcast to be removed 3248df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung for (int i=0; i<N; i++) { 3249ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (isPackageDisabled(context, packages[i], mUser)) { 3250df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung removedPackageNames.add(packages[i]); 325164359a53dc827797917a8d9a0697a91996789801Winson Chung } 325264359a53dc827797917a8d9a0697a91996789801Winson Chung } 3253df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } 32541a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 3255df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung if (!removedPackageNames.isEmpty() || !removedApps.isEmpty()) { 32561a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final int removeReason; 32571a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (mOp == OP_UNAVAILABLE) { 32581a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal removeReason = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; 32591a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else { 32601a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Remove all the components associated with this package 32611a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal for (String pn : removedPackageNames) { 32621a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal deletePackageFromDatabase(context, pn, mUser); 32631a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 32641a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Remove all the specific components 32651a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal for (AppInfo a : removedApps) { 32661a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal ArrayList<ItemInfo> infos = getItemInfoForComponentName(a.componentName, mUser); 32671a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal deleteItemsFromDatabase(context, infos); 32681a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 32691a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal removeReason = 0; 32701a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 32711a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 3272df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Remove any queued items from the install queue 3273e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal InstallShortcutReceiver.removeFromInstallQueue(context, removedPackageNames, mUser); 3274df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Call the components-removed callback 32753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 32763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 3277e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3278cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 32791a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal callbacks.bindComponentsRemoved( 32801a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal removedPackageNames, removedApps, mUser, removeReason); 32813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 32823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 32833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 3284be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 3285227239e7c05d26c4098980b991d3472077c01ccbHyunyoung Song 32862d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal // Update widgets 32872d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal if (mOp == OP_ADD || mOp == OP_REMOVE || mOp == OP_UPDATE) { 32882d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal // Always refresh for a package event on secondary user 32892d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal boolean needToRefresh = !mUser.equals(UserHandleCompat.myUserHandle()); 32902d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal 32912d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal // Refresh widget list, if the package already had a widget. 32922d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal synchronized (sBgLock) { 32932d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal if (sBgWidgetProviders != null) { 32942d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal HashSet<String> pkgSet = new HashSet<>(); 32952d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal Collections.addAll(pkgSet, mPackages); 32962d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal 32972d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal for (ComponentKey key : sBgWidgetProviders.keySet()) { 32982d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal needToRefresh |= key.user.equals(mUser) && 32992d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal pkgSet.contains(key.componentName.getPackageName()); 33002d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal } 33012d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal } 33022d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal } 33032d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal 33042d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal if (!needToRefresh && mOp != OP_REMOVE) { 33052d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal // Refresh widget list, if there is any newly added widget 33062d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal PackageManager pm = context.getPackageManager(); 33072d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal for (String pkg : mPackages) { 33082d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal needToRefresh |= !pm.queryBroadcastReceivers( 33092d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE) 33102d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal .setPackage(pkg), 0).isEmpty(); 33112d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal } 33122d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal } 33132d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal 33142d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal loadAndBindWidgetsAndShortcuts(callbacks, needToRefresh); 33152d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal } 3316227239e7c05d26c4098980b991d3472077c01ccbHyunyoung Song 33174caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen // Write all the logs to disk 33184caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen mHandler.post(new Runnable() { 33194caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen public void run() { 3320e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 33214caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen if (callbacks == cb && cb != null) { 3322ede4129e77f8347e32c0da9c615bcff2cbc06fd8Winson Chung callbacks.dumpLogsToLocalData(); 33234caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen } 33244caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen } 332580baf5a6b3c62a62265f626d43d1167783c94131Winson Chung }); 332631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 332731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 332831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 332970a48befe48af0a318e88745f480d2ed42936bb5Hyunyoung Song public static List<LauncherAppWidgetProviderInfo> getWidgetProviders(Context context, 333070a48befe48af0a318e88745f480d2ed42936bb5Hyunyoung Song boolean refresh) { 33313abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song ArrayList<LauncherAppWidgetProviderInfo> results = 33323abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song new ArrayList<LauncherAppWidgetProviderInfo>(); 33333abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song try { 33343abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song synchronized (sBgLock) { 33353abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song if (sBgWidgetProviders == null || refresh) { 33363abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song HashMap<ComponentKey, LauncherAppWidgetProviderInfo> tmpWidgetProviders 33373abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song = new HashMap<>(); 33383abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song AppWidgetManagerCompat wm = AppWidgetManagerCompat.getInstance(context); 33393abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song LauncherAppWidgetProviderInfo info; 33403abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song 33413abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song List<AppWidgetProviderInfo> widgets = wm.getAllProviders(); 33423abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song for (AppWidgetProviderInfo pInfo : widgets) { 33433abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song info = LauncherAppWidgetProviderInfo.fromProviderInfo(context, pInfo); 33443abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song UserHandleCompat user = wm.getUser(info); 33453abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song tmpWidgetProviders.put(new ComponentKey(info.provider, user), info); 33463abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song } 33475940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 33483abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song Collection<CustomAppWidget> customWidgets = Launcher.getCustomAppWidgets().values(); 33493abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song for (CustomAppWidget widget : customWidgets) { 33503abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song info = new LauncherAppWidgetProviderInfo(context, widget); 33513abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song UserHandleCompat user = wm.getUser(info); 33523abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song tmpWidgetProviders.put(new ComponentKey(info.provider, user), info); 33533abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song } 33543abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song // Replace the global list at the very end, so that if there is an exception, 33553abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song // previously loaded provider list is used. 33563abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song sBgWidgetProviders = tmpWidgetProviders; 33573abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song } 33583abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song results.addAll(sBgWidgetProviders.values()); 33593abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song return results; 33603abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song } 33613abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song } catch (Exception e) { 33623abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song if (e.getCause() instanceof TransactionTooLargeException) { 33633abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song // the returned value may be incomplete and will not be refreshed until the next 33643abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song // time Launcher starts. 33653abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song // TODO: after figuring out a repro step, introduce a dirty bit to check when 33663abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song // onResume is called to refresh the widget provider list. 33673abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song synchronized (sBgLock) { 33683abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song if (sBgWidgetProviders != null) { 33693abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song results.addAll(sBgWidgetProviders.values()); 33703abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song } 33713abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song return results; 337226ace12135a662ad864678c9fede9817e5c02b67Robin Lee } 33733abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song } else { 33743abd5488cca5b06c97251db453a5a6ed61e33ce8Hyunyoung Song throw e; 33755940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33765940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33775940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33785940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 337926ace12135a662ad864678c9fede9817e5c02b67Robin Lee public static LauncherAppWidgetProviderInfo getProviderInfo(Context ctx, ComponentName name, 338026ace12135a662ad864678c9fede9817e5c02b67Robin Lee UserHandleCompat user) { 33815940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen synchronized (sBgLock) { 33825940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (sBgWidgetProviders == null) { 338370a48befe48af0a318e88745f480d2ed42936bb5Hyunyoung Song getWidgetProviders(ctx, false /* refresh */); 33845940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 338526ace12135a662ad864678c9fede9817e5c02b67Robin Lee return sBgWidgetProviders.get(new ComponentKey(name, user)); 33865940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33875940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 33885940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 33892d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal public void loadAndBindWidgetsAndShortcuts(final Callbacks callbacks, final boolean refresh) { 33909110d485fa12c03df3061278717efb342f1142cfHyunyoung Song 3391eaf291b9feba4e332d258b6d53ff119c88dc0d39Hyunyoung Song runOnWorkerThread(new Runnable() { 3392d4af1484447129d489203130e0d654f81a10437dHyunyoung Song @Override 3393d4af1484447129d489203130e0d654f81a10437dHyunyoung Song public void run() { 33942d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal updateWidgetsModel(refresh); 3395eaf291b9feba4e332d258b6d53ff119c88dc0d39Hyunyoung Song final WidgetsModel model = mBgWidgetsModel.clone(); 3396eaf291b9feba4e332d258b6d53ff119c88dc0d39Hyunyoung Song 3397d4af1484447129d489203130e0d654f81a10437dHyunyoung Song mHandler.post(new Runnable() { 3398d4af1484447129d489203130e0d654f81a10437dHyunyoung Song @Override 3399d4af1484447129d489203130e0d654f81a10437dHyunyoung Song public void run() { 3400d4af1484447129d489203130e0d654f81a10437dHyunyoung Song Callbacks cb = getCallback(); 3401d4af1484447129d489203130e0d654f81a10437dHyunyoung Song if (callbacks == cb && cb != null) { 34022bd3d7d1cb5e4d8d826982d11b456739fed6b817Hyunyoung Song callbacks.bindAllPackages(model); 3403d4af1484447129d489203130e0d654f81a10437dHyunyoung Song } 3404d4af1484447129d489203130e0d654f81a10437dHyunyoung Song } 3405d4af1484447129d489203130e0d654f81a10437dHyunyoung Song }); 34068821ca9a6a5bf34308f9b70c2cabf9da17330497Hyunyoung Song // update the Widget entries inside DB on the worker thread. 34072bd3d7d1cb5e4d8d826982d11b456739fed6b817Hyunyoung Song LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews( 34082bd3d7d1cb5e4d8d826982d11b456739fed6b817Hyunyoung Song model.getRawList()); 3409d4af1484447129d489203130e0d654f81a10437dHyunyoung Song } 3410d4af1484447129d489203130e0d654f81a10437dHyunyoung Song }); 3411d4af1484447129d489203130e0d654f81a10437dHyunyoung Song } 3412d4af1484447129d489203130e0d654f81a10437dHyunyoung Song 34138821ca9a6a5bf34308f9b70c2cabf9da17330497Hyunyoung Song /** 34149110d485fa12c03df3061278717efb342f1142cfHyunyoung Song * Returns a list of ResolveInfos/AppWidgetInfos. 34158821ca9a6a5bf34308f9b70c2cabf9da17330497Hyunyoung Song * 34169110d485fa12c03df3061278717efb342f1142cfHyunyoung Song * @see #loadAndBindWidgetsAndShortcuts 34178821ca9a6a5bf34308f9b70c2cabf9da17330497Hyunyoung Song */ 34182d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal @Thunk void updateWidgetsModel(boolean refresh) { 34192d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal PackageManager packageManager = mApp.getContext().getPackageManager(); 3420c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka final ArrayList<Object> widgetsAndShortcuts = new ArrayList<Object>(); 34212d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal widgetsAndShortcuts.addAll(getWidgetProviders(mApp.getContext(), refresh)); 3422c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); 3423c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka widgetsAndShortcuts.addAll(packageManager.queryIntentActivities(shortcutsIntent, 0)); 3424eaf291b9feba4e332d258b6d53ff119c88dc0d39Hyunyoung Song mBgWidgetsModel.setWidgetsAndShortcuts(widgetsAndShortcuts); 3425c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka } 3426c402cd9992d431b6beacdf3c75e31cf103e230cbMichael Jurka 3427091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static boolean isPackageDisabled(Context context, String packageName, 3428ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user) { 3429ed13187a745866483139e2878037e1f8427ce567Kenny Guy final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3430ed13187a745866483139e2878037e1f8427ce567Kenny Guy return !launcherApps.isPackageEnabledForProfile(packageName, user); 3431df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } 3432556f6135f992dcd5bfbfffe0172627bfbf57d24eAdam Cohen 3433ed13187a745866483139e2878037e1f8427ce567Kenny Guy public static boolean isValidPackageActivity(Context context, ComponentName cn, 3434ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user) { 3435ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung if (cn == null) { 3436ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung return false; 3437ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3438ed13187a745866483139e2878037e1f8427ce567Kenny Guy final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3439ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!launcherApps.isPackageEnabledForProfile(cn.getPackageName(), user)) { 3440ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung return false; 3441ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3442ed13187a745866483139e2878037e1f8427ce567Kenny Guy return launcherApps.isActivityEnabledForProfile(cn, user); 3443ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3444ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung 3445a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen public static boolean isValidPackage(Context context, String packageName, 3446a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen UserHandleCompat user) { 3447a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen if (packageName == null) { 3448a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen return false; 3449a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen } 3450a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3451a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen return launcherApps.isPackageEnabledForProfile(packageName, user); 3452a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen } 3453a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen 34549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 3455f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * Make an ShortcutInfo object for a restored application or shortcut item that points 3456f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * to a package that is not yet installed on the system. 3457f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren */ 34584e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal public ShortcutInfo getRestoredItemInfo(Cursor c, int titleIndex, Intent intent, 3459c22841bfd1961781a84cfccb98d1c2937a9adee4Sunny Goyal int promiseType, int itemType, CursorIconInfo iconInfo, Context context) { 3460f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren final ShortcutInfo info = new ShortcutInfo(); 3461349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.user = UserHandleCompat.myUserHandle(); 34624e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal 34634e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal Bitmap icon = iconInfo.loadIcon(c, info, context); 34644e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal // the fallback icon 34654e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (icon == null) { 34664e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal mIconCache.getTitleAndIcon(info, intent, info.user, false /* useLowResIcon */); 34674e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } else { 34684e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal info.setIcon(icon); 34694e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 3470349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 3471349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) { 34724e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal String title = (c != null) ? c.getString(titleIndex) : null; 3473349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (!TextUtils.isEmpty(title)) { 347482b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.title = Utilities.trim(title); 3475349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 3476349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } else if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { 3477349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (TextUtils.isEmpty(info.title)) { 34784e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal info.title = (c != null) ? Utilities.trim(c.getString(titleIndex)) : ""; 3479349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 3480f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } else { 3481349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal throw new InvalidParameterException("Invalid restoreType " + promiseType); 3482f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3483349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 348482b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); 3485c22841bfd1961781a84cfccb98d1c2937a9adee4Sunny Goyal info.itemType = itemType; 3486349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.promisedIntent = intent; 3487756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal info.status = promiseType; 3488f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren return info; 3489f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3490f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 3491f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren /** 3492f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * Make an Intent object for a restored application or shortcut item that points 3493f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * to the market page for the item. 3494f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren */ 3495091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Intent getRestoredItemIntent(Cursor c, Context context, Intent intent) { 3496f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren ComponentName componentName = intent.getComponent(); 3497e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return getMarketIntent(componentName.getPackageName()); 3498e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 3499e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 3500e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal static Intent getMarketIntent(String packageName) { 3501e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return new Intent(Intent.ACTION_VIEW) 3502e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .setData(new Uri.Builder() 3503f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren .scheme("market") 3504f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren .authority("details") 3505e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .appendQueryParameter("id", packageName) 3506e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .build()); 3507f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3508f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 3509f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren /** 351056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * Make an ShortcutInfo object for a shortcut that is an application. 351156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * 351256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * If c is not null, then it will be used to fill in missing data like the title and icon. 351356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato */ 35144fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal public ShortcutInfo getAppShortcutInfo(PackageManager manager, Intent intent, 3515ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user, Context context, Cursor c, int iconIndex, int titleIndex, 351634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal boolean allowMissingTarget, boolean useLowResIcon) { 3517ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user == null) { 3518ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "Null user found in getShortcutInfo"); 3519ed13187a745866483139e2878037e1f8427ce567Kenny Guy return null; 3520ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3521ed13187a745866483139e2878037e1f8427ce567Kenny Guy 352256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato ComponentName componentName = intent.getComponent(); 3523ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (componentName == null) { 3524ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "Missing component found in getShortcutInfo: " + componentName); 35259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 352631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 352731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3528ed13187a745866483139e2878037e1f8427ce567Kenny Guy Intent newIntent = new Intent(intent.getAction(), null); 3529ed13187a745866483139e2878037e1f8427ce567Kenny Guy newIntent.addCategory(Intent.CATEGORY_LAUNCHER); 3530ed13187a745866483139e2878037e1f8427ce567Kenny Guy newIntent.setComponent(componentName); 3531ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherActivityInfoCompat lai = mLauncherApps.resolveActivity(newIntent, user); 3532f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if ((lai == null) && !allowMissingTarget) { 3533ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "Missing activity found in getShortcutInfo: " + componentName); 3534ed13187a745866483139e2878037e1f8427ce567Kenny Guy return null; 3535ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3536ed13187a745866483139e2878037e1f8427ce567Kenny Guy 3537ed13187a745866483139e2878037e1f8427ce567Kenny Guy final ShortcutInfo info = new ShortcutInfo(); 353834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal mIconCache.getTitleAndIcon(info, componentName, lai, user, false, useLowResIcon); 35394fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (mIconCache.isDefaultIcon(info.getIcon(mIconCache), user) && c != null) { 35404fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal Bitmap icon = Utilities.createIconBitmap(c, iconIndex, context); 35414fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal info.setIcon(icon == null ? mIconCache.getDefaultIcon(user) : icon); 3542ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3543ed13187a745866483139e2878037e1f8427ce567Kenny Guy 354456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the db 35454fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (TextUtils.isEmpty(info.title) && c != null) { 354682b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.title = Utilities.trim(c.getString(titleIndex)); 354756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 35484fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 354956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // fall back to the class name of the activity 35509c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (info.title == null) { 355156d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = componentName.getClassName(); 35529c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 35534fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 35549c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; 3555ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = user; 355682b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); 3557fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal if (lai != null) { 3558fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal info.flags = AppInfo.initFlags(lai); 3559fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal } 35609c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 35619c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 356231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3563e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal static ArrayList<ItemInfo> filterItemInfos(Iterable<ItemInfo> infos, 356464359a53dc827797917a8d9a0697a91996789801Winson Chung ItemInfoFilter f) { 356564359a53dc827797917a8d9a0697a91996789801Winson Chung HashSet<ItemInfo> filtered = new HashSet<ItemInfo>(); 356664359a53dc827797917a8d9a0697a91996789801Winson Chung for (ItemInfo i : infos) { 356764359a53dc827797917a8d9a0697a91996789801Winson Chung if (i instanceof ShortcutInfo) { 356864359a53dc827797917a8d9a0697a91996789801Winson Chung ShortcutInfo info = (ShortcutInfo) i; 3569349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ComponentName cn = info.getTargetComponent(); 357064359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(null, info, cn)) { 357164359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(info); 357264359a53dc827797917a8d9a0697a91996789801Winson Chung } 357364359a53dc827797917a8d9a0697a91996789801Winson Chung } else if (i instanceof FolderInfo) { 357464359a53dc827797917a8d9a0697a91996789801Winson Chung FolderInfo info = (FolderInfo) i; 357564359a53dc827797917a8d9a0697a91996789801Winson Chung for (ShortcutInfo s : info.contents) { 3576349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ComponentName cn = s.getTargetComponent(); 357764359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(info, s, cn)) { 357864359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(s); 35798a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 35808a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 358164359a53dc827797917a8d9a0697a91996789801Winson Chung } else if (i instanceof LauncherAppWidgetInfo) { 358264359a53dc827797917a8d9a0697a91996789801Winson Chung LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) i; 358364359a53dc827797917a8d9a0697a91996789801Winson Chung ComponentName cn = info.providerName; 358464359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(null, info, cn)) { 358564359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(info); 358664359a53dc827797917a8d9a0697a91996789801Winson Chung } 35878a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 35888a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 358964359a53dc827797917a8d9a0697a91996789801Winson Chung return new ArrayList<ItemInfo>(filtered); 359064359a53dc827797917a8d9a0697a91996789801Winson Chung } 359164359a53dc827797917a8d9a0697a91996789801Winson Chung 3592091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk ArrayList<ItemInfo> getItemInfoForComponentName(final ComponentName cname, 3593ed13187a745866483139e2878037e1f8427ce567Kenny Guy final UserHandleCompat user) { 359464359a53dc827797917a8d9a0697a91996789801Winson Chung ItemInfoFilter filter = new ItemInfoFilter() { 359564359a53dc827797917a8d9a0697a91996789801Winson Chung @Override 359664359a53dc827797917a8d9a0697a91996789801Winson Chung public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn) { 3597ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (info.user == null) { 3598ed13187a745866483139e2878037e1f8427ce567Kenny Guy return cn.equals(cname); 3599ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 3600ed13187a745866483139e2878037e1f8427ce567Kenny Guy return cn.equals(cname) && info.user.equals(user); 3601ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 360264359a53dc827797917a8d9a0697a91996789801Winson Chung } 360364359a53dc827797917a8d9a0697a91996789801Winson Chung }; 3604e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal return filterItemInfos(sBgItemsIdMap, filter); 360564359a53dc827797917a8d9a0697a91996789801Winson Chung } 360664359a53dc827797917a8d9a0697a91996789801Winson Chung 36071a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal /** 36080589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Make an ShortcutInfo object for a shortcut that isn't an application. 36099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 3610091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk ShortcutInfo getShortcutInfo(Cursor c, Context context, 36114e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal int titleIndex, CursorIconInfo iconInfo) { 3612c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 3613ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Non-app shortcuts are only supported for current user. 3614ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = UserHandleCompat.myUserHandle(); 36159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 36167376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project 36178ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: If there's an explicit component and we can't install that, delete it. 36188ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 361982b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.title = Utilities.trim(c.getString(titleIndex)); 362056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 36214e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal Bitmap icon = iconInfo.loadIcon(c, info, context); 36224e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal // the fallback icon 36234e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (icon == null) { 3624ed13187a745866483139e2878037e1f8427ce567Kenny Guy icon = mIconCache.getDefaultIcon(info.user); 362556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 362631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 3627d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato info.setIcon(icon); 36289c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 3629f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 363031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 36312350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal ShortcutInfo infoFromShortcutIntent(Context context, Intent data) { 36320589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 36330589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); 36340589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON); 36350589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 3636d919882006a457d16dea46bd546472e6534b5c19Adam Cohen if (intent == null) { 3637d919882006a457d16dea46bd546472e6534b5c19Adam Cohen // If the intent is null, we can't construct a valid ShortcutInfo, so we return null 3638d919882006a457d16dea46bd546472e6534b5c19Adam Cohen Log.e(TAG, "Can't construct ShorcutInfo with null intent"); 3639d919882006a457d16dea46bd546472e6534b5c19Adam Cohen return null; 3640d919882006a457d16dea46bd546472e6534b5c19Adam Cohen } 3641d919882006a457d16dea46bd546472e6534b5c19Adam Cohen 36420589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Bitmap icon = null; 36430589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato boolean customIcon = false; 36440589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutIconResource iconResource = null; 36450589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 36462fce90c38a79d318e96a28107dea287e42509861Sunny Goyal if (bitmap instanceof Bitmap) { 36472fce90c38a79d318e96a28107dea287e42509861Sunny Goyal icon = Utilities.createIconBitmap((Bitmap) bitmap, context); 36480589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato customIcon = true; 36490589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } else { 36500589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 3651b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (extra instanceof ShortcutIconResource) { 3652b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal iconResource = (ShortcutIconResource) extra; 3653b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal icon = Utilities.createIconBitmap(iconResource.packageName, 365453d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal iconResource.resourceName, context); 36550589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 36560589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 36570589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 3658c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 365956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 3660ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Only support intents for current user for now. Intents sent from other 3661ed13187a745866483139e2878037e1f8427ce567Kenny Guy // users wouldn't get here without intent forwarding anyway. 3662ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = UserHandleCompat.myUserHandle(); 36630589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (icon == null) { 36642350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal icon = mIconCache.getDefaultIcon(info.user); 36652350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal info.usingFallbackIcon = true; 36660589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 36670589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.setIcon(icon); 366856d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 366982b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.title = Utilities.trim(name); 367082b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); 36710589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.intent = intent; 36720589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.customIcon = customIcon; 36730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.iconResource = iconResource; 36740589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 36750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 36760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 36770589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 367831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 3679df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * Return an existing FolderInfo object if we have encountered this ID previously, 36809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * or make a new one. 368131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 3682e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal @Thunk static FolderInfo findOrMakeFolder(LongArrayMap<FolderInfo> folders, long id) { 36839c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // See if a placeholder was created for us already 36849c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = folders.get(id); 3685df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (folderInfo == null) { 36869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // No placeholder -- create a new instance 3687c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka folderInfo = new FolderInfo(); 36889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folders.put(id, folderInfo); 368931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 3690df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return folderInfo; 369131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 369231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3693be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 3694651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal static boolean isValidProvider(AppWidgetProviderInfo provider) { 3695651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal return (provider != null) && (provider.provider != null) 3696651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal && (provider.provider.getPackageName() != null); 3697651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } 3698651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal 3699be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 3700be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mCallbacks=" + mCallbacks); 3701eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.data", mBgAllAppsList.data); 3702eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.added", mBgAllAppsList.added); 3703eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.removed", mBgAllAppsList.removed); 3704eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.modified", mBgAllAppsList.modified); 37053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask != null) { 37063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask.dumpState(); 37073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 37083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "mLoaderTask=null"); 37093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3710be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 3711e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 3712e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal public Callbacks getCallback() { 3713e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return mCallbacks != null ? mCallbacks.get() : null; 3714e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 371518bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal 371618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal /** 371718bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal * @return {@link FolderInfo} if its already loaded. 371818bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal */ 371918bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal public FolderInfo findFolderById(Long folderId) { 372018bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal synchronized (sBgLock) { 372118bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal return sBgFolders.get(folderId); 372218bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal } 372318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal } 3724756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 3725756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal /** 3726756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal * @return the looper for the worker thread which can be used to start background tasks. 3727756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal */ 3728756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public static Looper getWorkerLooper() { 3729756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal return sWorkerThread.getLooper(); 3730756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 373131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 3732