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 19629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetProviderInfo; 20f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.BroadcastReceiver; 21f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ComponentName; 22f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ContentProviderOperation; 23f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ContentResolver; 24f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.ContentValues; 25f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.Context; 26f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.Intent; 270589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.content.Intent.ShortcutIconResource; 28f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport android.content.IntentFilter; 2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.PackageManager; 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.pm.ResolveInfo; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.database.Cursor; 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Bitmap; 3331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.net.Uri; 343611578579b4bfb25616085dafdb1a45207394f9Joe Onoratoimport android.os.Handler; 353611578579b4bfb25616085dafdb1a45207394f9Joe Onoratoimport android.os.HandlerThread; 36756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyalimport android.os.Looper; 370589f0f66ce498512c6ee47482c649d88294c9d0Joe Onoratoimport android.os.Parcelable; 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Process; 399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onoratoimport android.os.SystemClock; 40e26d1008eb587303db25797ca02cc32464e45656Sunny Goyalimport android.os.Trace; 41c3919c0e994309982efc8779af57e2bc78dcac43Chris Wrenimport android.provider.BaseColumns; 42a90303bb6fdad59e4a55855edba68c9902192599Winson Chungimport android.text.TextUtils; 43aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chungimport android.util.Log; 4471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyalimport android.util.LongSparseArray; 45bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickhamimport android.util.MutableInt; 46c916834ad0da535f08325bcd902a60070f2f7e53Winson Chungimport android.util.Pair; 4734c2e6cf7af328aba25c98158161dbad15ae986dMichael Jurka 48ffe83f13319cdb833a25596d47cf1af098cc4c60Sunny Goyalimport com.android.launcher3.compat.AppWidgetManagerCompat; 49ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherActivityInfoCompat; 50ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.LauncherAppsCompat; 51349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat; 52e755d469d40b95e763a9dcb67d0e4f511d1948ddSunny Goyalimport com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo; 53ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.UserHandleCompat; 54ed13187a745866483139e2878037e1f8427ce567Kenny Guyimport com.android.launcher3.compat.UserManagerCompat; 55a9e2f5abb3c21d9721939c625ffb0caabb34e8d9Sunny Goyalimport com.android.launcher3.config.FeatureFlags; 566c56c68555dcb3d99b05d5faecd582a1f683cc92Sunny Goyalimport com.android.launcher3.config.ProviderConfig; 57827cef203f386cb548b98a7fa9888b75478c8e20Tony Wickhamimport com.android.launcher3.dynamicui.ExtractionUtils; 58261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.folder.Folder; 59261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.folder.FolderIcon; 601acb9e9e29bb06b6266781284ae60e9fd4d0962fSunny Goyalimport com.android.launcher3.logging.FileLog; 61f862a26347b583bd84be22a8ceff4bc13158ec7eSunny Goyalimport com.android.launcher3.model.GridSizeMigrationTask; 622bd3d7d1cb5e4d8d826982d11b456739fed6b817Hyunyoung Songimport com.android.launcher3.model.WidgetsModel; 63a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyalimport com.android.launcher3.provider.ImportDataTask; 64a9e2f5abb3c21d9721939c625ffb0caabb34e8d9Sunny Goyalimport com.android.launcher3.provider.LauncherDbUtils; 65bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickhamimport com.android.launcher3.shortcuts.DeepShortcutManager; 66bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickhamimport com.android.launcher3.shortcuts.ShortcutInfoCompat; 67bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickhamimport com.android.launcher3.shortcuts.ShortcutKey; 6826ace12135a662ad864678c9fede9817e5c02b67Robin Leeimport com.android.launcher3.util.ComponentKey; 694e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyalimport com.android.launcher3.util.CursorIconInfo; 703bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyalimport com.android.launcher3.util.FlagOp; 71ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyalimport com.android.launcher3.util.GridOccupancy; 72e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyalimport com.android.launcher3.util.LongArrayMap; 7318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyalimport com.android.launcher3.util.ManagedProfileHeuristic; 74d82a39da1c61b19d2749725f9c70c3baf2dab6bfTony Wickhamimport com.android.launcher3.util.MultiHashMap; 75d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyalimport com.android.launcher3.util.PackageManagerHelper; 76aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyalimport com.android.launcher3.util.Preconditions; 77da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyalimport com.android.launcher3.util.StringFilter; 78091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 79527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport com.android.launcher3.util.ViewOnDrawExecutor; 80edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 81c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.lang.ref.WeakReference; 82c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.net.URISyntaxException; 83349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyalimport java.security.InvalidParameterException; 84c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.ArrayList; 85dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohenimport java.util.Arrays; 86c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.Collections; 87c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.Comparator; 88c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.HashMap; 89b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chungimport java.util.HashSet; 902abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chungimport java.util.Iterator; 91c2f801e770b4f80354b3edb722ec04222251990cMichael Jurkaimport java.util.List; 92bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickhamimport java.util.Map; 93f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyalimport java.util.Map.Entry; 94b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chungimport java.util.Set; 95527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyalimport java.util.concurrent.Executor; 96c2f801e770b4f80354b3edb722ec04222251990cMichael Jurka 9731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Maintains in-memory state of the Launcher. It is expected that there should be only one 9931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * LauncherModel object held in a static. Also provide APIs for updating the database state 100bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project * for the Launcher. 10131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 102ed13187a745866483139e2878037e1f8427ce567Kenny Guypublic class LauncherModel extends BroadcastReceiver 103c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy implements LauncherAppsCompat.OnAppsChangedCallbackCompat { 104a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato static final boolean DEBUG_LOADERS = false; 105ee52336a9ed0c98f78831a0e44b21f5a8d8c17d1Chris Wren private static final boolean DEBUG_RECEIVER = false; 106b358f813c93ac0d6c4f31058947efd16b188cd1eChris Wren 1079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato static final String TAG = "Launcher.Model"; 1089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons 1107aff399974c756930070d82d7b2df88f125dacd6Derek Prothro private static final long INVALID_SCREEN_ID = -1L; 111a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung 112091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final LauncherAppState mApp; 113091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final Object mLock = new Object(); 114091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk DeferredHandler mHandler = new DeferredHandler(); 115091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk LoaderTask mLoaderTask; 116091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk boolean mIsLoaderTaskRunning; 117756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal @Thunk boolean mHasLoaderCompletedOnce; 1189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 119091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader"); 120700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick static { 121700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick sWorkerThread.start(); 122700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick } 123091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper()); 124700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick 125cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // We start off with everything not loaded. After that, we assume that 126cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // our monitoring of the package manager provides all updates and we never 127cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato // need to do a requery. These are only ever touched from the loader thread. 128bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private boolean mWorkspaceLoaded; 129bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private boolean mAllAppsLoaded; 130bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private boolean mDeepShortcutsLoaded; 131cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 132756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal /** 133756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal * Set of runnables to be called on the background thread after the workspace binding 134756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal * is complete. 135756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal */ 136756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal static final ArrayList<Runnable> mBindCompleteRunnables = new ArrayList<Runnable>(); 137756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal 138091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk WeakReference<Callbacks> mCallbacks; 1399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 140a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // < only access in worker thread > 1412e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal private final AllAppsList mBgAllAppsList; 1429110d485fa12c03df3061278717efb342f1142cfHyunyoung Song // Entire list of widgets. 1432e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal private final WidgetsModel mBgWidgetsModel; 144a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 145bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // Maps all launcher activities to the id's of their shortcuts (if they have any). 146bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private final MultiHashMap<ComponentKey, String> mBgDeepShortcutMap = new MultiHashMap<>(); 147bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 14895f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal private boolean mHasShortcutHostPermission; 14995f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal // Runnable to check if the shortcuts permission has changed. 15095f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal private final Runnable mShortcutPermissionCheckRunnable = new Runnable() { 15195f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal @Override 15295f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal public void run() { 15395f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal if (mDeepShortcutsLoaded) { 15495f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal boolean hasShortcutHostPermission = mDeepShortcutManager.hasHostPermission(); 15595f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal if (hasShortcutHostPermission != mHasShortcutHostPermission) { 15695f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal mApp.reloadWorkspace(); 15795f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal } 15895f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal } 15995f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal } 16095f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal }; 16195f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal 162b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // The lock that must be acquired before referencing any static bg data structures. Unlike 163b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // other locks, this one can generally be held long-term because we never expect any of these 164b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // static data structures to be referenced outside of the worker thread except on the first 165b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // load after configuration change. 1662abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung static final Object sBgLock = new Object(); 167b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 168487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgItemsIdMap maps *all* the ItemInfos (shortcuts, folders, and widgets) created by 169a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // LauncherModel to their ids 170e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal static final LongArrayMap<ItemInfo> sBgItemsIdMap = new LongArrayMap<>(); 171a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 172487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgWorkspaceItems is passed to bindItems, which expects a list of all folders and shortcuts 173487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // created by LauncherModel that are directly on the home screen (however, no widgets or 174487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // shortcuts within folders). 175487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final ArrayList<ItemInfo> sBgWorkspaceItems = new ArrayList<ItemInfo>(); 1760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 177487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgAppWidgets is all LauncherAppWidgetInfo created by LauncherModel. Passed to bindAppWidget() 178487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen static final ArrayList<LauncherAppWidgetInfo> sBgAppWidgets = 179a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka new ArrayList<LauncherAppWidgetInfo>(); 180a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 181487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // sBgFolders is all FolderInfos created by LauncherModel. Passed to bindFolders() 182e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal static final LongArrayMap<FolderInfo> sBgFolders = new LongArrayMap<>(); 183b1094bd9630f659cc606853b8a244b6a6b6c6943Winson Chung 184dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // sBgWorkspaceScreens is the ordered set of workspace screens. 185dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen static final ArrayList<Long> sBgWorkspaceScreens = new ArrayList<Long>(); 186dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 187bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // sBgPinnedShortcutCounts is the ComponentKey representing a pinned shortcut to the number of 188bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // times it is pinned. 189bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham static final Map<ShortcutKey, MutableInt> sBgPinnedShortcutCounts = new HashMap<>(); 190bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 191f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // sPendingPackages is a set of packages which could be on sdcard and are not available yet 192513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala static final HashMap<UserHandleCompat, HashSet<String>> sPendingPackages = 193513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala new HashMap<UserHandleCompat, HashSet<String>>(); 194f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 195a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka // </ only access in worker thread > 196a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka 197bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private IconCache mIconCache; 198bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private DeepShortcutManager mDeepShortcutManager; 1999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 200bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private final LauncherAppsCompat mLauncherApps; 201bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private final UserManagerCompat mUserManager; 202ed13187a745866483139e2878037e1f8427ce567Kenny Guy 2039c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public interface Callbacks { 204ef2efcff5e70e5900f4f10f9e46c3fa17c03b0ecJoe Onorato public boolean setLoadOnResume(); 2059c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public int getCurrentWorkspaceScreen(); 206527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void clearPendingBinds(); 2079c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void startBinding(); 20864359a53dc827797917a8d9a0697a91996789801Winson Chung public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end, 20964359a53dc827797917a8d9a0697a91996789801Winson Chung boolean forceAnimateIcons); 210dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void bindScreens(ArrayList<Long> orderedScreenIds); 211b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal public void finishFirstPageBind(ViewOnDrawExecutor executor); 21266cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal public void finishBindingItems(); 2139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void bindAppWidget(LauncherAppWidgetInfo info); 214eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public void bindAllApplications(ArrayList<AppInfo> apps); 215d64d1763c590b1c954b759156683abf39ff22945Winson Chung public void bindAppsAdded(ArrayList<Long> newScreens, 216d64d1763c590b1c954b759156683abf39ff22945Winson Chung ArrayList<ItemInfo> addNotAnimated, 217c58497ee619416c4949b16eb43486c11618b69e5Winson Chung ArrayList<ItemInfo> addAnimated, 218c58497ee619416c4949b16eb43486c11618b69e5Winson Chung ArrayList<AppInfo> addedApps); 219eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka public void bindAppsUpdated(ArrayList<AppInfo> apps); 2204390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated, 2214390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ArrayList<ShortcutInfo> removed, UserHandleCompat user); 2224390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets); 223756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public void bindRestoreItemsChange(HashSet<ItemInfo> updates); 2243bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal public void bindWorkspaceComponentsRemoved( 2253bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal HashSet<String> packageNames, HashSet<ComponentName> components, 2263bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal UserHandleCompat user); 2273bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal public void bindAppInfosRemoved(ArrayList<AppInfo> appInfos); 2282e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal public void notifyWidgetProvidersChanged(); 2292e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal public void bindWidgetsModel(WidgetsModel model); 2301462de39f01cec0ba785386532719cb0207dd827Adam Cohen public void onPageBoundSynchronously(int page); 231527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void executeOnNextDraw(ViewOnDrawExecutor executor); 232bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham public void bindDeepShortcutMap(MultiHashMap<ComponentKey, String> deepShortcutMap); 2339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23564359a53dc827797917a8d9a0697a91996789801Winson Chung public interface ItemInfoFilter { 23664359a53dc827797917a8d9a0697a91996789801Winson Chung public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn); 23764359a53dc827797917a8d9a0697a91996789801Winson Chung } 23864359a53dc827797917a8d9a0697a91996789801Winson Chung 239bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter, 240bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham DeepShortcutManager deepShortcutManager) { 241a694524047fda0a51dede4eefb1201a598d2d3a7Winson Chung Context context = app.getContext(); 242e4f9891f01bdc10d8f96e4e2429e2f4d0558238bDaniel Sandler mApp = app; 2431307f63f8a93541bf6e2d29c11fab69778a25e42Bjorn Bringert mBgAllAppsList = new AllAppsList(iconCache, appFilter); 244eaf291b9feba4e332d258b6d53ff119c88dc0d39Hyunyoung Song mBgWidgetsModel = new WidgetsModel(context, iconCache, appFilter); 2450589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = iconCache; 246bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mDeepShortcutManager = deepShortcutManager; 2470589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 248ed13187a745866483139e2878037e1f8427ce567Kenny Guy mLauncherApps = LauncherAppsCompat.getInstance(context); 249ed13187a745866483139e2878037e1f8427ce567Kenny Guy mUserManager = UserManagerCompat.getInstance(context); 2500589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 2510589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 252b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Runs the specified runnable immediately if called from the main thread, otherwise it is 253b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * posted on the main thread handler. */ 25480f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham private void runOnMainThread(Runnable r) { 255b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 256b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we are on the worker thread, post onto the main handler 257b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mHandler.post(r); 258b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 259b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r.run(); 260b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 261b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 262b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 263b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Runs the specified runnable immediately if called from the worker thread, otherwise it is 264b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * posted on the worker thread handler. */ 26580f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham private static void runOnWorkerThread(Runnable r) { 266b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (sWorkerThread.getThreadId() == Process.myTid()) { 267b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r.run(); 268b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 269b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // If we are not on the worker thread, then post to the worker handler 270b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorker.post(r); 271b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 272b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 273b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson 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) { 338d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal ArrayList<ShortcutInfo> updates = new ArrayList<>(); 339d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 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 361d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal bindUpdatedShortcuts(updates, user); 362a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 363a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 364a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal }; 365756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal runOnWorkerThread(updateRunnable); 366a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal } 367a22666f68151269853e7ab6ab696ee6361bac793Sunny Goyal 36876a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void addAppsToAllApps(final Context ctx, final ArrayList<AppInfo> allAppsApps) { 369e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal final Callbacks callbacks = getCallback(); 37076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 37176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (allAppsApps == null) { 37276a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen throw new RuntimeException("allAppsApps must not be null"); 37376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 37476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (allAppsApps.isEmpty()) { 37576a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen return; 37676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 37776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 37876a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen // Process the newly added applications and add them to the database first 37976a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen Runnable r = new Runnable() { 38076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void run() { 38176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen runOnMainThread(new Runnable() { 38276a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen public void run() { 383e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 38476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (callbacks == cb && cb != null) { 3856d0dde01f307051ee1849481c989d9e87774b894Chris Wren callbacks.bindAppsAdded(null, null, null, allAppsApps); 38676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 38776a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 38876a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen }); 38976a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen } 39076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen }; 39176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen runOnWorkerThread(r); 392997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 39376a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 394a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal private static boolean findNextAvailableIconSpaceInScreen(ArrayList<ItemInfo> occupiedPos, 39571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] xy, int spanX, int spanY) { 39671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal LauncherAppState app = LauncherAppState.getInstance(); 3972e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); 398ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal 399ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal GridOccupancy occupied = new GridOccupancy(profile.numColumns, profile.numRows); 40071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (occupiedPos != null) { 401a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal for (ItemInfo r : occupiedPos) { 402ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal occupied.markCells(r, true); 40371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 40471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 405ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal return occupied.findVacantCell(xy, spanX, spanY); 40671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 40771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 40871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal /** 40971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * Find a position on the screen for the given size or adds a new screen. 41071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * @return screenId and the coordinates for the item. 41171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal */ 412756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal @Thunk Pair<Long, int[]> findSpaceForItem( 413c3642d45098eed97ee278f7db370335d7fd407fcSunny Goyal Context context, 41471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal ArrayList<Long> workspaceScreens, 41571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal ArrayList<Long> addedWorkspaceScreensFinal, 41671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int spanX, int spanY) { 417a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal LongSparseArray<ArrayList<ItemInfo>> screenItems = new LongSparseArray<>(); 418a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal 419a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal // Use sBgItemsIdMap as all the items are already loaded. 420756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal assertWorkspaceLoaded(); 421a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal synchronized (sBgLock) { 422a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal for (ItemInfo info : sBgItemsIdMap) { 423a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { 424a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal ArrayList<ItemInfo> items = screenItems.get(info.screenId); 425a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal if (items == null) { 426a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal items = new ArrayList<>(); 427a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal screenItems.put(info.screenId, items); 428a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal } 429a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal items.add(info); 43071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 43171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 43271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 43371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 43471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Find appropriate space for the item. 43571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal long screenId = 0; 43671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] cordinates = new int[2]; 43771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal boolean found = false; 43871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 43971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int screenCount = workspaceScreens.size(); 44071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // First check the preferred screen. 441a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal int preferredScreenIndex = workspaceScreens.isEmpty() ? 0 : 1; 44271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (preferredScreenIndex < screenCount) { 44371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId = workspaceScreens.get(preferredScreenIndex); 44471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal found = findNextAvailableIconSpaceInScreen( 44571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY); 44671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 44771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 44871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!found) { 449a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal // Search on any of the screens starting from the first screen. 450a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal for (int screen = 1; screen < screenCount; screen++) { 45171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenId = workspaceScreens.get(screen); 45271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (findNextAvailableIconSpaceInScreen( 45371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY)) { 45471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // We found a space for it 45571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal found = true; 45671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal break; 45771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 45871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 45971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 46071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 46171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!found) { 46271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Still no position found. Add a new screen to the end. 463d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal screenId = LauncherSettings.Settings.call(context.getContentResolver(), 464d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal LauncherSettings.Settings.METHOD_NEW_SCREEN_ID) 465d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal .getLong(LauncherSettings.Settings.EXTRA_VALUE); 46671b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 46771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Save the screen id for binding in the workspace 46871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal workspaceScreens.add(screenId); 46971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal addedWorkspaceScreensFinal.add(screenId); 47076a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 47171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // If we still can't find an empty space, then God help us all!!! 47271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal if (!findNextAvailableIconSpaceInScreen( 47371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal screenItems.get(screenId), cordinates, spanX, spanY)) { 47471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal throw new RuntimeException("Can't find space to add the item"); 47571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 476fe9d96a39651de99819208e95c7ec7d432a402e0Winson Chung } 47771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal return Pair.create(screenId, cordinates); 47871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } 47971b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 48071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal /** 48171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal * Adds the provided items to the workspace. 48271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal */ 48318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal public void addAndBindAddedWorkspaceItems(final Context context, 484a214a63bfe365a0e81bc3082d56896c6df24d0b4Sunny Goyal final ArrayList<? extends ItemInfo> workspaceApps) { 48571b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal final Callbacks callbacks = getCallback(); 48676a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (workspaceApps.isEmpty()) { 4879e6a0a20d40675ef98c7fdb8892cf34b90152f7aWinson Chung return; 488997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 48964359a53dc827797917a8d9a0697a91996789801Winson Chung // Process the newly added applications and add them to the database first 49064359a53dc827797917a8d9a0697a91996789801Winson Chung Runnable r = new Runnable() { 49164359a53dc827797917a8d9a0697a91996789801Winson Chung public void run() { 49264359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>(); 49364359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>(); 49464359a53dc827797917a8d9a0697a91996789801Winson Chung 49576828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // Get the list of workspace screens. We need to append to this list and 49676828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // can not use sBgWorkspaceScreens because loadWorkspace() may not have been 49776828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // called. 498c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal ArrayList<Long> workspaceScreens = loadWorkspaceScreensDb(context); 49964359a53dc827797917a8d9a0697a91996789801Winson Chung synchronized(sBgLock) { 50071b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal for (ItemInfo item : workspaceApps) { 501a911672f45900fc0ed746e0d84c43c6e5ad89b6aSunny Goyal if (item instanceof ShortcutInfo) { 50271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Short-circuit this logic if the icon exists somewhere on the workspace 503756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (shortcutExists(context, item.getIntent(), item.user)) { 50471b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal continue; 505c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung } 50664359a53dc827797917a8d9a0697a91996789801Winson Chung } 50764359a53dc827797917a8d9a0697a91996789801Winson Chung 50871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal // Find appropriate space for the item. 509c3642d45098eed97ee278f7db370335d7fd407fcSunny Goyal Pair<Long, int[]> coords = findSpaceForItem(context, 5109eba1fd75e9fa6b0dc5cad9a4e817b3b167d2461Sunny Goyal workspaceScreens, addedWorkspaceScreensFinal, 1, 1); 51171b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal long screenId = coords.first; 51271b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal int[] cordinates = coords.second; 51371b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal 51418bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal ItemInfo itemInfo; 51518bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal if (item instanceof ShortcutInfo || item instanceof FolderInfo) { 51618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal itemInfo = item; 51771b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal } else if (item instanceof AppInfo) { 51818bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal itemInfo = ((AppInfo) item).makeShortcut(); 519997a92348a6d6e061737399321393449c16cd4d8Winson Chung } else { 520997a92348a6d6e061737399321393449c16cd4d8Winson Chung throw new RuntimeException("Unexpected info type"); 521997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 52294d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung 52364359a53dc827797917a8d9a0697a91996789801Winson Chung // Add the shortcut to the db 52418bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal addItemToDatabase(context, itemInfo, 52564359a53dc827797917a8d9a0697a91996789801Winson Chung LauncherSettings.Favorites.CONTAINER_DESKTOP, 5261d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal screenId, cordinates[0], cordinates[1]); 52764359a53dc827797917a8d9a0697a91996789801Winson Chung // Save the ShortcutInfo for binding in the workspace 52818bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal addedShortcutsFinal.add(itemInfo); 52964359a53dc827797917a8d9a0697a91996789801Winson Chung } 53064359a53dc827797917a8d9a0697a91996789801Winson Chung } 53164359a53dc827797917a8d9a0697a91996789801Winson Chung 53276828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung // Update the workspace screens 53376828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung updateWorkspaceScreenOrder(context, workspaceScreens); 53476828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 53576a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen if (!addedShortcutsFinal.isEmpty()) { 536997a92348a6d6e061737399321393449c16cd4d8Winson Chung runOnMainThread(new Runnable() { 537997a92348a6d6e061737399321393449c16cd4d8Winson Chung public void run() { 538e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 539997a92348a6d6e061737399321393449c16cd4d8Winson Chung if (callbacks == cb && cb != null) { 540997a92348a6d6e061737399321393449c16cd4d8Winson Chung final ArrayList<ItemInfo> addAnimated = new ArrayList<ItemInfo>(); 541997a92348a6d6e061737399321393449c16cd4d8Winson Chung final ArrayList<ItemInfo> addNotAnimated = new ArrayList<ItemInfo>(); 54294d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung if (!addedShortcutsFinal.isEmpty()) { 54394d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung ItemInfo info = addedShortcutsFinal.get(addedShortcutsFinal.size() - 1); 54494d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung long lastScreenId = info.screenId; 54594d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung for (ItemInfo i : addedShortcutsFinal) { 54694d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung if (i.screenId == lastScreenId) { 54794d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung addAnimated.add(i); 54894d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung } else { 54994d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung addNotAnimated.add(i); 55094d6768c65929efa21bb893fdef7f269d65da3c3Winson Chung } 551997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 552997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 553d64d1763c590b1c954b759156683abf39ff22945Winson Chung callbacks.bindAppsAdded(addedWorkspaceScreensFinal, 55476a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen addNotAnimated, addAnimated, null); 555997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 55664359a53dc827797917a8d9a0697a91996789801Winson Chung } 557997a92348a6d6e061737399321393449c16cd4d8Winson Chung }); 558997a92348a6d6e061737399321393449c16cd4d8Winson Chung } 55964359a53dc827797917a8d9a0697a91996789801Winson Chung } 56064359a53dc827797917a8d9a0697a91996789801Winson Chung }; 56164359a53dc827797917a8d9a0697a91996789801Winson Chung runOnWorkerThread(r); 56264359a53dc827797917a8d9a0697a91996789801Winson Chung } 56364359a53dc827797917a8d9a0697a91996789801Winson Chung 5649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 5659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Adds an item to the DB if it was not created previously, or move it to a new 5669c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * <container, screen, cellX, cellY> 5679c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 568f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container, 569dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long screenId, int cellX, int cellY) { 5709c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (item.container == ItemInfo.NO_ID) { 5719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From all apps 5721d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal addItemToDatabase(context, item, container, screenId, cellX, cellY); 5739c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } else { 5749c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // From somewhere else 575dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen moveItemInDatabase(context, item, container, screenId, cellX, cellY); 5769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 5779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 57831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 579b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka static void checkItemInfoLocked( 580b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka final long itemId, final ItemInfo item, StackTraceElement[] stackTrace) { 581b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ItemInfo modelItem = sBgItemsIdMap.get(itemId); 582b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelItem != null && item != modelItem) { 583b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // check all the data is consistent 584b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) { 585b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ShortcutInfo modelShortcut = (ShortcutInfo) modelItem; 586b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ShortcutInfo shortcut = (ShortcutInfo) item; 587b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (modelShortcut.title.toString().equals(shortcut.title.toString()) && 588b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.intent.filterEquals(shortcut.intent) && 589b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.id == shortcut.id && 590b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.itemType == shortcut.itemType && 591b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.container == shortcut.container && 592dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen modelShortcut.screenId == shortcut.screenId && 593b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.cellX == shortcut.cellX && 594b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.cellY == shortcut.cellY && 595b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka modelShortcut.spanX == shortcut.spanX && 596aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal modelShortcut.spanY == shortcut.spanY) { 597b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // For all intents and purposes, this is the same object 598b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka return; 599b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 600b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 601b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka 602b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // the modelItem needs to match up perfectly with item if our model is 603b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // to be consistent with the database-- for now, just require 604b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka // modelItem == item or the equality check above 605b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka String msg = "item: " + ((item != null) ? item.toString() : "null") + 606b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka "modelItem: " + 607b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka ((modelItem != null) ? modelItem.toString() : "null") + 608b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka "Error: ItemInfo passed to checkItemInfo doesn't match original"; 609b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka RuntimeException e = new RuntimeException(msg); 610b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka if (stackTrace != null) { 611b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka e.setStackTrace(stackTrace); 612b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 613b9ada65af30c61c5b35da9b9efac75ffe6c56fd7Adam Cohen throw e; 614b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 615b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 616b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka 617816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka static void checkItemInfo(final ItemInfo item) { 618816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 619816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka final long itemId = item.id; 620816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka Runnable r = new Runnable() { 621b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka public void run() { 622b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka synchronized (sBgLock) { 623b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka checkItemInfoLocked(itemId, item, stackTrace); 624816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka } 625b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka } 626b2ae8acc0c65a5464a4782ee43e0594a15b9cc16Michael Jurka }; 627b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 628816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka } 629816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka 630c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka static void updateItemInDatabaseHelper(Context context, final ContentValues values, 631c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ItemInfo item, final String callingFunction) { 632c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final long itemId = item.id; 6331d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final Uri uri = LauncherSettings.Favorites.getContentUri(itemId); 634c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ContentResolver cr = context.getContentResolver(); 635c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 636487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 637c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 638c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka public void run() { 639c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka cr.update(uri, values, null, null); 640f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemArrays(item, itemId, stackTrace); 641f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 642f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen }; 643f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen runOnWorkerThread(r); 644f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 645c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 646f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void updateItemsInDatabaseHelper(Context context, final ArrayList<ContentValues> valuesList, 647f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ArrayList<ItemInfo> items, final String callingFunction) { 648f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ContentResolver cr = context.getContentResolver(); 649c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 650f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 651f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Runnable r = new Runnable() { 652f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen public void run() { 653f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ContentProviderOperation> ops = 654f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen new ArrayList<ContentProviderOperation>(); 655f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int count = items.size(); 656f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < count; i++) { 657f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo item = items.get(i); 658f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final long itemId = item.id; 6591d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final Uri uri = LauncherSettings.Favorites.getContentUri(itemId); 660f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ContentValues values = valuesList.get(i); 661f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 662f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build()); 663f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemArrays(item, itemId, stackTrace); 664487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen 665f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 666f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen try { 667f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen cr.applyBatch(LauncherProvider.AUTHORITY, ops); 668f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } catch (Exception e) { 669f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen e.printStackTrace(); 670c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 671c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 672c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 673b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 674c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 675bebf042666cffe52039b875a549a582abd78a431Adam Cohen 676f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen static void updateItemArrays(ItemInfo item, long itemId, StackTraceElement[] stackTrace) { 677f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Lock on mBgLock *after* the db operation 678f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen synchronized (sBgLock) { 679f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen checkItemInfoLocked(itemId, item, stackTrace); 680f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 681f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP && 682f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 683f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Item is in a folder, make sure this folder exists 684f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (!sBgFolders.containsKey(item.container)) { 685f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // An items container is being set to a that of an item which is not in 686f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // the list of Folders. 687f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen String msg = "item: " + item + " container being set to: " + 688f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container + ", not in the list of folders"; 689f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen Log.e(TAG, msg); 690f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 691f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 692f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 693f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // Items are added/removed from the corresponding FolderInfo elsewhere, such 694f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // as in Workspace.onDrop. Here, we just add/remove them from the list of items 695f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // that are on the desktop, as appropriate 696f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo modelItem = sBgItemsIdMap.get(itemId); 69733231f587e1a6f716af68e6198df774d2847a8e5Winson Chung if (modelItem != null && 69833231f587e1a6f716af68e6198df774d2847a8e5Winson Chung (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || 69933231f587e1a6f716af68e6198df774d2847a8e5Winson Chung modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT)) { 700f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen switch (modelItem.itemType) { 701f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 702f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 703bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: 704f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 705f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (!sBgWorkspaceItems.contains(modelItem)) { 706f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen sBgWorkspaceItems.add(modelItem); 707f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 708f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen break; 709f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen default: 710f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen break; 711f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 712f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } else { 713f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen sBgWorkspaceItems.remove(modelItem); 714f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 715f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 716f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 717f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 7189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 7199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Move an item in the DB to a new <container, screen, cellX, cellY> 7209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 72183a8f042adda926489494dff217c15ab696139b4Sunny Goyal public static void moveItemInDatabase(Context context, final ItemInfo item, final long container, 722dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY) { 7239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 7249c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 7259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 726c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 7273d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // We store hotseat items in canonical form which is this orientation invariant position 7283d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // in the hotseat 729dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 7303d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 7312fd020860533e18c64a93d14d11cb2d34bc9cbafTony item.screenId = Launcher.getLauncher(context).getHotseat() 7322fd020860533e18c64a93d14d11cb2d34bc9cbafTony .getOrderInHotseat(cellX, cellY); 7333d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } else { 734dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 7353d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } 73631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 7389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato values.put(LauncherSettings.Favorites.CONTAINER, item.container); 7393d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung values.put(LauncherSettings.Favorites.CELLX, item.cellX); 7403d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung values.put(LauncherSettings.Favorites.CELLY, item.cellY); 74108f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal values.put(LauncherSettings.Favorites.RANK, item.rank); 742dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 743ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 744c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka updateItemInDatabaseHelper(context, values, item, "moveItemInDatabase"); 74531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 74631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 74731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 748f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen * Move items in the DB to a new <container, screen, cellX, cellY>. We assume that the 749f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen * cellX, cellY have already been updated on the ItemInfos. 750f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen */ 751f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public static void moveItemsInDatabase(Context context, final ArrayList<ItemInfo> items, 752f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final long container, final int screen) { 753f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 754f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ContentValues> contentValues = new ArrayList<ContentValues>(); 755f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int count = items.size(); 756f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 757f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < count; i++) { 758f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo item = items.get(i); 759f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.container = container; 760f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 761f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // We store hotseat items in canonical form which is this orientation invariant position 762f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen // in the hotseat 763f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen if (context instanceof Launcher && screen < 0 && 764f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 7652fd020860533e18c64a93d14d11cb2d34bc9cbafTony item.screenId = Launcher.getLauncher(context).getHotseat().getOrderInHotseat(item.cellX, 766f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen item.cellY); 767f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } else { 768dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screen; 769f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 770f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 771f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen final ContentValues values = new ContentValues(); 772f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CONTAINER, item.container); 773f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CELLX, item.cellX); 774f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen values.put(LauncherSettings.Favorites.CELLY, item.cellY); 77508f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal values.put(LauncherSettings.Favorites.RANK, item.rank); 776dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 777f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 778f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen contentValues.add(values); 779f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 780f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemsInDatabaseHelper(context, contentValues, items, "moveItemInDatabase"); 781f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 782f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 783f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen /** 784bebf042666cffe52039b875a549a582abd78a431Adam Cohen * Move and/or resize item in the DB to a new <container, screen, cellX, cellY, spanX, spanY> 785d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen */ 786bebf042666cffe52039b875a549a582abd78a431Adam Cohen static void modifyItemInDatabase(Context context, final ItemInfo item, final long container, 787dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final long screenId, final int cellX, final int cellY, final int spanX, final int spanY) { 7880f84a604563037ea65883b99d30e7ff802d986c2Winson Chung item.container = container; 789d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen item.cellX = cellX; 790d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen item.cellY = cellY; 791bebf042666cffe52039b875a549a582abd78a431Adam Cohen item.spanX = spanX; 792bebf042666cffe52039b875a549a582abd78a431Adam Cohen item.spanY = spanY; 793bebf042666cffe52039b875a549a582abd78a431Adam Cohen 794bebf042666cffe52039b875a549a582abd78a431Adam Cohen // We store hotseat items in canonical form which is this orientation invariant position 795bebf042666cffe52039b875a549a582abd78a431Adam Cohen // in the hotseat 796dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 797bebf042666cffe52039b875a549a582abd78a431Adam Cohen container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 7982fd020860533e18c64a93d14d11cb2d34bc9cbafTony item.screenId = Launcher.getLauncher(context).getHotseat() 7992fd020860533e18c64a93d14d11cb2d34bc9cbafTony .getOrderInHotseat(cellX, cellY); 800bebf042666cffe52039b875a549a582abd78a431Adam Cohen } else { 801dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 802bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 803d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 804d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen final ContentValues values = new ContentValues(); 805d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen values.put(LauncherSettings.Favorites.CONTAINER, item.container); 806bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.CELLX, item.cellX); 807bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.CELLY, item.cellY); 80808f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal values.put(LauncherSettings.Favorites.RANK, item.rank); 809bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.SPANX, item.spanX); 810bebf042666cffe52039b875a549a582abd78a431Adam Cohen values.put(LauncherSettings.Favorites.SPANY, item.spanY); 811dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen values.put(LauncherSettings.Favorites.SCREEN, item.screenId); 812d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 813816474f06b9bea400f4511fa35b63a7f18a54c54Michael Jurka updateItemInDatabaseHelper(context, values, item, "modifyItemInDatabase"); 814bebf042666cffe52039b875a549a582abd78a431Adam Cohen } 815c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 816c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka /** 817c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * Update an item to the database in a specified container. 818c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka */ 81983a8f042adda926489494dff217c15ab696139b4Sunny Goyal public static void updateItemInDatabase(Context context, final ItemInfo item) { 820c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ContentValues values = new ContentValues(); 821ed13187a745866483139e2878037e1f8427ce567Kenny Guy item.onAddToDatabase(context, values); 822c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka updateItemInDatabaseHelper(context, values, item, "updateItemInDatabase"); 823d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen } 824d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen 825756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal private void assertWorkspaceLoaded() { 8268f531dd9883443265afba8b94db62e78ce02ca57Sunny Goyal if (ProviderConfig.IS_DOGFOOD_BUILD) { 827639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal synchronized (mLock) { 828639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal if (!mHasLoaderCompletedOnce || 829639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal (mLoaderTask != null && mLoaderTask.mIsLoadingAndBindingWorkspace)) { 830639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal throw new RuntimeException("Trying to add shortcut while loader is running"); 831639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 832639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 833756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal } 834756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal } 835756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal 836d4844c3e731b00547a31f23a00f8bd4a271e2b62Adam Cohen /** 837756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal * Returns true if the shortcuts already exists on the workspace. This must be called after 838756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal * the workspace has been loaded. We identify a shortcut by its intent. 839bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project */ 840756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal @Thunk boolean shortcutExists(Context context, Intent intent, UserHandleCompat user) { 841756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal assertWorkspaceLoaded(); 842dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal final String intentWithPkg, intentWithoutPkg; 8432a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal if (intent.getComponent() != null) { 8442a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal // If component is not null, an intent with null package will produce 8452a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal // the same result and should also be a match. 8464e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal String packageName = intent.getComponent().getPackageName(); 8472a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal if (intent.getPackage() != null) { 848dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithPkg = intent.toUri(0); 849dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithoutPkg = new Intent(intent).setPackage(null).toUri(0); 8502a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } else { 851dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithPkg = new Intent(intent).setPackage(packageName).toUri(0); 852dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithoutPkg = intent.toUri(0); 8532a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } 8542a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } else { 855dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithPkg = intent.toUri(0); 856dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal intentWithoutPkg = intent.toUri(0); 8572a6cf09be968f71f23d520f1dc3f339feb61b269Sunny Goyal } 858756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 859756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal synchronized (sBgLock) { 860e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo item : sBgItemsIdMap) { 861756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (item instanceof ShortcutInfo) { 862756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal ShortcutInfo info = (ShortcutInfo) item; 8634e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal Intent targetIntent = info.promisedIntent == null 8644e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal ? info.intent : info.promisedIntent; 8654e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (targetIntent != null && info.user.equals(user)) { 866cbfe71dba38af1d1cd2d2372b649537d7d94610bSunny Goyal Intent copyIntent = new Intent(targetIntent); 867cbfe71dba38af1d1cd2d2372b649537d7d94610bSunny Goyal copyIntent.setSourceBounds(intent.getSourceBounds()); 868cbfe71dba38af1d1cd2d2372b649537d7d94610bSunny Goyal String s = copyIntent.toUri(0); 869dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal if (intentWithPkg.equals(s) || intentWithoutPkg.equals(s)) { 870dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal return true; 871dfde999ccd0db397c7e4610444bb3fb69f7aa183Sunny Goyal } 872756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 873756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 874756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 8759c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 876756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal return false; 877bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project } 878bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project 879bc219c3c127cb74cf4fe578f05022b745da921b8The Android Open Source Project /** 8809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Add an item to the database in a specified container. Sets the container, screen, cellX and 8819c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * cellY fields of the item. Also assigns an ID to the item. 8829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 88318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal public static void addItemToDatabase(Context context, final ItemInfo item, final long container, 8841d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final long screenId, final int cellX, final int cellY) { 8859c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.container = container; 8869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellX = cellX; 8879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato item.cellY = cellY; 8883d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // We store hotseat items in canonical form which is this orientation invariant position 8893d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung // in the hotseat 890dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (context instanceof Launcher && screenId < 0 && 8913d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 8922fd020860533e18c64a93d14d11cb2d34bc9cbafTony item.screenId = Launcher.getLauncher(context).getHotseat() 8932fd020860533e18c64a93d14d11cb2d34bc9cbafTony .getOrderInHotseat(cellX, cellY); 8943d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } else { 895dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen item.screenId = screenId; 8963d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung } 897ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 8989c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentValues values = new ContentValues(); 8999c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 900ed13187a745866483139e2878037e1f8427ce567Kenny Guy item.onAddToDatabase(context, values); 901ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 902d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal item.id = LauncherSettings.Settings.call(cr, LauncherSettings.Settings.METHOD_NEW_ITEM_ID) 903d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal .getLong(LauncherSettings.Settings.EXTRA_VALUE); 904d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal 905a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka values.put(LauncherSettings.Favorites._ID, item.id); 906aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 9078e19cf22a4ab86f982b08e7d10b86ea7be56acccJason Monk final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); 908c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 909a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka public void run() { 9101d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal cr.insert(LauncherSettings.Favorites.CONTENT_URI, values); 911ca9475f0403d9c0e843d5c189575068a386b2eb6The Android Open Source Project 912b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 9132abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 9148e19cf22a4ab86f982b08e7d10b86ea7be56acccJason Monk checkItemInfoLocked(item.id, item, stackTrace); 915b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(item.id, item); 916b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (item.itemType) { 917b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 918b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.put(item.id, (FolderInfo) item); 919b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Fall through 920b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 921b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 922bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: 923b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || 924b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 925b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(item); 926b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 927b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!sBgFolders.containsKey(item.container)) { 928b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Adding an item to a folder that doesn't exist. 929b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String msg = "adding item: " + item + " to a folder that " + 930b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung " doesn't exist"; 93128b3e10fdea4d719b46d2e0da9a916bacc238fd1Adam Cohen Log.e(TAG, msg); 932b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 933487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 934bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { 935d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal incrementPinnedShortcutCount( 936fc02c1b446ee54561ac7351fb6ff0f8294785f0eTony Wickham ShortcutKey.fromShortcutInfo((ShortcutInfo) item), 937fc02c1b446ee54561ac7351fb6ff0f8294785f0eTony Wickham true /* shouldPin */); 938bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 939b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 940b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 941b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.add((LauncherAppWidgetInfo) item); 942b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 943b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 944a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 945a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 946c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 947b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 94831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 94931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 950349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal private static ArrayList<ItemInfo> getItemsByPackageName( 951349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal final String pn, final UserHandleCompat user) { 952e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal ItemInfoFilter filter = new ItemInfoFilter() { 953e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal @Override 954e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn) { 955e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return cn.getPackageName().equals(pn) && info.user.equals(user); 956e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 957e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal }; 958e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal return filterItemInfos(sBgItemsIdMap, filter); 959349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 960349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 961349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal /** 962349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal * Removes all the items from the database corresponding to the specified package. 963349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal */ 964349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal static void deletePackageFromDatabase(Context context, final String pn, 965349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal final UserHandleCompat user) { 966349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal deleteItemsFromDatabase(context, getItemsByPackageName(pn, user)); 967e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 968e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 969e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal /** 970c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka * Removes the specified item from the database 9719c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 972fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal public static void deleteItemFromDatabase(Context context, final ItemInfo item) { 973e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal ArrayList<ItemInfo> items = new ArrayList<ItemInfo>(); 974e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal items.add(item); 975e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal deleteItemsFromDatabase(context, items); 976e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 977e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 978e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal /** 979e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal * Removes the specified items from the database 980e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal */ 9814390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal static void deleteItemsFromDatabase(Context context, final ArrayList<? extends ItemInfo> items) { 9829c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 98383df188ce0822f4058406e5f2878d1cf34bf413eMichael Jurka Runnable r = new Runnable() { 984a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka public void run() { 985e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal for (ItemInfo item : items) { 9861d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final Uri uri = LauncherSettings.Favorites.getContentUri(item.id); 987e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal cr.delete(uri, null, null); 988b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 989e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // Lock on mBgLock *after* the db operation 990e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal synchronized (sBgLock) { 991e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal switch (item.itemType) { 992e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 993e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgFolders.remove(item.id); 994e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo info: sBgItemsIdMap) { 995e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal if (info.container == item.id) { 996e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // We are deleting a folder which still contains items that 997e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal // think they are contained by that folder. 998e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal String msg = "deleting a folder (" + item + ") which still " + 999e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal "contains items (" + info + ")"; 1000e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal Log.e(TAG, msg); 1001e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1002b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1003e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgWorkspaceItems.remove(item); 1004e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1005bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: 1006fc02c1b446ee54561ac7351fb6ff0f8294785f0eTony Wickham decrementPinnedShortcutCount(ShortcutKey.fromShortcutInfo( 1007fc02c1b446ee54561ac7351fb6ff0f8294785f0eTony Wickham (ShortcutInfo) item)); 1008bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // Fall through. 1009e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1010e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1011e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgWorkspaceItems.remove(item); 1012e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1013e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 1014e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgAppWidgets.remove((LauncherAppWidgetInfo) item); 1015e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal break; 1016e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 1017e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal sBgItemsIdMap.remove(item.id); 1018b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1019a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 1020a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka } 102183df188ce0822f4058406e5f2878d1cf34bf413eMichael Jurka }; 1022b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 102331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 102431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 1026bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham * Decrement the count for the given pinned shortcut, unpinning it if the count becomes 0. 1027bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham */ 1028bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private static void decrementPinnedShortcutCount(final ShortcutKey pinnedShortcut) { 1029bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham synchronized (sBgLock) { 1030bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham MutableInt count = sBgPinnedShortcutCounts.get(pinnedShortcut); 1031bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (count == null || --count.value == 0) { 1032bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham LauncherAppState.getInstance().getShortcutManager().unpinShortcut(pinnedShortcut); 1033bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1034bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1035bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1036bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 1037bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham /** 1038bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham * Increment the count for the given shortcut, pinning it if the count becomes 1. 1039bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham * 1040bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham * As an optimization, the caller can pass shouldPin == false to avoid 1041bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham * unnecessary RPC's if the shortcut is already pinned. 1042bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham */ 1043bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private static void incrementPinnedShortcutCount(ShortcutKey pinnedShortcut, boolean shouldPin) { 1044bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham synchronized (sBgLock) { 1045bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham MutableInt count = sBgPinnedShortcutCounts.get(pinnedShortcut); 1046bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (count == null) { 1047bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham count = new MutableInt(1); 1048bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham sBgPinnedShortcutCounts.put(pinnedShortcut, count); 1049bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } else { 1050bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham count.value++; 1051bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1052bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (shouldPin && count.value == 1) { 1053bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham LauncherAppState.getInstance().getShortcutManager().pinShortcut(pinnedShortcut); 1054bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1055bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1056bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1057bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 1058bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham /** 1059dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen * Update the order of the workspace screens in the database. The array list contains 1060dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen * a list of screen ids in the order that they should appear. 1061dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen */ 1062e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal public void updateWorkspaceScreenOrder(Context context, final ArrayList<Long> screens) { 106364359a53dc827797917a8d9a0697a91996789801Winson Chung final ArrayList<Long> screensCopy = new ArrayList<Long>(screens); 1064dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ContentResolver cr = context.getContentResolver(); 1065dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI; 1066dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1067dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Remove any negative screen ids -- these aren't persisted 106864359a53dc827797917a8d9a0697a91996789801Winson Chung Iterator<Long> iter = screensCopy.iterator(); 1069dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen while (iter.hasNext()) { 1070dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long id = iter.next(); 1071dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (id < 0) { 1072dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen iter.remove(); 1073dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1074dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1075dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1076dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Runnable r = new Runnable() { 1077dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen @Override 1078dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void run() { 1079085c853a5702c45865e9b017d21fa15cf2b151b9Yura ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); 1080dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen // Clear the table 1081085c853a5702c45865e9b017d21fa15cf2b151b9Yura ops.add(ContentProviderOperation.newDelete(uri).build()); 108276828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung int count = screensCopy.size(); 1083dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen for (int i = 0; i < count; i++) { 1084dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen ContentValues v = new ContentValues(); 108576828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung long screenId = screensCopy.get(i); 1086dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen v.put(LauncherSettings.WorkspaceScreens._ID, screenId); 1087dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i); 1088085c853a5702c45865e9b017d21fa15cf2b151b9Yura ops.add(ContentProviderOperation.newInsert(uri).withValues(v).build()); 1089085c853a5702c45865e9b017d21fa15cf2b151b9Yura } 1090085c853a5702c45865e9b017d21fa15cf2b151b9Yura 1091085c853a5702c45865e9b017d21fa15cf2b151b9Yura try { 1092085c853a5702c45865e9b017d21fa15cf2b151b9Yura cr.applyBatch(LauncherProvider.AUTHORITY, ops); 1093085c853a5702c45865e9b017d21fa15cf2b151b9Yura } catch (Exception ex) { 1094085c853a5702c45865e9b017d21fa15cf2b151b9Yura throw new RuntimeException(ex); 1095dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 10969e6a0a20d40675ef98c7fdb8892cf34b90152f7aWinson Chung 1097ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung synchronized (sBgLock) { 1098ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.clear(); 1099ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.addAll(screensCopy); 11004caf298a2c9d861d69f5a47b747ada911b125b6dAdam Cohen } 1101dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1102dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen }; 1103dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen runOnWorkerThread(r); 1104dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 1105dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 1106dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen /** 1107c0b52fefbc11531d560359c093484099f9d1298eWinson * Remove the specified folder and all its contents from the database. 11089c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1109c0b52fefbc11531d560359c093484099f9d1298eWinson public static void deleteFolderAndContentsFromDatabase(Context context, final FolderInfo info) { 11109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final ContentResolver cr = context.getContentResolver(); 1111f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1112c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka Runnable r = new Runnable() { 1113c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka public void run() { 11141d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null); 1115b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 11162abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1117b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(info.id); 1118b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.remove(info.id); 1119b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.remove(info); 1120b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1121c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka 11221d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal cr.delete(LauncherSettings.Favorites.CONTENT_URI, 1123c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka LauncherSettings.Favorites.CONTAINER + "=" + info.id, null); 1124b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Lock on mBgLock *after* the db operation 11252abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1126b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo childInfo : info.contents) { 1127b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.remove(childInfo.id); 1128b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1129afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1130c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka } 1131c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka }; 1132b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung runOnWorkerThread(r); 11339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1134f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 11359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 11369c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Set this as the current Launcher activity object for the loader. 11379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 11389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void initialize(Callbacks callbacks) { 11399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato synchronized (mLock) { 1140aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal Preconditions.assertUIThread(); 1141aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal // Remove any queued UI runnables 1142aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal mHandler.cancelAll(); 1143aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal mCallbacks = new WeakReference<>(callbacks); 1144f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1145f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1146f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1147ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1148c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageChanged(String packageName, UserHandleCompat user) { 1149ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_UPDATE; 1150bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask(new PackageUpdatedTask(op, new String[] { packageName }, 1151ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1152ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1153ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1154ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1155c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageRemoved(String packageName, UserHandleCompat user) { 1156ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_REMOVE; 1157bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask(new PackageUpdatedTask(op, new String[] { packageName }, 1158ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1159ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1160ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1161ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1162c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackageAdded(String packageName, UserHandleCompat user) { 1163ed13187a745866483139e2878037e1f8427ce567Kenny Guy int op = PackageUpdatedTask.OP_ADD; 1164bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask(new PackageUpdatedTask(op, new String[] { packageName }, 1165ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1166ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1167ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1168ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1169c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackagesAvailable(String[] packageNames, UserHandleCompat user, 1170ed13187a745866483139e2878037e1f8427ce567Kenny Guy boolean replacing) { 1171bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask( 1172144154d435ac535b28c947cd765c02590a683d3aSunny Goyal new PackageUpdatedTask(PackageUpdatedTask.OP_UPDATE, packageNames, user)); 1173ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1174ed13187a745866483139e2878037e1f8427ce567Kenny Guy 1175ed13187a745866483139e2878037e1f8427ce567Kenny Guy @Override 1176c2bd8101b8e26b9ebb2c079ae6867229dad3f196Kenny Guy public void onPackagesUnavailable(String[] packageNames, UserHandleCompat user, 1177ed13187a745866483139e2878037e1f8427ce567Kenny Guy boolean replacing) { 1178ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!replacing) { 1179bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask(new PackageUpdatedTask( 1180ed13187a745866483139e2878037e1f8427ce567Kenny Guy PackageUpdatedTask.OP_UNAVAILABLE, packageNames, 1181ed13187a745866483139e2878037e1f8427ce567Kenny Guy user)); 1182ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1183ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1184ed13187a745866483139e2878037e1f8427ce567Kenny Guy 118544cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy @Override 118644cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy public void onPackagesSuspended(String[] packageNames, UserHandleCompat user) { 1187bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask(new PackageUpdatedTask( 118844cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy PackageUpdatedTask.OP_SUSPEND, packageNames, 118944cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy user)); 119044cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy } 119144cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy 119244cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy @Override 119344cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy public void onPackagesUnsuspended(String[] packageNames, UserHandleCompat user) { 1194bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask(new PackageUpdatedTask( 119544cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy PackageUpdatedTask.OP_UNSUSPEND, packageNames, 119644cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy user)); 119744cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy } 119844cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy 1199bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham @Override 1200bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham public void onShortcutsChanged(String packageName, List<ShortcutInfoCompat> shortcuts, 1201bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham UserHandleCompat user) { 120250941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal enqueueItemUpdatedTask(new ShortcutsChangedTask(packageName, shortcuts, user, true)); 120350941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal } 120450941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal 120550941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal public void updatePinnedShortcuts(String packageName, List<ShortcutInfoCompat> shortcuts, 120650941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal UserHandleCompat user) { 120750941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal enqueueItemUpdatedTask(new ShortcutsChangedTask(packageName, shortcuts, user, false)); 1208bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1209bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 12101d8e7bbe09e130af5e9534cc26a65f623be7a424Joe Onorato /** 12119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and 12129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * ACTION_PACKAGE_CHANGED. 12139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 1214cb1a4778686a46c46d8dc88b6c83674f6fac6592Narayan Kamath @Override 1215f99f8c1ad265cf7bea7e30476911d730b7d0eaaeJoe Onorato public void onReceive(Context context, Intent intent) { 1216b358f813c93ac0d6c4f31058947efd16b188cd1eChris Wren if (DEBUG_RECEIVER) Log.d(TAG, "onReceive intent=" + intent); 1217aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 12183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String action = intent.getAction(); 1219ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (Intent.ACTION_LOCALE_CHANGED.equals(action)) { 122093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // If we have changed locale we need to clear out the labels in all apps/workspace. 122193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee forceReload(); 1222d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action) 1223d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal || Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) { 1224823fd5090209017a029460e7dbd8ab9d51d013ddSunny Goyal UserManagerCompat.getInstance(context).enableAndResetCache(); 1225957c13f032fc4088b3273cec08603c67c069e2c6Sunny Goyal forceReload(); 1226d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) || 1227d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) || 1228d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) { 1229da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal UserHandleCompat user = UserHandleCompat.fromIntent(intent); 1230da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal if (user != null) { 1231d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) || 1232d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) { 1233d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal enqueueItemUpdatedTask(new PackageUpdatedTask( 1234d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal PackageUpdatedTask.OP_USER_AVAILABILITY_CHANGE, 1235d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal new String[0], user)); 1236d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 1237d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 1238d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // ACTION_MANAGED_PROFILE_UNAVAILABLE sends the profile back to locked mode, so 1239d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // we need to run the state change task again. 1240d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action) || 1241d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)) { 1242d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal enqueueItemUpdatedTask(new UserLockStateChangedTask(user)); 1243d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 1244da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal } 1245827cef203f386cb548b98a7fa9888b75478c8e20Tony Wickham } else if (Intent.ACTION_WALLPAPER_CHANGED.equals(action)) { 1246827cef203f386cb548b98a7fa9888b75478c8e20Tony Wickham ExtractionUtils.startColorExtractionServiceIfNecessary(context); 1247e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1248e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1249e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato 12506cc806d678c8a44478308119c087ac9adde73b66Amith Yamasani void forceReload() { 1251f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung resetLoadedState(true, true); 1252f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 1253f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // Do this here because if the launcher activity is running it will be restarted. 1254f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // If it's not running startLoaderFromBackground will merely tell it that it needs 1255f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung // to reload. 1256f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung startLoaderFromBackground(); 1257f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung } 1258f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung 1259f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung public void resetLoadedState(boolean resetAllAppsLoaded, boolean resetWorkspaceLoaded) { 126093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (mLock) { 126193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // Stop any existing loaders first, so they don't set mAllAppsLoaded or 126293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee // mWorkspaceLoaded to true later 126393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee stopLoaderLocked(); 1264f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung if (resetAllAppsLoaded) mAllAppsLoaded = false; 1265f0c6ae0e35d3e020db55b5b826955da66b14b7f6Winson Chung if (resetWorkspaceLoaded) mWorkspaceLoaded = false; 1266bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // Always reset deep shortcuts loaded. 126795f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal // TODO: why? 1268bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mDeepShortcutsLoaded = false; 126993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 127093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 127193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 1272e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato /** 1273e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * When the launcher is in the background, it's possible for it to miss paired 1274e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * configuration changes. So whenever we trigger the loader from the background 1275e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * tell the launcher that it needs to re-run the loader when it comes back instead 1276e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato * of doing it now. 1277e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato */ 1278e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato public void startLoaderFromBackground() { 1279e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks callbacks = getCallback(); 1280e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (callbacks != null) { 1281e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Only actually run the loader if they're not paused. 1282e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal if (!callbacks.setLoadOnResume()) { 128393f878c1686f0438f399353b6fa61ac256f89e6dSunny Goyal startLoader(callbacks.getCurrentWorkspaceScreen()); 1284e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 1285e9ad59eba6d8ffd2cbf28520c237ccefd291a33cJoe Onorato } 12863611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1287f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 12882bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal /** 12892bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal * If there is already a loader task running, tell it to stop. 12902bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal */ 12912bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal private void stopLoaderLocked() { 129293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee LoaderTask oldTask = mLoaderTask; 129393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (oldTask != null) { 129493f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee oldTask.stopLocked(); 129593f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 129693f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 129793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee 12981a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen public boolean isCurrentCallbacks(Callbacks callbacks) { 12991a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen return (mCallbacks != null && mCallbacks.get() == callbacks); 13001a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen } 13011a85c5839c91942b3c7dd0da5992db4d98defdc3Adam Cohen 1302b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal /** 1303b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal * Starts the loader. Tries to bind {@params synchronousBindPage} synchronously if possible. 1304b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal * @return true if the page could be bound synchronously. 1305b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal */ 1306b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal public boolean startLoader(int synchronousBindPage) { 1307756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems 1308756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal InstallShortcutReceiver.enableInstallQueue(); 13093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 13103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Don't bother to start the thread if we know it's not going to do anything 13113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mCallbacks != null && mCallbacks.get() != null) { 1312527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal final Callbacks oldCallbacks = mCallbacks.get(); 1313527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal // Clear any pending bind-runnables from the synchronized load process. 1314527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal runOnMainThread(new Runnable() { 1315527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void run() { 1316527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal oldCallbacks.clearPendingBinds(); 1317527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 1318527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal }); 1319527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 13203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // If there is already one running, tell it to stop. 13212bba4c37c6402dfdc965d0c412c840c57993c7ddSunny Goyal stopLoaderLocked(); 1322ded0fdba52d94f8c841598a14dbece36a2f1849cSunny Goyal mLoaderTask = new LoaderTask(mApp.getContext(), synchronousBindPage); 132395f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal // TODO: mDeepShortcutsLoaded does not need to be true for synchronous bind. 132480f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE && mAllAppsLoaded 132580f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham && mWorkspaceLoaded && mDeepShortcutsLoaded && !mIsLoaderTaskRunning) { 1326b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mLoaderTask.runBindSynchronousPage(synchronousBindPage); 1327b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal return true; 1328b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 1329b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorkerThread.setPriority(Thread.NORM_PRIORITY); 1330b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sWorker.post(mLoaderTask); 1331b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1332b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1333b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1334b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal return false; 1335b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1336b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 13373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void stopLoader() { 13383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 13393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask != null) { 13403611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask.stopLocked(); 13419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1342f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 13433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1344b132a97cb7ee976bc54370fd0d5899876eaaf33aRomain Guy 1345c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal /** 1346c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal * Loads the workspace screen ids in an ordered list. 1347c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal */ 1348e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal public static ArrayList<Long> loadWorkspaceScreensDb(Context context) { 134976828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung final ContentResolver contentResolver = context.getContentResolver(); 135076828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung final Uri screensUri = LauncherSettings.WorkspaceScreens.CONTENT_URI; 135176828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 1352c1b7c2ecbdcf6b16e36fd8ad843d017f0eaac594Sunny Goyal // Get screens ordered by rank. 1353a9e2f5abb3c21d9721939c625ffb0caabb34e8d9Sunny Goyal return LauncherDbUtils.getScreenIdsFromCursor(contentResolver.query( 1354a9e2f5abb3c21d9721939c625ffb0caabb34e8d9Sunny Goyal screensUri, null, null, null, LauncherSettings.WorkspaceScreens.SCREEN_RANK)); 135576828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung } 135676828c87ddb50ee3b423ef26f36387a2f03fd562Winson Chung 13573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato /** 13583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * Runnable for the thread that loads the contents of the launcher: 13593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - workspace icons 13603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - widgets 13613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * - all apps icons 1362bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham * - deep shortcuts within apps 13633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato */ 13643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private class LoaderTask implements Runnable { 13653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private Context mContext; 136693f878c1686f0438f399353b6fa61ac256f89e6dSunny Goyal private int mPageToBindFirst; 136793f878c1686f0438f399353b6fa61ac256f89e6dSunny Goyal 1368091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk boolean mIsLoadingAndBindingWorkspace; 13693611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private boolean mStopped; 1370091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk boolean mLoadAndBindStepFinished; 1371b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1372ded0fdba52d94f8c841598a14dbece36a2f1849cSunny Goyal LoaderTask(Context context, int pageToBindFirst) { 13733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mContext = context; 137493f878c1686f0438f399353b6fa61ac256f89e6dSunny Goyal mPageToBindFirst = pageToBindFirst; 13753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1376f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 137766cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal private void loadAndBindWorkspace() { 137836a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung mIsLoadingAndBindingWorkspace = true; 137936a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 13803611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Load the workspace 13813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 13823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "loadAndBindWorkspace mWorkspaceLoaded=" + mWorkspaceLoaded); 13833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1384288a36b563801a26d00084cb823435a3ba4cb76cMichael Jurka 1385a8c760d395e1d2a78522427738302fbca3a72453Michael Jurka if (!mWorkspaceLoaded) { 138666cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal loadWorkspace(); 138793f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (LoaderTask.this) { 138893f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (mStopped) { 138966cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal return; 139093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 139193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mWorkspaceLoaded = true; 13929c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 13933611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1394cc67f476c01ee6a7d593fa67f80392c6793432d7Joe Onorato 13953611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Bind the workspace 139693f878c1686f0438f399353b6fa61ac256f89e6dSunny Goyal bindWorkspace(mPageToBindFirst); 13973611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1398f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 13993611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void waitForIdle() { 14003611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Wait until the either we're stopped or the other threads are done. 14013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This way we don't start loading all apps until the workspace has settled 14023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // down. 14033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 14043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long workspaceWaitTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1405843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 14063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.postIdle(new Runnable() { 14073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 14083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 14093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoadAndBindStepFinished = true; 14103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 14113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "done with previous binding step"); 14129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato LoaderTask.this.notify(); 14149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14159c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 14173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 141871b5c0b988a64b3a0613ded5403749bc537ee8a5Sunny Goyal while (!mStopped && !mLoadAndBindStepFinished) { 14193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato try { 1420c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka // Just in case mFlushingWorkerThread changes but we aren't woken up, 1421c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka // wait no longer than 1sec at a time 1422c7700af21f7b1df939fce22f4ab5072b3ea29b66Michael Jurka this.wait(1000); 14233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } catch (InterruptedException ex) { 14243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Ignore 14259c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 14263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 14273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 14283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "waited " 1429aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung + (SystemClock.uptimeMillis()-workspaceWaitTime) 14303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + "ms for previous step to finish binding"); 14319c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 1432843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 14333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1434f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1435b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung void runBindSynchronousPage(int synchronousBindPage) { 14367aff399974c756930070d82d7b2df88f125dacd6Derek Prothro if (synchronousBindPage == PagedView.INVALID_RESTORE_PAGE) { 1437b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we have a valid page index to load synchronously 1438b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Should not call runBindSynchronousPage() without " + 1439b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung "valid page index"); 1440b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1441b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (!mAllAppsLoaded || !mWorkspaceLoaded) { 1442b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we don't try and bind a specified page when the pages have not been 1443b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // loaded already (we should load everything asynchronously in that case) 1444b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Expecting AllApps and Workspace to be loaded"); 1445b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1446b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung synchronized (mLock) { 1447b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (mIsLoaderTaskRunning) { 1448b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Ensure that we are never running the background loading at this point since 1449b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // we also touch the background collections 1450b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung throw new RuntimeException("Error! Background loading is already running"); 1451b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1452b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1453b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1454b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: Throw an exception if we are already loading (since we touch the worker thread 1455b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // data structures, we can't allow any other thread to touch that data, but because 1456b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // this call is synchronous, we can get away with not locking). 1457b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1458cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler // The LauncherModel is static in the LauncherAppState and mHandler may have queued 1459a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen // operations from the previous activity. We need to ensure that all queued operations 1460a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen // are executed before any synchronous binding work is done. 1461a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen mHandler.flush(); 1462a13a2f2a7bd0550d1ad973f760ff25e1a4137c43Adam Cohen 1463b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Divide the set of loaded items into those that we are binding synchronously, and 1464b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // everything else that is to be bound normally (asynchronously). 146566cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal bindWorkspace(synchronousBindPage); 1466b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // XXX: For now, continue posting the binding of AllApps as there are other issues that 1467b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // arise from that. 1468b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung onlyBindAllApps(); 146980f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham 147080f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham bindDeepShortcuts(); 1471b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1472b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 14733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 1474b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung synchronized (mLock) { 1475f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal if (mStopped) { 1476f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal return; 1477f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal } 1478b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mIsLoaderTaskRunning = true; 1479b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 14803611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Optimize for end-user experience: if the Launcher is up and // running with the 14813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // All Apps interface in the foreground, load All Apps first. Otherwise, load the 14823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // workspace first (default). 14833611578579b4bfb25616085dafdb1a45207394f9Joe Onorato keep_running: { 148464359a53dc827797917a8d9a0697a91996789801Winson Chung if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace"); 148566cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal loadAndBindWorkspace(); 1486843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 14873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mStopped) { 14883611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break keep_running; 14893611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 14903611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 14913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato waitForIdle(); 1492f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1493843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler // second step 149464359a53dc827797917a8d9a0697a91996789801Winson Chung if (DEBUG_LOADERS) Log.d(TAG, "step 2: loading all apps"); 149564359a53dc827797917a8d9a0697a91996789801Winson Chung loadAndBindAllApps(); 1496bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 1497bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham waitForIdle(); 1498bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 1499bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // third step 1500bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (DEBUG_LOADERS) Log.d(TAG, "step 3: loading deep shortcuts"); 1501bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham loadAndBindDeepShortcuts(); 15023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1503843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler 15043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // Clear out this reference, otherwise we end up holding it until all of the 15053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // callback runnables are done. 15063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mContext = null; 1507f3d5ea926d4dd1a739b9d3816543728af723cc26Joe Onorato 15083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 15093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // If we are still the last one to be scheduled, remove ourselves. 15103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask == this) { 15113611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask = null; 1512843e860e8ebab96ff70988f2829fac38afd9d937Daniel Sandler } 1513b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung mIsLoaderTaskRunning = false; 1514756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal mHasLoaderCompletedOnce = true; 15153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 15163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1517f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 15183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void stopLocked() { 15193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (LoaderTask.this) { 15203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mStopped = true; 15213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato this.notify(); 1522f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 15233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1524f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 15253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato /** 15263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * Gets the callbacks object. If we've been stopped, or if the launcher object 15273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * has somehow been garbage collected, return null instead. Pass in the Callbacks 15283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * object that was around when the deferred message was scheduled, and if there's 15293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * a new Callbacks object around then also return null. This will save us from 15303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato * calling onto it with data that will be ignored. 15313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato */ 15323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Callbacks tryGetCallbacks(Callbacks oldCallbacks) { 15333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato synchronized (mLock) { 15343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mStopped) { 15353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 15363611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1537ac03330c9684f98b4dd067a87ca70d3e0be1cfedJoe Onorato 15383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mCallbacks == null) { 15393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 15403611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1541f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 15423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = mCallbacks.get(); 15433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != oldCallbacks) { 15443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 15453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 15463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks == null) { 15473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "no mCallbacks"); 15483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return null; 15499c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 15503611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 15513611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return callbacks; 1552f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 15533611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1554f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 15553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // check & update map of what's occupied; used to discard overlapping/invalid items 1556ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal private boolean checkItemPlacement(LongArrayMap<GridOccupancy> occupied, ItemInfo item, 155741cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal ArrayList<Long> workspaceScreens) { 1558892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 15592e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); 1560892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 1561dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen long containerIndex = item.screenId; 1562f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 1563a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung // Return early if we detect that an item is under the hotseat button 1564bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal if (!FeatureFlags.NO_ALL_APPS_ICON && 1565bb011dad4e69bec027be1e00d573a3095b318b43Sunny Goyal profile.isAllAppsButtonRank((int) item.screenId)) { 1566295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler Log.e(TAG, "Error loading shortcut into hotseat " + item 1567295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler + " into position (" + item.screenId + ":" + item.cellX + "," 1568295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler + item.cellY + ") occupied by all apps"); 1569a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung return false; 1570a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung } 1571a0b7e86299ed9baf278e0c1ed73f4a4f6a057322Winson Chung 1572ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal final GridOccupancy hotseatOccupancy = 1573295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler occupied.get((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT); 1574295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler 15752e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen if (item.screenId >= profile.numHotseatIcons) { 1576ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen Log.e(TAG, "Error loading shortcut " + item 1577ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + " into hotseat position " + item.screenId 15782e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen + ", position out of bounds: (0 to " + (profile.numHotseatIcons - 1) 1579ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + ")"); 1580ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen return false; 1581ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen } 1582ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 1583ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal if (hotseatOccupancy != null) { 1584ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal if (hotseatOccupancy.cells[(int) item.screenId][0]) { 1585dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Log.e(TAG, "Error loading shortcut into hotseat " + item 1586dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen + " into position (" + item.screenId + ":" + item.cellX + "," 1587ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal + item.cellY + ") already occupied"); 1588dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen return false; 1589295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler } else { 1590ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal hotseatOccupancy.cells[(int) item.screenId][0] = true; 1591295ae18d0fa7c102c50cf95a2ea09e7f2e9b1539Dan Sandler return true; 1592dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 15936ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung } else { 1594ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal final GridOccupancy occupancy = new GridOccupancy(profile.numHotseatIcons, 1); 1595ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal occupancy.cells[(int) item.screenId][0] = true; 1596ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal occupied.put((long) LauncherSettings.Favorites.CONTAINER_HOTSEAT, occupancy); 15976ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung return true; 15986ba2a1b6e7595a14ba33e98f728b39d0ecb3ae36Winson Chung } 159941cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal } else if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { 160041cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal if (!workspaceScreens.contains((Long) item.screenId)) { 160141cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal // The item has an invalid screen id. 160241cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal return false; 160341cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal } 160441cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal } else { 1605f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung // Skip further checking if it is not the hotseat or workspace container 16063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return true; 16073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 1608f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung 1609ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal final int countX = profile.numColumns; 1610ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal final int countY = profile.numRows; 1611ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 1612ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen item.cellX < 0 || item.cellY < 0 || 1613ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen item.cellX + item.spanX > countX || item.cellY + item.spanY > countY) { 1614ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen Log.e(TAG, "Error loading shortcut " + item 1615ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + " into cell (" + containerIndex + "-" + item.screenId + ":" 1616ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + item.cellX + "," + item.cellY 1617ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen + ") out of screen bounds ( " + countX + "x" + countY + ")"); 1618ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen return false; 1619ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen } 1620ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 1621ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal if (!occupied.containsKey(item.screenId)) { 1622da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal GridOccupancy screen = new GridOccupancy(countX + 1, countY + 1); 1623da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal if (item.screenId == Workspace.FIRST_SCREEN_ID) { 1624a9e2f5abb3c21d9721939c625ffb0caabb34e8d9Sunny Goyal // Mark the first row as occupied (if the feature is enabled) 1625a9e2f5abb3c21d9721939c625ffb0caabb34e8d9Sunny Goyal // in order to account for the QSB. 1626a9e2f5abb3c21d9721939c625ffb0caabb34e8d9Sunny Goyal screen.markCells(0, 0, countX + 1, 1, FeatureFlags.QSB_ON_FIRST_SCREEN); 1627da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal } 1628da4fe1a6244457f144e0a331cada3ada17157809Sunny Goyal occupied.put(item.screenId, screen); 16298802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler } 1630ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal final GridOccupancy occupancy = occupied.get(item.screenId); 1631f30ad5f1bf33baceeca6b770464fb543b58af985Winson Chung 1632ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal // Check if any workspace icons overlap with each other 1633ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal if (occupancy.isRegionVacant(item.cellX, item.cellY, item.spanX, item.spanY)) { 1634ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal occupancy.markCells(item, true); 1635ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal return true; 1636ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal } else { 1637ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal Log.e(TAG, "Error loading shortcut " + item 1638ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal + " into cell (" + containerIndex + "-" + item.screenId + ":" 1639ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal + item.cellX + "," + item.cellX + "," + item.spanX + "," + item.spanY 1640ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal + ") already occupied"); 1641ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal return false; 1642ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal } 16433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 16448802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler 1645ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung /** Clears all the sBg data structures */ 1646ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung private void clearSBgDataStructures() { 1647ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung synchronized (sBgLock) { 1648ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceItems.clear(); 1649ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgAppWidgets.clear(); 1650ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgFolders.clear(); 1651ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgItemsIdMap.clear(); 1652ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung sBgWorkspaceScreens.clear(); 1653bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham sBgPinnedShortcutCounts.clear(); 1654ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 1655ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 1656ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung 165766cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal private void loadWorkspace() { 1658e26d1008eb587303db25797ca02cc32464e45656Sunny Goyal if (LauncherAppState.PROFILE_STARTUP) { 1659e26d1008eb587303db25797ca02cc32464e45656Sunny Goyal Trace.beginSection("Loading Workspace"); 1660e26d1008eb587303db25797ca02cc32464e45656Sunny Goyal } 16613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 1662f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 16633611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Context context = mContext; 16643611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final ContentResolver contentResolver = context.getContentResolver(); 16653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final PackageManager manager = context.getPackageManager(); 16663611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final boolean isSafeMode = manager.isSafeMode(); 1667f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 166825aba0aea58b2ecbc0fd350c378fa9e45edb81c3Sunny Goyal final boolean isSdCardReady = Utilities.isBootCompleted(); 1669f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 1670892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 16712e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); 167241cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal int countX = profile.numColumns; 167341cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal int countY = profile.numRows; 1674892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 1675ded0fdba52d94f8c841598a14dbece36a2f1849cSunny Goyal boolean clearDb = false; 1676a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyal try { 1677a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyal ImportDataTask.performImportIfPossible(context); 1678a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyal } catch (Exception e) { 1679a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyal // Migration failed. Clear workspace. 1680a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyal clearDb = true; 1681a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyal } 1682a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyal 1683a5c8a9eb666da16bc4c9ea4412868e22ace8d1f0Sunny Goyal if (!clearDb && GridSizeMigrationTask.ENABLED && 1684f076eae0cab10f035f7b187c72a680cd220acf1bSunny Goyal !GridSizeMigrationTask.migrateGridIfNeeded(mContext)) { 1685f076eae0cab10f035f7b187c72a680cd220acf1bSunny Goyal // Migration failed. Clear workspace. 1686ded0fdba52d94f8c841598a14dbece36a2f1849cSunny Goyal clearDb = true; 1687e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal } 1688e5bb705fb79f18df8680958dcf2c5460e16c90b6Sunny Goyal 1689ded0fdba52d94f8c841598a14dbece36a2f1849cSunny Goyal if (clearDb) { 1690a13654529cb557abd946da4d4637593565917ecdSunny Goyal Log.d(TAG, "loadWorkspace: resetting launcher database"); 1691d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal LauncherSettings.Settings.call(contentResolver, 1692d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal LauncherSettings.Settings.METHOD_DELETE_DB); 1693d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler } 1694d502404a44fb7c4ea739622d7f8bdd2a764d97a1Dan Sandler 1695ded0fdba52d94f8c841598a14dbece36a2f1849cSunny Goyal Log.d(TAG, "loadWorkspace: loading default favorites"); 1696ded0fdba52d94f8c841598a14dbece36a2f1849cSunny Goyal LauncherSettings.Settings.call(contentResolver, 1697ded0fdba52d94f8c841598a14dbece36a2f1849cSunny Goyal LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES); 1698e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 16992abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 1700ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung clearSBgDataStructures(); 1701756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal final HashMap<String, Integer> installingPkgs = PackageInstallerCompat 17029448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal .getInstance(mContext).updateAndGetActiveSessionCache(); 170341cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal sBgWorkspaceScreens.addAll(loadWorkspaceScreensDb(mContext)); 1704b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 17052e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal final ArrayList<Long> itemsToRemove = new ArrayList<>(); 17062e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal final ArrayList<Long> restoredRows = new ArrayList<>(); 1707bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>(); 17081d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal final Uri contentUri = LauncherSettings.Favorites.CONTENT_URI; 1709e523e70f75ff90ca5d613fb8398d37208e6cd32dChris Wren if (DEBUG_LOADERS) Log.d(TAG, "loading model from " + contentUri); 1710e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen final Cursor c = contentResolver.query(contentUri, null, null, null, null); 1711b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1712b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // +1 for the hotseat (it can be larger than the workspace) 1713b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Load workspace in reverse order to ensure that latest items are loaded first (and 1714b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // before any earlier duplicates) 1715ff4ba2d99593ed84963b3f71c555b529dd905835Sunny Goyal final LongArrayMap<GridOccupancy> occupied = new LongArrayMap<>(); 17162e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null; 1717b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1718b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1719b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int idIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites._ID); 1720b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int intentIndex = c.getColumnIndexOrThrow 1721b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.INTENT); 1722b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int containerIndex = c.getColumnIndexOrThrow( 1723b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.CONTAINER); 1724b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int itemTypeIndex = c.getColumnIndexOrThrow( 1725b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.ITEM_TYPE); 1726b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int appWidgetIdIndex = c.getColumnIndexOrThrow( 1727b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.APPWIDGET_ID); 1728c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren final int appWidgetProviderIndex = c.getColumnIndexOrThrow( 1729c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren LauncherSettings.Favorites.APPWIDGET_PROVIDER); 1730b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int screenIndex = c.getColumnIndexOrThrow( 1731b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.SCREEN); 1732b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int cellXIndex = c.getColumnIndexOrThrow 1733b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.CELLX); 1734b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int cellYIndex = c.getColumnIndexOrThrow 1735b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.CELLY); 1736b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int spanXIndex = c.getColumnIndexOrThrow 1737b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung (LauncherSettings.Favorites.SPANX); 1738b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final int spanYIndex = c.getColumnIndexOrThrow( 1739b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherSettings.Favorites.SPANY); 174008f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal final int rankIndex = c.getColumnIndexOrThrow( 174108f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal LauncherSettings.Favorites.RANK); 1742f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren final int restoredIndex = c.getColumnIndexOrThrow( 1743f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren LauncherSettings.Favorites.RESTORED); 1744ed13187a745866483139e2878037e1f8427ce567Kenny Guy final int profileIdIndex = c.getColumnIndexOrThrow( 1745ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherSettings.Favorites.PROFILE_ID); 17465d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal final int optionsIndex = c.getColumnIndexOrThrow( 17475d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal LauncherSettings.Favorites.OPTIONS); 1748d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal final CursorIconInfo cursorIconInfo = new CursorIconInfo(mContext, c); 1749b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 17507f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal final LongSparseArray<UserHandleCompat> allUsers = new LongSparseArray<>(); 1751ff05f4375dd47242d7e4864287e0d5af8ac8ba8fKenny Guy final LongSparseArray<Boolean> quietMode = new LongSparseArray<>(); 1752d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>(); 17537f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal for (UserHandleCompat user : mUserManager.getUserProfiles()) { 1754ff05f4375dd47242d7e4864287e0d5af8ac8ba8fKenny Guy long serialNo = mUserManager.getSerialNumberForUser(user); 1755ff05f4375dd47242d7e4864287e0d5af8ac8ba8fKenny Guy allUsers.put(serialNo, user); 1756ff05f4375dd47242d7e4864287e0d5af8ac8ba8fKenny Guy quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user)); 1757bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 1758d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal boolean userUnlocked = mUserManager.isUserUnlocked(user); 1759d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 1760d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // We can only query for shortcuts when the user is unlocked. 1761d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (userUnlocked) { 176249f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal List<ShortcutInfoCompat> pinnedShortcuts = 176349f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal mDeepShortcutManager.queryForPinnedShortcuts(null, user); 176449f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal if (mDeepShortcutManager.wasLastCallSuccess()) { 176549f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal for (ShortcutInfoCompat shortcut : pinnedShortcuts) { 176649f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut), 176749f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal shortcut); 176849f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal } 176949f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal } else { 177049f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal // Shortcut manager can fail due to some race condition when the 177149f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal // lock state changes too frequently. For the purpose of the loading 177249f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal // shortcuts, consider the user is still locked. 177349f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal userUnlocked = false; 1774d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 1775bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 177649f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal unlockedUsers.put(serialNo, userUnlocked); 17777f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal } 17787f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal 1779b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ShortcutInfo info; 1780b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String intentDescription; 1781b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung LauncherAppWidgetInfo appWidgetInfo; 1782b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int container; 1783b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung long id; 178426ace12135a662ad864678c9fede9817e5c02b67Robin Lee long serialNumber; 1785b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent intent; 1786ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user; 1787d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal String targetPackage; 1788b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1789b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung while (!mStopped && c.moveToNext()) { 1790b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1791b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int itemType = c.getInt(itemTypeIndex); 1792f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren boolean restored = 0 != c.getInt(restoredIndex); 1793f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean allowMissingTarget = false; 1794b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal container = c.getInt(containerIndex); 1795b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1796b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (itemType) { 1797b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 1798b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1799bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: 1800ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung id = c.getLong(idIndex); 1801b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intentDescription = c.getString(intentIndex); 180226ace12135a662ad864678c9fede9817e5c02b67Robin Lee serialNumber = c.getInt(profileIdIndex); 18037f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal user = allUsers.get(serialNumber); 1804349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal int promiseType = c.getInt(restoredIndex); 18051a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal int disabledState = 0; 1806bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal boolean itemReplaced = false; 1807d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal targetPackage = null; 1808ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user == null) { 1809ed13187a745866483139e2878037e1f8427ce567Kenny Guy // User has been deleted remove the item. 1810ed13187a745866483139e2878037e1f8427ce567Kenny Guy itemsToRemove.add(id); 1811ed13187a745866483139e2878037e1f8427ce567Kenny Guy continue; 1812ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1813b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung try { 1814b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intent = Intent.parseUri(intentDescription, 0); 1815ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung ComponentName cn = intent.getComponent(); 1816f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (cn != null && cn.getPackageName() != null) { 1817f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean validPkg = launcherApps.isPackageEnabledForProfile( 1818f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal cn.getPackageName(), user); 1819f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal boolean validComponent = validPkg && 1820f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal launcherApps.isActivityEnabledForProfile(cn, user); 1821d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal if (validPkg) { 1822d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal targetPackage = cn.getPackageName(); 1823d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal } 1824f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 1825f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (validComponent) { 1826f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (restored) { 1827f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // no special handling necessary for this item 1828f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal restoredRows.add(id); 1829f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal restored = false; 1830f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 1831ff05f4375dd47242d7e4864287e0d5af8ac8ba8fKenny Guy if (quietMode.get(serialNumber)) { 1832d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal disabledState = ShortcutInfo.FLAG_DISABLED_QUIET_USER; 1833ff05f4375dd47242d7e4864287e0d5af8ac8ba8fKenny Guy } 1834f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } else if (validPkg) { 1835349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent = null; 1836349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { 1837349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // We allow auto install apps to have their intent 1838349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // updated after an install. 1839349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent = manager.getLaunchIntentForPackage( 1840349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal cn.getPackageName()); 1841349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (intent != null) { 1842349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ContentValues values = new ContentValues(); 1843349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal values.put(LauncherSettings.Favorites.INTENT, 1844349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal intent.toUri(0)); 1845bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal updateItem(id, values); 1846349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1847349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1848349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 1849349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (intent == null) { 1850349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // The app is installed but the component is no 1851349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // longer available. 1852713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal FileLog.d(TAG, "Invalid component removed: " + cn); 1853349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal itemsToRemove.add(id); 1854349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal continue; 1855349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } else { 1856349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal // no special handling necessary for this item 1857349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal restoredRows.add(id); 1858349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal restored = false; 1859349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 1860f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } else if (restored) { 1861f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // Package is not yet available but might be 1862f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // installed later. 1863713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal FileLog.d(TAG, "package not yet restored: " + cn); 18649448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal 18659448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal if ((promiseType & ShortcutInfo.FLAG_RESTORE_STARTED) != 0) { 18669448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // Restore has started once. 1867756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } else if (installingPkgs.containsKey(cn.getPackageName())) { 18689448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // App restore has started. Update the flag 18699448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal promiseType |= ShortcutInfo.FLAG_RESTORE_STARTED; 18709448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal ContentValues values = new ContentValues(); 18719448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal values.put(LauncherSettings.Favorites.RESTORED, 18729448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal promiseType); 1873bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal updateItem(id, values); 1874bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } else if ((promiseType & ShortcutInfo.FLAG_RESTORED_APP_TYPE) != 0) { 1875bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal // This is a common app. Try to replace this. 1876bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal int appType = CommonAppTypeParser.decodeItemTypeFromFlag(promiseType); 1877bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal CommonAppTypeParser parser = new CommonAppTypeParser(id, appType, context); 1878bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal if (parser.findDefaultApp()) { 1879bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal // Default app found. Replace it. 1880bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal intent = parser.parsedIntent; 1881bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal cn = intent.getComponent(); 1882bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal ContentValues values = parser.parsedValues; 1883bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal values.put(LauncherSettings.Favorites.RESTORED, 0); 1884bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal updateItem(id, values); 1885bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal restored = false; 1886bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal itemReplaced = true; 1887bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal 1888b05a00a441d7e608fd709fae62bde1c661936e2aSunny Goyal } else { 1889713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal FileLog.d(TAG, "Unrestored package removed: " + cn); 1890bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal itemsToRemove.add(id); 1891bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal continue; 1892bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } 1893b05a00a441d7e608fd709fae62bde1c661936e2aSunny Goyal } else { 1894713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal FileLog.d(TAG, "Unrestored package removed: " + cn); 18959448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal itemsToRemove.add(id); 18969448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal continue; 18979448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } 1898d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal } else if (PackageManagerHelper.isAppOnSdcard( 1899d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal manager, cn.getPackageName())) { 19001a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Package is present but not available. 19011a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal allowMissingTarget = true; 19021a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal disabledState = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE; 19031a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else if (!isSdCardReady) { 1904f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // SdCard is not ready yet. Package might get available, 1905f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // once it is ready. 1906a13654529cb557abd946da4d4637593565917ecdSunny Goyal Log.d(TAG, "Invalid package: " + cn + " (check again later)"); 1907f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal HashSet<String> pkgs = sPendingPackages.get(user); 1908f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (pkgs == null) { 1909513edaebce9846c2d5eb4c0c013a9dcf6232c0e3Sameer Padala pkgs = new HashSet<String>(); 1910f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal sPendingPackages.put(user, pkgs); 1911f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 1912f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal pkgs.add(cn.getPackageName()); 1913f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal allowMissingTarget = true; 1914f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal // Add the icon on the workspace anyway. 19151a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 19161a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else { 19171a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Do not wait for external media load anymore. 19181a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal // Log the invalid package, and remove it 1919713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal FileLog.d(TAG, "Invalid package removed: " + cn); 19201a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal itemsToRemove.add(id); 19211a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal continue; 1922ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 1923938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal } else if (cn == null) { 1924938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal // For shortcuts with no component, keep them as they are 1925938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal restoredRows.add(id); 1926938a53d8640ddec14b36b1e7ddc3e156824d9de0Sunny Goyal restored = false; 1927ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 1928b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (URISyntaxException e) { 1929713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal FileLog.d(TAG, "Invalid uri: " + intentDescription); 193041cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal itemsToRemove.add(id); 1931b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung continue; 1932b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 1933968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka 193434b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal boolean useLowResIcon = container >= 0 && 193534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW; 193634b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 1937bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal if (itemReplaced) { 1938bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal if (user.equals(UserHandleCompat.myUserHandle())) { 1939d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info = getAppShortcutInfo(intent, user, null, 1940d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal cursorIconInfo, false, useLowResIcon); 1941bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } else { 1942bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal // Don't replace items for other profiles. 1943bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal itemsToRemove.add(id); 1944bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal continue; 1945bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } 1946bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } else if (restored) { 1947ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user.equals(UserHandleCompat.myUserHandle())) { 1948d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info = getRestoredItemInfo(c, intent, 1949d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal promiseType, itemType, cursorIconInfo); 1950ed13187a745866483139e2878037e1f8427ce567Kenny Guy intent = getRestoredItemIntent(c, context, intent); 1951ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 1952ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Don't restore items for other profiles. 1953ed13187a745866483139e2878037e1f8427ce567Kenny Guy itemsToRemove.add(id); 1954ed13187a745866483139e2878037e1f8427ce567Kenny Guy continue; 1955ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 1956f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } else if (itemType == 1957f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 1958d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info = getAppShortcutInfo(intent, user, c, 1959d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal cursorIconInfo, allowMissingTarget, useLowResIcon); 1960bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } else if (itemType == 1961bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { 1962d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 1963d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal ShortcutKey key = ShortcutKey.fromIntent(intent, user); 1964d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (unlockedUsers.get(serialNumber)) { 1965d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal ShortcutInfoCompat pinnedShortcut = 1966d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal shortcutKeyToPinnedShortcuts.get(key); 1967d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (pinnedShortcut == null) { 1968d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // The shortcut is no longer valid. 1969d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal itemsToRemove.add(id); 1970d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal continue; 1971bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1972d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info = new ShortcutInfo(pinnedShortcut, context); 1973d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal intent = info.intent; 1974d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } else { 1975d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // Create a shortcut info in disabled mode for now. 1976d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info = new ShortcutInfo(); 1977d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info.user = user; 1978d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info.itemType = itemType; 1979d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal loadInfoFromCursor(info, c, cursorIconInfo); 1980d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 1981d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER; 1982bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 1983d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal incrementPinnedShortcutCount(key, false /* shouldPin */); 1984bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } else { // item type == ITEM_TYPE_SHORTCUT 1985d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info = getShortcutInfo(c, cursorIconInfo); 1986b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 1987d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal // Shortcuts are only available on the primary profile 1988d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal if (PackageManagerHelper.isAppSuspended(manager, targetPackage)) { 1989d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED; 1990d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal } 1991d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal 1992b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // App shortcuts that used to be automatically added to Launcher 1993b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // didn't always have the correct intent flags set, so do that 1994b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // here 1995b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (intent.getAction() != null && 19969ad005639e1698c94674cdfadf3ae342fb56c9b5Michael Jurka intent.getCategories() != null && 19979ad005639e1698c94674cdfadf3ae342fb56c9b5Michael Jurka intent.getAction().equals(Intent.ACTION_MAIN) && 1998968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) { 1999b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung intent.addFlags( 2000b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent.FLAG_ACTIVITY_NEW_TASK | 2001b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 2002b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2003968795679be0a3f0118d5a6e2e1580808da5716dMichael Jurka } 20043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 2005b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info != null) { 2006ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung info.id = id; 2007b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.intent = intent; 2008b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.container = container; 2009dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen info.screenId = c.getInt(screenIndex); 2010b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.cellX = c.getInt(cellXIndex); 2011b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung info.cellY = c.getInt(cellYIndex); 201208f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal info.rank = c.getInt(rankIndex); 20135f8afe6280eae34620067696173e71943e1a30a3Winson Chung info.spanX = 1; 20145f8afe6280eae34620067696173e71943e1a30a3Winson Chung info.spanY = 1; 2015ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.intent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); 20164e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (info.promisedIntent != null) { 20174e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal info.promisedIntent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber); 20184e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 2019d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal info.isDisabled |= disabledState; 20201a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (isSafeMode && !Utilities.isSystemApp(context, intent)) { 20211a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE; 20221a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 2023ae4409dea97d03f0f0a9195ab648188efa2b5cc1Adam Cohen 2024b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // check & update map of what's occupied 202541cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal if (!checkItemPlacement(occupied, info, sBgWorkspaceScreens)) { 2026fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 2027b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2028b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2029b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2030756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (restored) { 2031756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal ComponentName cn = info.getTargetComponent(); 2032756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (cn != null) { 2033756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Integer progress = installingPkgs.get(cn.getPackageName()); 2034756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal if (progress != null) { 2035756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal info.setInstallProgress(progress); 2036756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } else { 2037756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE; 2038756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 2039756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 2040756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 2041756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 2042b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung switch (container) { 2043b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: 2044b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: 2045b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(info); 2046b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2047b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung default: 2048b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Item is in a user folder 2049b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folderInfo = 2050b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung findOrMakeFolder(sBgFolders, container); 2051c52ba710053e4c6927937dd1a26d1abe06b6fa99Sunny Goyal folderInfo.add(info, false); 2052b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2053b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2054b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(info.id, info); 20551323b4856a2a822af77293cadeda9910a5d1ba0eWinson Chung } else { 20561323b4856a2a822af77293cadeda9910a5d1ba0eWinson Chung throw new RuntimeException("Unexpected null ShortcutInfo"); 2057b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2058b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2059b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2060b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: 2061b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung id = c.getLong(idIndex); 2062b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung FolderInfo folderInfo = findOrMakeFolder(sBgFolders, id); 2063b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2064a508e4f804c2bddf9e2cdfa3d0bd4a8202ff2151Sunny Goyal // Do not trim the folder label, as is was set by the user. 2065d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal folderInfo.title = c.getString(cursorIconInfo.titleIndex); 2066b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.id = id; 2067b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.container = container; 2068dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen folderInfo.screenId = c.getInt(screenIndex); 2069b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.cellX = c.getInt(cellXIndex); 2070b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung folderInfo.cellY = c.getInt(cellYIndex); 20715f8afe6280eae34620067696173e71943e1a30a3Winson Chung folderInfo.spanX = 1; 20725f8afe6280eae34620067696173e71943e1a30a3Winson Chung folderInfo.spanY = 1; 20735d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal folderInfo.options = c.getInt(optionsIndex); 20745f8afe6280eae34620067696173e71943e1a30a3Winson Chung 20753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // check & update map of what's occupied 207641cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal if (!checkItemPlacement(occupied, folderInfo, sBgWorkspaceScreens)) { 2077fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 20783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 20799c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 20805f8afe6280eae34620067696173e71943e1a30a3Winson Chung 20813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato switch (container) { 2082b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: 2083b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: 2084b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgWorkspaceItems.add(folderInfo); 2085b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 20869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 208717a8922e2ab2ad599df3750d398a095473ccd1b4Joe Onorato 2088f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren if (restored) { 2089f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren // no special handling required for restored folders 2090f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren restoredRows.add(id); 2091f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 2092f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 2093b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(folderInfo.id, folderInfo); 2094b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgFolders.put(folderInfo.id, folderInfo); 2095b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2096b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2097b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 20985940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET: 2099b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Read all Launcher-specific widget details 21005940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen boolean customWidget = itemType == 21015940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET; 21025940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 2103b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung int appWidgetId = c.getInt(appWidgetIdIndex); 21047f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal serialNumber = c.getLong(profileIdIndex); 2105c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren String savedProvider = c.getString(appWidgetProviderIndex); 21063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato id = c.getLong(idIndex); 21077f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal user = allUsers.get(serialNumber); 21087f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal if (user == null) { 21097f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal itemsToRemove.add(id); 21107f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal continue; 21117f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal } 21127f834d2b3084f012b935e6e95f038f2eb4a0acfaSunny Goyal 2113ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final ComponentName component = 2114ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal ComponentName.unflattenFromString(savedProvider); 2115f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 2116651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal final int restoreStatus = c.getInt(restoredIndex); 2117ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean isIdValid = (restoreStatus & 2118ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) == 0; 2119ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean wasProviderReady = (restoreStatus & 2120ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0; 2121ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 21222e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal if (widgetProvidersMap == null) { 21232e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal widgetProvidersMap = AppWidgetManagerCompat 21242e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal .getInstance(mContext).getAllProvidersMap(); 21252e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal } 21262e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal final AppWidgetProviderInfo provider = widgetProvidersMap.get( 21272e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal new ComponentKey( 212826ace12135a662ad864678c9fede9817e5c02b67Robin Lee ComponentName.unflattenFromString(savedProvider), 21292e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal user)); 2130ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2131ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal final boolean isProviderReady = isValidProvider(provider); 21325940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!isSafeMode && !customWidget && 21335940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen wasProviderReady && !isProviderReady) { 2134713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal FileLog.d(TAG, "Deleting widget that isn't installed anymore: " 2135a13654529cb557abd946da4d4637593565917ecdSunny Goyal + provider); 2136b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsToRemove.add(id); 2137b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2138ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (isProviderReady) { 2139651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, 2140651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal provider.provider); 21415940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 214253f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal // The provider is available. So the widget is either 214353f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal // available or not available. We do not need to track 214453f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal // any future restore updates. 214553f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal int status = restoreStatus & 214653f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; 2147ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (!wasProviderReady) { 2148ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // If provider was not previously ready, update the 2149ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // status and UI flag. 2150ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2151ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal // Id would be valid only if the widget restore broadcast was received. 2152ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal if (isIdValid) { 215386df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY; 2154ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } else { 2155ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal status &= ~LauncherAppWidgetInfo 2156ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal .FLAG_PROVIDER_NOT_READY; 2157ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } 2158ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal } 2159ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal appWidgetInfo.restoreStatus = status; 2160651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } else { 2161651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal Log.v(TAG, "Widget restore pending id=" + id 2162651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal + " appWidgetId=" + appWidgetId 2163651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal + " status =" + restoreStatus); 2164651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId, 2165ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal component); 2166651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal appWidgetInfo.restoreStatus = restoreStatus; 2167756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal Integer installProgress = installingPkgs.get(component.getPackageName()); 21689448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal 21699448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal if ((restoreStatus & LauncherAppWidgetInfo.FLAG_RESTORE_STARTED) != 0) { 21709448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // Restore has started once. 2171756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } else if (installProgress != null) { 21729448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal // App restore has started. Update the flag 21739448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal appWidgetInfo.restoreStatus |= 21749448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; 2175b05a00a441d7e608fd709fae62bde1c661936e2aSunny Goyal } else if (!isSafeMode) { 2176713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal FileLog.d(TAG, "Unrestored widget removed: " + component); 21779448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal itemsToRemove.add(id); 21789448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal continue; 21799448536b113afa6ceefce26604a1b44618d1d4f2Sunny Goyal } 2180756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 2181756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal appWidgetInfo.installProgress = 2182756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal installProgress == null ? 0 : installProgress; 2183651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } 218486df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal if (appWidgetInfo.hasRestoreFlag( 218586df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) { 218686df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal intentDescription = c.getString(intentIndex); 218786df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal if (!TextUtils.isEmpty(intentDescription)) { 218886df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal appWidgetInfo.bindOptions = 218986df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal Intent.parseUri(intentDescription, 0); 219086df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal } 219186df138d9f5b32d947f3497314694a2a7adac70cSunny Goyal } 2192ff572277112ec3d6a6a8c1be274d6fa1019e3648Sunny Goyal 2193b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.id = id; 2194dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen appWidgetInfo.screenId = c.getInt(screenIndex); 2195b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.cellX = c.getInt(cellXIndex); 2196b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.cellY = c.getInt(cellYIndex); 2197b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.spanX = c.getInt(spanXIndex); 2198b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgetInfo.spanY = c.getInt(spanYIndex); 2199ab7a4fe206b4ca1c18457738d5068df473a01ea5Sunny Goyal appWidgetInfo.user = user; 2200b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2201b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && 2202b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 2203b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.e(TAG, "Widget found where container != " + 220441cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!"); 220541cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal itemsToRemove.add(id); 2206b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung continue; 2207b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2208b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2209b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal appWidgetInfo.container = container; 2210b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // check & update map of what's occupied 221141cdc8d20a9ffc35eb5cde29a187a09d62cca8a1Sunny Goyal if (!checkItemPlacement(occupied, appWidgetInfo, sBgWorkspaceScreens)) { 2212fc0fe6b9be040122bc6047ef7f91b20fc8ead9ccSunny Goyal itemsToRemove.add(id); 2213b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung break; 2214b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2215651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal 22165940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!customWidget) { 22175940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen String providerName = 22185940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.providerName.flattenToString(); 22195940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen if (!providerName.equals(savedProvider) || 22205940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen (appWidgetInfo.restoreStatus != restoreStatus)) { 22215940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen ContentValues values = new ContentValues(); 22225940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen values.put( 22235940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen LauncherSettings.Favorites.APPWIDGET_PROVIDER, 22245940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen providerName); 22255940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen values.put(LauncherSettings.Favorites.RESTORED, 22265940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen appWidgetInfo.restoreStatus); 2227bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal updateItem(id, values); 22285940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 2229c3919c0e994309982efc8779af57e2bc78dcac43Chris Wren } 2230b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgItemsIdMap.put(appWidgetInfo.id, appWidgetInfo); 2231b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sBgAppWidgets.add(appWidgetInfo); 2232b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 22339c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato break; 22343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2235b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } catch (Exception e) { 2236a13654529cb557abd946da4d4637593565917ecdSunny Goyal Log.e(TAG, "Desktop items loading interrupted", e); 2237b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2238b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2239b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } finally { 2240713edfce264db7edc409216d5c083f8dd6a7083fSunny Goyal Utilities.closeSilently(c); 2241b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2242ad72e1705c32da463a552f2283ae467dc15a4a34Joe Onorato 2243ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung // Break early if we've stopped loading 2244ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung if (mStopped) { 2245ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung clearSBgDataStructures(); 224666cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal return; 2247ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung } 2248ba9c37f41c41121a38d5a52232953d4b103e9471Winson Chung 2249b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemsToRemove.size() > 0) { 2250b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Remove dead items 2251b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal contentResolver.delete(LauncherSettings.Favorites.CONTENT_URI, 2252b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal Utilities.createDbSelectionQuery( 2253b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal LauncherSettings.Favorites._ID, itemsToRemove), null); 2254b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal if (DEBUG_LOADERS) { 2255b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal Log.d(TAG, "Removed = " + Utilities.createDbSelectionQuery( 2256b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal LauncherSettings.Favorites._ID, itemsToRemove)); 2257b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal } 2258b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal 2259b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal // Remove any empty folder 2260d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal ArrayList<Long> deletedFolderIds = (ArrayList<Long>) LauncherSettings.Settings 2261d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal .call(contentResolver, 2262d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS) 2263d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal .getSerializable(LauncherSettings.Settings.EXTRA_VALUE); 2264d249748abf357925b326d57ab68eb6c2b23c4ef6Sunny Goyal for (long folderId : deletedFolderIds) { 2265b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal sBgWorkspaceItems.remove(sBgFolders.get(folderId)); 2266b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal sBgFolders.remove(folderId); 2267b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal sBgItemsIdMap.remove(folderId); 2268b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2269b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 22708802e960495e61803c18ea3dda2e30ef0a611d8fDaniel Sandler 2271bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // Unpin shortcuts that don't exist on the workspace. 2272bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) { 2273bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham MutableInt numTimesPinned = sBgPinnedShortcutCounts.get(key); 2274bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (numTimesPinned == null || numTimesPinned.value == 0) { 2275bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // Shortcut is pinned but doesn't exist on the workspace; unpin it. 2276bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mDeepShortcutManager.unpinShortcut(key); 2277bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2278bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2279bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 2280317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal // Sort all the folder items and make sure the first 3 items are high resolution. 2281317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal for (FolderInfo folder : sBgFolders) { 2282317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR); 2283317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal int pos = 0; 2284317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal for (ShortcutInfo info : folder.contents) { 2285317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal if (info.usingLowResIcon) { 2286317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal info.updateIcon(mIconCache, false); 2287317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal } 2288317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal pos ++; 2289317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal if (pos >= FolderIcon.NUM_ITEMS_IN_PREVIEW) { 2290317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal break; 2291317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal } 2292317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal } 2293317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal } 2294317698bd012c1930b83bb4e2e47ac9e363fa6c6aSunny Goyal 2295f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren if (restoredRows.size() > 0) { 2296f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren // Update restored items that no longer require special handling 2297b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal ContentValues values = new ContentValues(); 2298b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal values.put(LauncherSettings.Favorites.RESTORED, 0); 2299b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal contentResolver.update(LauncherSettings.Favorites.CONTENT_URI, values, 2300b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal Utilities.createDbSelectionQuery( 2301b1622cc30f2fd9b579cb918083e063685950df92Sunny Goyal LauncherSettings.Favorites._ID, restoredRows), null); 2302f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 2303f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 2304f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!isSdCardReady && !sPendingPackages.isEmpty()) { 2305f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal context.registerReceiver(new AppsAvailabilityCheck(), 230625aba0aea58b2ecbc0fd350c378fa9e45edb81c3Sunny Goyal new IntentFilter(Intent.ACTION_BOOT_COMPLETED), 2307f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal null, sWorker); 2308f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2309f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 231066cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal // Remove any empty screens 231166cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal ArrayList<Long> unusedScreens = new ArrayList<Long>(sBgWorkspaceScreens); 2312e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo item: sBgItemsIdMap) { 231366cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal long screenId = item.screenId; 231466cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 231566cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal unusedScreens.contains(screenId)) { 231666cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal unusedScreens.remove(screenId); 2317dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 231866cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal } 2319dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 232066cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal // If there are any empty screens remove them, and update. 232166cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal if (unusedScreens.size() != 0) { 232266cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal sBgWorkspaceScreens.removeAll(unusedScreens); 232366cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal updateWorkspaceScreenOrder(context, sBgWorkspaceScreens); 2324dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2325dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2326b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (DEBUG_LOADERS) { 2327b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "loaded workspace in " + (SystemClock.uptimeMillis()-t) + "ms"); 2328b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "workspace layout: "); 2329dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen int nScreens = occupied.size(); 2330892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung for (int y = 0; y < countY; y++) { 2331b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung String line = ""; 2332dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2333e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (int i = 0; i < nScreens; i++) { 2334e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal long screenId = occupied.keyAt(i); 2335c916834ad0da535f08325bcd902a60070f2f7e53Winson Chung if (screenId > 0) { 2336b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung line += " | "; 2337b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 23389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2339b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.d(TAG, "[ " + line + " ]"); 23409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 23419c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 23423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2343e26d1008eb587303db25797ca02cc32464e45656Sunny Goyal if (LauncherAppState.PROFILE_STARTUP) { 2344e26d1008eb587303db25797ca02cc32464e45656Sunny Goyal Trace.endSection(); 2345e26d1008eb587303db25797ca02cc32464e45656Sunny Goyal } 2346e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 2347e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 2348bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal /** 2349bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal * Partially updates the item without any notification. Must be called on the worker thread. 2350bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal */ 2351bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal private void updateItem(long itemId, ContentValues update) { 2352bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal mContext.getContentResolver().update( 23531d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal LauncherSettings.Favorites.CONTENT_URI, 2354bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal update, 2355bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal BaseColumns._ID + "= ?", 2356bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal new String[]{Long.toString(itemId)}); 2357bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal } 2358bb3b02f562bef4de063099c085d3199a77d06cfdSunny Goyal 2359b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of items who are directly or indirectly (via another container) on the 2360b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * specified screen. */ 23619b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung private void filterCurrentWorkspaceItems(long currentScreenId, 2362b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> allWorkspaceItems, 2363b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> currentScreenItems, 2364b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<ItemInfo> otherScreenItems) { 23652abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung // Purge any null ItemInfos 23662abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung Iterator<ItemInfo> iter = allWorkspaceItems.iterator(); 23672abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung while (iter.hasNext()) { 23682abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung ItemInfo i = iter.next(); 23692abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (i == null) { 23702abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung iter.remove(); 23712abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung } 23722abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung } 23732abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung 2374b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Order the set of items by their containers first, this allows use to walk through the 2375b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // list sequentially, build up a list of containers that are in the specified screen, 2376b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // as well as all items in those containers. 2377b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Set<Long> itemsOnScreen = new HashSet<Long>(); 2378b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Collections.sort(allWorkspaceItems, new Comparator<ItemInfo>() { 2379b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 2380b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public int compare(ItemInfo lhs, ItemInfo rhs) { 238112fb9fc3c3133c3a748deef7a0265e6a11a24cd6Winson return Utilities.longCompare(lhs.container, rhs.container); 2382b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2383b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }); 2384b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (ItemInfo info : allWorkspaceItems) { 2385b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { 23869b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung if (info.screenId == currentScreenId) { 2387b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2388b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2389b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2390b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenItems.add(info); 23913611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2392b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { 2393b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2394b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2395b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2396b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (itemsOnScreen.contains(info.container)) { 2397b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenItems.add(info); 2398b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung itemsOnScreen.add(info.id); 2399b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2400b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenItems.add(info); 24015c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 24025c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 24033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2404b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 24055c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 2406b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Filters the set of widgets which are on the specified screen. */ 24079b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung private void filterCurrentAppWidgets(long currentScreenId, 2408b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> appWidgets, 2409b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> currentScreenWidgets, 2410b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) { 2411b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2412b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (LauncherAppWidgetInfo widget : appWidgets) { 24132abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung if (widget == null) continue; 2414b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP && 24159b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung widget.screenId == currentScreenId) { 2416b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung currentScreenWidgets.add(widget); 2417b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } else { 2418b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherScreenWidgets.add(widget); 2419a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato } 24209c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 24213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 242231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2423b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to 2424b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * right) */ 2425b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) { 2426892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung final LauncherAppState app = LauncherAppState.getInstance(); 24272e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen final InvariantDeviceProfile profile = app.getInvariantDeviceProfile(); 2428882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung final int screenCols = profile.numColumns; 2429882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung final int screenCellCount = profile.numColumns * profile.numRows; 2430b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Collections.sort(workspaceItems, new Comparator<ItemInfo>() { 2431db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung @Override 2432db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung public int compare(ItemInfo lhs, ItemInfo rhs) { 2433882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung if (lhs.container == rhs.container) { 2434882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung // Within containers, order by their spatial position in that container 2435882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung switch ((int) lhs.container) { 2436882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung case LauncherSettings.Favorites.CONTAINER_DESKTOP: { 2437882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung long lr = (lhs.screenId * screenCellCount + 2438882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung lhs.cellY * screenCols + lhs.cellX); 2439882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung long rr = (rhs.screenId * screenCellCount + 2440882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung rhs.cellY * screenCols + rhs.cellX); 2441722e85678aa4aabd5e92f492544dbb3015fbd352Winson return Utilities.longCompare(lr, rr); 2442882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung } 2443882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung case LauncherSettings.Favorites.CONTAINER_HOTSEAT: { 2444882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung // We currently use the screen id as the rank 2445722e85678aa4aabd5e92f492544dbb3015fbd352Winson return Utilities.longCompare(lhs.screenId, rhs.screenId); 2446882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung } 2447882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung default: 24486c56c68555dcb3d99b05d5faecd582a1f683cc92Sunny Goyal if (ProviderConfig.IS_DOGFOOD_BUILD) { 2449882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung throw new RuntimeException("Unexpected container type when " + 2450882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung "sorting workspace items."); 2451882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung } 2452882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung return 0; 2453882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung } 2454882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung } else { 2455882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung // Between containers, order by hotseat, desktop 2456722e85678aa4aabd5e92f492544dbb3015fbd352Winson return Utilities.longCompare(lhs.container, rhs.container); 2457882a52eacf9e3bba09aa693f4982c2b8c41d25bbWinson Chung } 2458db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung } 2459db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung }); 2460b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2461db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung 2462dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen private void bindWorkspaceScreens(final Callbacks oldCallbacks, 2463dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final ArrayList<Long> orderedScreens) { 2464dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen final Runnable r = new Runnable() { 2465dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen @Override 2466dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen public void run() { 2467dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2468dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen if (callbacks != null) { 2469dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen callbacks.bindScreens(orderedScreens); 2470dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2471dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2472dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen }; 2473d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 2474dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen } 2475dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2476b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung private void bindWorkspaceItems(final Callbacks oldCallbacks, 2477b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<ItemInfo> workspaceItems, 2478b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final ArrayList<LauncherAppWidgetInfo> appWidgets, 2479527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal final Executor executor) { 2480603bcb91a091d0f4512fdfb92d6df3c6f9fa8059Winson Chung 2481b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the workspace items 2482db8a8944ede3be4ee63b43e24c407a3aaabee4deWinson Chung int N = workspaceItems.size(); 2483b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int i = 0; i < N; i += ITEMS_CHUNK) { 24843611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int start = i; 24853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i); 2486b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 2487b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung @Override 24889c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato public void run() { 2489c131b74922e6323331c374856bda830010d761c8Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 24909c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (callbacks != null) { 249164359a53dc827797917a8d9a0697a91996789801Winson Chung callbacks.bindItems(workspaceItems, start, start+chunkSize, 249264359a53dc827797917a8d9a0697a91996789801Winson Chung false); 24939c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 24949c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2495b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2496527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal executor.execute(r); 2497b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2498b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2499b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Bind the widgets, one at a time 2500b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung N = appWidgets.size(); 2501b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung for (int i = 0; i < N; i++) { 2502b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final LauncherAppWidgetInfo widget = appWidgets.get(i); 2503b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Runnable r = new Runnable() { 2504b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung public void run() { 2505b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2506b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 2507b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.bindAppWidget(widget); 25083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2509b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2510b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2511527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal executor.execute(r); 25123611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2513b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2514b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2515b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung /** 2516b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung * Binds all loaded data to actual views on the main thread. 2517b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung */ 251866cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal private void bindWorkspace(int synchronizeBindPage) { 2519b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final long t = SystemClock.uptimeMillis(); 2520b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Runnable r; 2521b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2522b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Don't use these two variables in any of the callback runnables. 2523b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Otherwise we hold a reference to them. 2524b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung final Callbacks oldCallbacks = mCallbacks.get(); 2525b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (oldCallbacks == null) { 2526b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // This launcher has exited and nobody bothered to tell us. Just bail. 2527b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Log.w(TAG, "LoaderTask running with no launcher"); 2528b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung return; 2529b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2530b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 25319b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // Save a copy of all the bg-thread collections 253244c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal ArrayList<ItemInfo> workspaceItems = new ArrayList<>(); 253344c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal ArrayList<LauncherAppWidgetInfo> appWidgets = new ArrayList<>(); 253444c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal ArrayList<Long> orderedScreenIds = new ArrayList<>(); 2535e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal 25362abf94d37c220c3af01aec05cc6ca22f9854d8e0Winson Chung synchronized (sBgLock) { 2537b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung workspaceItems.addAll(sBgWorkspaceItems); 2538b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung appWidgets.addAll(sBgAppWidgets); 2539dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen orderedScreenIds.addAll(sBgWorkspaceScreens); 2540b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2541b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2542b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal final int currentScreen; 2543b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal { 2544b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal int currScreen = synchronizeBindPage != PagedView.INVALID_RESTORE_PAGE 2545b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal ? synchronizeBindPage : oldCallbacks.getCurrentWorkspaceScreen(); 2546b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal if (currScreen >= orderedScreenIds.size()) { 2547b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal // There may be no workspace screens (just hotseat items and an empty page). 2548b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal currScreen = PagedView.INVALID_RESTORE_PAGE; 2549b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal } 2550b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal currentScreen = currScreen; 25519b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung } 2552b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal final boolean validFirstPage = currentScreen >= 0; 2553b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal final long currentScreenId = 2554b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal validFirstPage ? orderedScreenIds.get(currentScreen) : INVALID_SCREEN_ID; 25559b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung 25569b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung // Separate the items that are on the current screen, and all the other remaining items 255744c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>(); 255844c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>(); 255944c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>(); 256044c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>(); 2561b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 25629b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung filterCurrentWorkspaceItems(currentScreenId, workspaceItems, currentWorkspaceItems, 2563b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherWorkspaceItems); 25649b9fb967b2305413520dc676d6d3c472b2b6b25eWinson Chung filterCurrentAppWidgets(currentScreenId, appWidgets, currentAppWidgets, 2565b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung otherAppWidgets); 2566b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sortWorkspaceItemsSpatially(currentWorkspaceItems); 2567b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung sortWorkspaceItemsSpatially(otherWorkspaceItems); 2568b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2569b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Tell the workspace that we're about to start binding items 2570b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r = new Runnable() { 25713611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 25723611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Callbacks callbacks = tryGetCallbacks(oldCallbacks); 25733611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != null) { 2574527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal callbacks.clearPendingBinds(); 2575b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung callbacks.startBinding(); 25769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 25779c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2578b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2579d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 2580b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2581dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen bindWorkspaceScreens(oldCallbacks, orderedScreenIds); 2582dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen 2583527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal Executor mainExecutor = new DeferredMainThreadExecutor(); 2584527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal // Load items on the current page. 258544c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, currentAppWidgets, mainExecutor); 2586b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2587b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal // In case of validFirstPage, only bind the first screen, and defer binding the 2588b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal // remaining screens after first onDraw (and an optional the fade animation whichever 2589b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal // happens later). 2590b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal // This ensures that the first screen is immediately visible (eg. during rotation) 2591b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal // In case of !validFirstPage, bind all pages one after other. 2592b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal final Executor deferredExecutor = 2593b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal validFirstPage ? new ViewOnDrawExecutor(mHandler) : mainExecutor; 2594b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal 2595b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal mainExecutor.execute(new Runnable() { 2596b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal @Override 2597b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal public void run() { 2598b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2599b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal if (callbacks != null) { 2600b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal callbacks.finishFirstPageBind( 2601b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null); 2602b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal } 2603b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal } 2604b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal }); 2605527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 260644c06437e2e0476e24b61891d1a4aca9828f5327Sunny Goyal bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, deferredExecutor); 2607b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2608b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung // Tell the workspace that we're done binding items 2609b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung r = new Runnable() { 26103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 2611b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2612b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung if (callbacks != null) { 261366cfdc2549b973496f2d5555defc22b7a15b5620Sunny Goyal callbacks.finishBindingItems(); 2614b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung } 2615b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung 2616639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal mIsLoadingAndBindingWorkspace = false; 2617639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal 2618639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal // Run all the bind complete runnables after workspace is bound. 2619639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal if (!mBindCompleteRunnables.isEmpty()) { 2620639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal synchronized (mBindCompleteRunnables) { 2621639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal for (final Runnable r : mBindCompleteRunnables) { 2622639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal runOnWorkerThread(r); 2623639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2624639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal mBindCompleteRunnables.clear(); 2625639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2626639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2627639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal 262898e030be2abc03e90e9fd9f8bf67e2e01db39cc0Winson Chung // If we're profiling, ensure this is the last thing in the queue. 26293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 26303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound workspace in " 26313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato + (SystemClock.uptimeMillis()-t) + "ms"); 26329c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 263336a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 26349c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 2635b8b2a5aa45d82ce81301250707bc373e1da4aa14Winson Chung }; 2636527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal deferredExecutor.execute(r); 2637527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 2638b5b9ad68b707154fcc2c3b04b1b6c0b17127e415Sunny Goyal if (validFirstPage) { 2639527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal r = new Runnable() { 2640527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void run() { 2641527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal Callbacks callbacks = tryGetCallbacks(oldCallbacks); 2642527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal if (callbacks != null) { 2643527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal // We are loading synchronously, which means, some of the pages will be 2644527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal // bound after first draw. Inform the callbacks that page binding is 2645527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal // not complete, and schedule the remaining pages. 2646527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal if (currentScreen != PagedView.INVALID_RESTORE_PAGE) { 2647527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal callbacks.onPageBoundSynchronously(currentScreen); 2648527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 2649527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal callbacks.executeOnNextDraw((ViewOnDrawExecutor) deferredExecutor); 2650527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 2651527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 2652527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal }; 2653d33860f2cc027b91dd09cc38ddd0e37878ba6c69Sunny Goyal runOnMainThread(r); 26544a2afa36553079e9f75fe7c8fcce863e84578e14Winson Chung } 26553611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 26563611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 26573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void loadAndBindAllApps() { 26583611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 26593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "loadAndBindAllApps mAllAppsLoaded=" + mAllAppsLoaded); 26603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 26613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (!mAllAppsLoaded) { 266264359a53dc827797917a8d9a0697a91996789801Winson Chung loadAllApps(); 2663f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal synchronized (LoaderTask.this) { 2664f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal if (mStopped) { 2665f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal return; 2666f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal } 2667f5cd998c25b025e46c56f4e862f4f5573a807745Sunny Goyal } 26684e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal updateIconCache(); 266993f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee synchronized (LoaderTask.this) { 267093f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee if (mStopped) { 267193f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee return; 267293f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee } 267393f824ac2f2f3ec92a775cad58dcf59e4302fe64Reena Lee mAllAppsLoaded = true; 26743611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 26753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 26763611578579b4bfb25616085dafdb1a45207394f9Joe Onorato onlyBindAllApps(); 26773611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 26783611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 26793611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 26804e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal private void updateIconCache() { 26814e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal // Ignore packages which have a promise icon. 26824e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal HashSet<String> packagesToIgnore = new HashSet<>(); 26834e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal synchronized (sBgLock) { 26844e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal for (ItemInfo info : sBgItemsIdMap) { 26854e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (info instanceof ShortcutInfo) { 26864e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal ShortcutInfo si = (ShortcutInfo) info; 26874e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (si.isPromise() && si.getTargetComponent() != null) { 26884e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal packagesToIgnore.add(si.getTargetComponent().getPackageName()); 26894e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 26904e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } else if (info instanceof LauncherAppWidgetInfo) { 26914e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal LauncherAppWidgetInfo lawi = (LauncherAppWidgetInfo) info; 26924e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (lawi.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) { 26934e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal packagesToIgnore.add(lawi.providerName.getPackageName()); 26944e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 26954e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 26964e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 26974e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 26984e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal mIconCache.updateDbIcons(packagesToIgnore); 26994e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 27004e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal 27013611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private void onlyBindAllApps() { 27023611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 27033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (oldCallbacks == null) { 27043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 27053611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.w(TAG, "LoaderTask running with no launcher (onlyBindAllApps)"); 27063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 27073611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27083611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 27093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // shallow copy 2710c208ff9c5ded4953ded6a3358097c9f7280df825Winson Chung @SuppressWarnings("unchecked") 2711eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> list 2712eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka = (ArrayList<AppInfo>) mBgAllAppsList.data.clone(); 2713c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung Runnable r = new Runnable() { 27143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 27153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final long t = SystemClock.uptimeMillis(); 27163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks callbacks = tryGetCallbacks(oldCallbacks); 27173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (callbacks != null) { 27183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAllApplications(list); 27199c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 27203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 27213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "bound all " + list.size() + " apps from cache in " 2722747a5bc486a7c8335fc4a481cab1567369570c24Hyunyoung Song + (SystemClock.uptimeMillis() - t) + "ms"); 27239c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 27243611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2725c93e5ae12018bb214099ff88a48cc21580aec4c3Winson Chung }; 272680f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham runOnMainThread(r); 27273611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 27283611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 272964359a53dc827797917a8d9a0697a91996789801Winson Chung private void loadAllApps() { 273064359a53dc827797917a8d9a0697a91996789801Winson Chung final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 27313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 27323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final Callbacks oldCallbacks = mCallbacks.get(); 27333611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (oldCallbacks == null) { 27343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato // This launcher has exited and nobody bothered to tell us. Just bail. 273564359a53dc827797917a8d9a0697a91996789801Winson Chung Log.w(TAG, "LoaderTask running with no launcher (loadAllApps)"); 27363611578579b4bfb25616085dafdb1a45207394f9Joe Onorato return; 27379c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 273831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2739ed13187a745866483139e2878037e1f8427ce567Kenny Guy final List<UserHandleCompat> profiles = mUserManager.getUserProfiles(); 2740ed13187a745866483139e2878037e1f8427ce567Kenny Guy 274164359a53dc827797917a8d9a0697a91996789801Winson Chung // Clear the list of apps 274264359a53dc827797917a8d9a0697a91996789801Winson Chung mBgAllAppsList.clear(); 2743ed13187a745866483139e2878037e1f8427ce567Kenny Guy for (UserHandleCompat user : profiles) { 2744ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Query for the set of apps 2745ed13187a745866483139e2878037e1f8427ce567Kenny Guy final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0; 2746756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal final List<LauncherActivityInfoCompat> apps = mLauncherApps.getActivityList(null, user); 2747ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (DEBUG_LOADERS) { 2748ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "getActivityList took " 2749ed13187a745866483139e2878037e1f8427ce567Kenny Guy + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user); 2750ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user); 2751ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2752ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Fail if we don't have any apps 2753e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // TODO: Fix this. Only fail for the current user. 2754ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (apps == null || apps.isEmpty()) { 2755ed13187a745866483139e2878037e1f8427ce567Kenny Guy return; 2756ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2757ff05f4375dd47242d7e4864287e0d5af8ac8ba8fKenny Guy boolean quietMode = mUserManager.isQuietModeEnabled(user); 2758ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Create the ApplicationInfos 2759ed13187a745866483139e2878037e1f8427ce567Kenny Guy for (int i = 0; i < apps.size(); i++) { 2760ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherActivityInfoCompat app = apps.get(i); 2761ed13187a745866483139e2878037e1f8427ce567Kenny Guy // This builds the icon bitmaps. 2762ff05f4375dd47242d7e4864287e0d5af8ac8ba8fKenny Guy mBgAllAppsList.add(new AppInfo(mContext, app, user, mIconCache, quietMode)); 2763ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 2764e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 2765756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal final ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(mContext, user); 2766756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal if (heuristic != null) { 2767639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal final Runnable r = new Runnable() { 2768756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal 2769756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal @Override 2770756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal public void run() { 2771756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal heuristic.processUserApps(apps); 2772756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal } 2773639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal }; 2774639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal runOnMainThread(new Runnable() { 2775639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal 2776639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal @Override 2777639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal public void run() { 2778639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal // Check isLoadingWorkspace on the UI thread, as it is updated on 2779639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal // the UI thread. 2780639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal if (mIsLoadingAndBindingWorkspace) { 2781639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal synchronized (mBindCompleteRunnables) { 2782639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal mBindCompleteRunnables.add(r); 2783639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2784639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } else { 2785639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal runOnWorkerThread(r); 2786639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2787639e906a0fc205b48512951feec0cbb47513e246Sunny Goyal } 2788756a28aeece3b00f40415f1fccae6f7d57104bfbSunny Goyal }); 2789e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 279064359a53dc827797917a8d9a0697a91996789801Winson Chung } 279185f418d0f5607c66efef1673075a6d3486e5af83Bjorn Bringert // Huh? Shouldn't this be inside the Runnable below? 2792eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> added = mBgAllAppsList.added; 2793eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka mBgAllAppsList.added = new ArrayList<AppInfo>(); 27943611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 279564359a53dc827797917a8d9a0697a91996789801Winson Chung // Post callback on main thread 279664359a53dc827797917a8d9a0697a91996789801Winson Chung mHandler.post(new Runnable() { 279764359a53dc827797917a8d9a0697a91996789801Winson Chung public void run() { 27989892e5874061233dec57107d1d3d7d5d8e1f5d93Hyunyoung Song 279964359a53dc827797917a8d9a0697a91996789801Winson Chung final long bindTime = SystemClock.uptimeMillis(); 280011a1a53651924b544513f1f6971a735b18d67539Winson Chung final Callbacks callbacks = tryGetCallbacks(oldCallbacks); 280164359a53dc827797917a8d9a0697a91996789801Winson Chung if (callbacks != null) { 280264359a53dc827797917a8d9a0697a91996789801Winson Chung callbacks.bindAllApplications(added); 28033611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 280464359a53dc827797917a8d9a0697a91996789801Winson Chung Log.d(TAG, "bound " + added.size() + " apps in " 28052e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal + (SystemClock.uptimeMillis() - bindTime) + "ms"); 28063611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 280764359a53dc827797917a8d9a0697a91996789801Winson Chung } else { 280864359a53dc827797917a8d9a0697a91996789801Winson Chung Log.i(TAG, "not binding apps: no Launcher activity"); 280964359a53dc827797917a8d9a0697a91996789801Winson Chung } 28103611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 281164359a53dc827797917a8d9a0697a91996789801Winson Chung }); 281218bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal // Cleanup any data stored for a deleted user. 281318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal ManagedProfileHeuristic.processAllUsers(profiles, mContext); 28143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) { 281564359a53dc827797917a8d9a0697a91996789801Winson Chung Log.d(TAG, "Icons processed in " 281664359a53dc827797917a8d9a0697a91996789801Winson Chung + (SystemClock.uptimeMillis() - loadTime) + "ms"); 28173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 28183611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2819dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 2820bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private void loadAndBindDeepShortcuts() { 2821bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (DEBUG_LOADERS) { 2822bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham Log.d(TAG, "loadAndBindDeepShortcuts mDeepShortcutsLoaded=" + mDeepShortcutsLoaded); 2823bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2824bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (!mDeepShortcutsLoaded) { 2825bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mBgDeepShortcutMap.clear(); 282695f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal mHasShortcutHostPermission = mDeepShortcutManager.hasHostPermission(); 282795f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal if (mHasShortcutHostPermission) { 282895f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal for (UserHandleCompat user : mUserManager.getUserProfiles()) { 282995f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal if (mUserManager.isUserUnlocked(user)) { 283095f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal List<ShortcutInfoCompat> shortcuts = mDeepShortcutManager 283195f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal .queryForAllShortcuts(user); 283295f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal updateDeepShortcutMap(null, user, shortcuts); 283395f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal } 2834d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 2835bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2836bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham synchronized (LoaderTask.this) { 2837bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (mStopped) { 2838bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham return; 2839bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2840bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mDeepShortcutsLoaded = true; 2841bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2842bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 284380f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham bindDeepShortcuts(); 2844bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2845bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 284675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void dumpState() { 284775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal synchronized (sBgLock) { 284875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Log.d(TAG, "mLoaderTask.mContext=" + mContext); 284975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Log.d(TAG, "mLoaderTask.mStopped=" + mStopped); 285075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Log.d(TAG, "mLoaderTask.mLoadAndBindStepFinished=" + mLoadAndBindStepFinished); 285175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Log.d(TAG, "mItems size=" + sBgWorkspaceItems.size()); 285275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 285375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 285475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 285577919b93b98f5afa1b39546861197d6065847224Sunny Goyal 2856860538df1d72b3840811b7a39940a224f3326066Sunny Goyal /** 2857860538df1d72b3840811b7a39940a224f3326066Sunny Goyal * Clear all the shortcuts for the given package, and re-add the new shortcuts. 2858860538df1d72b3840811b7a39940a224f3326066Sunny Goyal */ 2859860538df1d72b3840811b7a39940a224f3326066Sunny Goyal private void updateDeepShortcutMap( 2860860538df1d72b3840811b7a39940a224f3326066Sunny Goyal String packageName, UserHandleCompat user, List<ShortcutInfoCompat> shortcuts) { 2861bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (packageName != null) { 2862bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham Iterator<ComponentKey> keysIter = mBgDeepShortcutMap.keySet().iterator(); 2863bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham while (keysIter.hasNext()) { 2864860538df1d72b3840811b7a39940a224f3326066Sunny Goyal ComponentKey next = keysIter.next(); 2865860538df1d72b3840811b7a39940a224f3326066Sunny Goyal if (next.componentName.getPackageName().equals(packageName) 2866860538df1d72b3840811b7a39940a224f3326066Sunny Goyal && next.user.equals(user)) { 2867bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham keysIter.remove(); 2868bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2869bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2870bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2871bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 2872bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // Now add the new shortcuts to the map. 2873bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham for (ShortcutInfoCompat shortcut : shortcuts) { 2874ca258b36be07f4835c9cc5fbc3e84e9851647dceTony Wickham boolean shouldShowInContainer = shortcut.isEnabled() 2875ca258b36be07f4835c9cc5fbc3e84e9851647dceTony Wickham && (shortcut.isDeclaredInManifest() || shortcut.isDynamic()); 2876ca258b36be07f4835c9cc5fbc3e84e9851647dceTony Wickham if (shouldShowInContainer) { 287770a7c9b70003ae87e2b2968bc6ceded0fe0f0e8bSunny Goyal ComponentKey targetComponent 287870a7c9b70003ae87e2b2968bc6ceded0fe0f0e8bSunny Goyal = new ComponentKey(shortcut.getActivity(), shortcut.getUserHandle()); 287970a7c9b70003ae87e2b2968bc6ceded0fe0f0e8bSunny Goyal mBgDeepShortcutMap.addToList(targetComponent, shortcut.getId()); 288070a7c9b70003ae87e2b2968bc6ceded0fe0f0e8bSunny Goyal } 2881bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2882bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2883bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 288480f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham public void bindDeepShortcuts() { 28855f06401807ef408a4b56a127bef1f0b55b0adcf6Sunny Goyal final MultiHashMap<ComponentKey, String> shortcutMapCopy = mBgDeepShortcutMap.clone(); 288680f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham Runnable r = new Runnable() { 2887bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham @Override 2888bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham public void run() { 2889bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham Callbacks callbacks = getCallback(); 2890bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (callbacks != null) { 2891bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham callbacks.bindDeepShortcutMap(shortcutMapCopy); 2892bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2893bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 289480f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham }; 289580f5787b1c12be2a5ce3d11e01ff9435bae71bdfTony Wickham runOnMainThread(r); 2896bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 2897bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 289875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal /** 289995f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal * Refreshes the cached shortcuts if the shortcut permission has changed. 290095f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal * Current implementation simply reloads the workspace, but it can be optimized to 290195f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal * use partial updates similar to {@link UserManagerCompat} 290295f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal */ 290395f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal public void refreshShortcutsIfRequired() { 290495f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal if (Utilities.isNycMR1OrAbove()) { 290595f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal sWorker.removeCallbacks(mShortcutPermissionCheckRunnable); 290695f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal sWorker.post(mShortcutPermissionCheckRunnable); 290795f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal } 290895f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal } 290995f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal 291095f3d6ba2ca02a9841487777cfff43fb9df65ec7Sunny Goyal /** 291175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal * Called when the icons for packages have been updated in the icon cache. 291275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal */ 291375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void onPackageIconsUpdated(HashSet<String> updatedPackages, UserHandleCompat user) { 291475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal final Callbacks callbacks = getCallback(); 291575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal final ArrayList<AppInfo> updatedApps = new ArrayList<>(); 291675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal final ArrayList<ShortcutInfo> updatedShortcuts = new ArrayList<>(); 291777919b93b98f5afa1b39546861197d6065847224Sunny Goyal 291875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // If any package icon has changed (app was updated while launcher was dead), 291975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal // update the corresponding shortcuts. 292075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal synchronized (sBgLock) { 292175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal for (ItemInfo info : sBgItemsIdMap) { 292275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (info instanceof ShortcutInfo && user.equals(info.user) 292375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 292475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal ShortcutInfo si = (ShortcutInfo) info; 292575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal ComponentName cn = si.getTargetComponent(); 292675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (cn != null && updatedPackages.contains(cn.getPackageName())) { 292775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal si.updateIcon(mIconCache); 292875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal updatedShortcuts.add(si); 292977919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 293077919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 293177919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 293275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mBgAllAppsList.updateIconsAndLabels(updatedPackages, user, updatedApps); 293375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 293477919b93b98f5afa1b39546861197d6065847224Sunny Goyal 2935bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham bindUpdatedShortcuts(updatedShortcuts, user); 2936bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 2937bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (!updatedApps.isEmpty()) { 293875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mHandler.post(new Runnable() { 293975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 294075b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void run() { 294175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Callbacks cb = getCallback(); 294275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (cb != null && callbacks == cb) { 2943bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham cb.bindAppsUpdated(updatedApps); 294477919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 294575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 294675b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal }); 294777919b93b98f5afa1b39546861197d6065847224Sunny Goyal } 2948bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 294977919b93b98f5afa1b39546861197d6065847224Sunny Goyal 2950d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal private void bindUpdatedShortcuts( 2951d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal ArrayList<ShortcutInfo> updatedShortcuts, UserHandleCompat user) { 2952d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal bindUpdatedShortcuts(updatedShortcuts, new ArrayList<ShortcutInfo>(), user); 2953d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 2954d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 2955d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal private void bindUpdatedShortcuts( 2956d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal final ArrayList<ShortcutInfo> updatedShortcuts, 2957d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal final ArrayList<ShortcutInfo> removedShortcuts, 2958d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal final UserHandleCompat user) { 2959d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (!updatedShortcuts.isEmpty() || !removedShortcuts.isEmpty()) { 2960bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham final Callbacks callbacks = getCallback(); 296175b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal mHandler.post(new Runnable() { 296275b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal 296375b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal public void run() { 296475b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal Callbacks cb = getCallback(); 296575b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal if (cb != null && callbacks == cb) { 2966d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal cb.bindShortcutsChanged(updatedShortcuts, removedShortcuts, user); 296775b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 296875b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal } 296975b0f552ae653a4afc64c5fb6782a481fdb89b4dSunny Goyal }); 29703611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 29713611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 297231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2973bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham void enqueueItemUpdatedTask(Runnable task) { 2974700889f504ef134ab307d95b6bfbbb426ea730e3Brad Fitzpatrick sWorker.post(task); 29753611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 2976d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 2977091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk class AppsAvailabilityCheck extends BroadcastReceiver { 2978f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 2979f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal @Override 2980f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal public void onReceive(Context context, Intent intent) { 2981f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal synchronized (sBgLock) { 2982f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal final LauncherAppsCompat launcherApps = LauncherAppsCompat 2983f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal .getInstance(mApp.getContext()); 29841a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final PackageManager manager = context.getPackageManager(); 29851a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final ArrayList<String> packagesRemoved = new ArrayList<String>(); 29861a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal final ArrayList<String> packagesUnavailable = new ArrayList<String>(); 2987f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal for (Entry<UserHandleCompat, HashSet<String>> entry : sPendingPackages.entrySet()) { 2988f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal UserHandleCompat user = entry.getKey(); 29891a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesRemoved.clear(); 29901a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.clear(); 2991f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal for (String pkg : entry.getValue()) { 2992f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!launcherApps.isPackageEnabledForProfile(pkg, user)) { 2993d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal if (PackageManagerHelper.isAppOnSdcard(manager, pkg)) { 29941a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.add(pkg); 29951a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } else { 29961a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesRemoved.add(pkg); 29971a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 2998f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 2999f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 3000f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if (!packagesRemoved.isEmpty()) { 3001bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask(new PackageUpdatedTask(PackageUpdatedTask.OP_REMOVE, 3002f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal packagesRemoved.toArray(new String[packagesRemoved.size()]), user)); 3003f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 30041a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal if (!packagesUnavailable.isEmpty()) { 3005bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham enqueueItemUpdatedTask(new PackageUpdatedTask(PackageUpdatedTask.OP_UNAVAILABLE, 30061a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal packagesUnavailable.toArray(new String[packagesUnavailable.size()]), user)); 30071a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 3008f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 3009349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal sPendingPackages.clear(); 3010f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 3011f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 3012f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal } 3013f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal 30143611578579b4bfb25616085dafdb1a45207394f9Joe Onorato private class PackageUpdatedTask implements Runnable { 30153611578579b4bfb25616085dafdb1a45207394f9Joe Onorato int mOp; 30163611578579b4bfb25616085dafdb1a45207394f9Joe Onorato String[] mPackages; 3017ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat mUser; 3018d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 30193611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_NONE = 0; 30203611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_ADD = 1; 30213611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_UPDATE = 2; 30223611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_REMOVE = 3; // uninstlled 30233611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public static final int OP_UNAVAILABLE = 4; // external media unmounted 302444cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy public static final int OP_SUSPEND = 5; // package suspended 302544cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy public static final int OP_UNSUSPEND = 6; // package unsuspended 3026da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal public static final int OP_USER_AVAILABILITY_CHANGE = 7; // user available/unavailable 3027d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 3028ed13187a745866483139e2878037e1f8427ce567Kenny Guy public PackageUpdatedTask(int op, String[] packages, UserHandleCompat user) { 30293611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mOp = op; 30303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mPackages = packages; 3031ed13187a745866483139e2878037e1f8427ce567Kenny Guy mUser = user; 30323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3033d65d08e709ec0916446100bae0a7276d0800382fJoe Onorato 30343611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 3035c905efc89cd8a391ae73f36d356c907b4aaf1bf0Sunny Goyal if (!mHasLoaderCompletedOnce) { 3036c905efc89cd8a391ae73f36d356c907b4aaf1bf0Sunny Goyal // Loader has not yet run. 3037c905efc89cd8a391ae73f36d356c907b4aaf1bf0Sunny Goyal return; 3038c905efc89cd8a391ae73f36d356c907b4aaf1bf0Sunny Goyal } 3039cc8befac3550c81d04ea206c170adae36c9a6c93Daniel Sandler final Context context = mApp.getContext(); 3040dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 30413611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final String[] packages = mPackages; 30423611578579b4bfb25616085dafdb1a45207394f9Joe Onorato final int N = packages.length; 30433bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal FlagOp flagOp = FlagOp.NO_OP; 3044da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal StringFilter pkgFilter = StringFilter.of(new HashSet<>(Arrays.asList(packages))); 30453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato switch (mOp) { 304618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal case OP_ADD: { 30473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30483611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.addPackage " + packages[i]); 30494fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mIconCache.updateIconsForPkg(packages[i], mUser); 3050ed13187a745866483139e2878037e1f8427ce567Kenny Guy mBgAllAppsList.addPackage(context, packages[i], mUser); 3051dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler } 3052e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 305318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(context, mUser); 305418bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal if (heuristic != null) { 305518bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal heuristic.processPackageAdd(mPackages); 3056e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 30573611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 305818bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal } 30593611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_UPDATE: 30603611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30613611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.updatePackage " + packages[i]); 30624fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mIconCache.updateIconsForPkg(packages[i], mUser); 3063ed13187a745866483139e2878037e1f8427ce567Kenny Guy mBgAllAppsList.updatePackage(context, packages[i], mUser); 30645b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal mApp.getWidgetCache().removePackage(packages[i], mUser); 30653611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 30663bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal // Since package was just updated, the target must be available now. 30673bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal flagOp = FlagOp.removeFlag(ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE); 30683611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 306918bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal case OP_REMOVE: { 307018bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(context, mUser); 307118bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal if (heuristic != null) { 307218bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal heuristic.processPackageRemoved(mPackages); 3073e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 30744fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal for (int i=0; i<N; i++) { 30754fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]); 30764fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mIconCache.removeIconsForPkg(packages[i], mUser); 30774fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal } 3078e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal // Fall through 307918bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal } 30803611578579b4bfb25616085dafdb1a45207394f9Joe Onorato case OP_UNAVAILABLE: 30813611578579b4bfb25616085dafdb1a45207394f9Joe Onorato for (int i=0; i<N; i++) { 30823611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]); 30834fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal mBgAllAppsList.removePackage(packages[i], mUser); 30845b0e669169ea2c951bf2f6f71faf793b24db3c23Sunny Goyal mApp.getWidgetCache().removePackage(packages[i], mUser); 30853611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 30863bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal flagOp = FlagOp.addFlag(ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE); 30873611578579b4bfb25616085dafdb1a45207394f9Joe Onorato break; 308844cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy case OP_SUSPEND: 308944cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy case OP_UNSUSPEND: 30903bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal flagOp = mOp == OP_SUSPEND ? 30913bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal FlagOp.addFlag(ShortcutInfo.FLAG_DISABLED_SUSPENDED) : 30923bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal FlagOp.removeFlag(ShortcutInfo.FLAG_DISABLED_SUSPENDED); 309317763cb1d2060fb95873a8920196720c862f0e14Sunny Goyal if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.(un)suspend " + N); 3094da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal mBgAllAppsList.updatePackageFlags(pkgFilter, mUser, flagOp); 3095da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal break; 3096da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal case OP_USER_AVAILABILITY_CHANGE: 3097da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal flagOp = UserManagerCompat.getInstance(context).isQuietModeEnabled(mUser) 3098da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal ? FlagOp.addFlag(ShortcutInfo.FLAG_DISABLED_QUIET_USER) 3099da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal : FlagOp.removeFlag(ShortcutInfo.FLAG_DISABLED_QUIET_USER); 3100da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal // We want to update all packages for this user. 3101da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal pkgFilter = StringFilter.matchesAll(); 3102da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal mBgAllAppsList.updatePackageFlags(pkgFilter, mUser, flagOp); 310344cba696386b44f9115cad13ec9ecf67a0ac9119Kenny Guy break; 31043611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3105dca661236c73ecd819cfea964c6f8170e5cc40aeDaniel Sandler 3106eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka ArrayList<AppInfo> added = null; 3107eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka ArrayList<AppInfo> modified = null; 3108eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> removedApps = new ArrayList<AppInfo>(); 31093611578579b4bfb25616085dafdb1a45207394f9Joe Onorato 3110487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mBgAllAppsList.added.size() > 0) { 31113bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal added = new ArrayList<>(mBgAllAppsList.added); 31125d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.added.clear(); 31133611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3114487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mBgAllAppsList.modified.size() > 0) { 31153bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal modified = new ArrayList<>(mBgAllAppsList.modified); 31165d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.modified.clear(); 31173611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 31185d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung if (mBgAllAppsList.removed.size() > 0) { 311983892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung removedApps.addAll(mBgAllAppsList.removed); 31205d55f33a1d7a16a11fb759d8f37eeef45e132b98Winson Chung mBgAllAppsList.removed.clear(); 3121cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung } 3122cd81073eac537e9f85eeee14588d513ea8a56e17Winson Chung 31233bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal final HashMap<ComponentName, AppInfo> addedOrUpdatedApps = new HashMap<>(); 31244390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (added != null) { 3126c9acdd51c40c1b397adae6ba62c4acd01914b473Sunny Goyal addAppsToAllApps(context, added); 31274390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal for (AppInfo ai : added) { 31284390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal addedOrUpdatedApps.put(ai.componentName, ai); 31294390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 313176a47a1b2273c4d7dfab0beeadc1a8387e6a2840Adam Cohen 31323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (modified != null) { 31333bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal final Callbacks callbacks = getCallback(); 3134eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka final ArrayList<AppInfo> modifiedFinal = modified; 31354390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal for (AppInfo ai : modified) { 31364390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal addedOrUpdatedApps.put(ai.componentName, ai); 313764359a53dc827797917a8d9a0697a91996789801Winson Chung } 313864359a53dc827797917a8d9a0697a91996789801Winson Chung 31393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 31403611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 3141e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3142cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 31433611578579b4bfb25616085dafdb1a45207394f9Joe Onorato callbacks.bindAppsUpdated(modifiedFinal); 31443611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 31453611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 31463611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 31473611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3148780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung 31494390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Update shortcut infos 31503bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal if (mOp == OP_ADD || flagOp != FlagOp.NO_OP) { 31514390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<ShortcutInfo> updatedShortcuts = new ArrayList<ShortcutInfo>(); 31524390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<ShortcutInfo> removedShortcuts = new ArrayList<ShortcutInfo>(); 31534390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal final ArrayList<LauncherAppWidgetInfo> widgets = new ArrayList<LauncherAppWidgetInfo>(); 31544390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 3155b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal synchronized (sBgLock) { 3156e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal for (ItemInfo info : sBgItemsIdMap) { 3157b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (info instanceof ShortcutInfo && mUser.equals(info.user)) { 3158b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal ShortcutInfo si = (ShortcutInfo) info; 31594390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal boolean infoUpdated = false; 31604390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal boolean shortcutUpdated = false; 31614390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31624390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Update shortcuts which use iconResource. 3163b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if ((si.iconResource != null) 3164da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal && pkgFilter.matches(si.iconResource.packageName)) { 316553d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal Bitmap icon = Utilities.createIconBitmap( 316653d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal si.iconResource.packageName, 316753d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal si.iconResource.resourceName, context); 3168b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (icon != null) { 3169b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal si.setIcon(icon); 3170b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal si.usingFallbackIcon = false; 31714390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 3172b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3173b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 31744390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31754390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ComponentName cn = si.getTargetComponent(); 3176da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal if (cn != null && pkgFilter.matches(cn.getPackageName())) { 31774390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal AppInfo appInfo = addedOrUpdatedApps.get(cn); 31784390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31794390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (si.isPromise()) { 31804390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) { 31814390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Auto install icon 31824390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal PackageManager pm = context.getPackageManager(); 31834390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal ResolveInfo matched = pm.resolveActivity( 31844390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal new Intent(Intent.ACTION_MAIN) 31854390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER), 31864390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal PackageManager.MATCH_DEFAULT_ONLY); 31874390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (matched == null) { 31884390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Try to find the best match activity. 31894390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal Intent intent = pm.getLaunchIntentForPackage( 31904390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal cn.getPackageName()); 31914390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (intent != null) { 31924390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal cn = intent.getComponent(); 31934390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal appInfo = addedOrUpdatedApps.get(cn); 31944390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 31954390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 31964390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if ((intent == null) || (appInfo == null)) { 31974390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal removedShortcuts.add(si); 31984390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal continue; 31994390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32004390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.promisedIntent = intent; 32014390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32024390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32034390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 32044390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal // Restore the shortcut. 3205fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal if (appInfo != null) { 3206fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal si.flags = appInfo.flags; 3207fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal } 32084390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 3209756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.intent = si.promisedIntent; 3210756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.promisedIntent = null; 3211756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal si.status = ShortcutInfo.DEFAULT; 32124390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 32134390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.updateIcon(mIconCache); 32144390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32154390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 32164390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction()) 32174390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { 32184390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.updateIcon(mIconCache); 321982b016cb56540fe26213e817dd0dd668099c8e20Winson Chung si.title = Utilities.trim(appInfo.title); 32204390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal si.contentDescription = appInfo.contentDescription; 32214390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal infoUpdated = true; 32224390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32234390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 32243bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal int oldDisabledFlags = si.isDisabled; 32253bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal si.isDisabled = flagOp.apply(si.isDisabled); 32263bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal if (si.isDisabled != oldDisabledFlags) { 32274390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal shortcutUpdated = true; 32284390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32294390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32304390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal 32314390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (infoUpdated || shortcutUpdated) { 32324390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updatedShortcuts.add(si); 32334390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 32344390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (infoUpdated) { 32354390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updateItemInDatabase(context, si); 32364390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 3237da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal } else if (info instanceof LauncherAppWidgetInfo && mOp == OP_ADD) { 32384390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info; 32394390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (mUser.equals(widgetInfo.user) 32404390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal && widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) 3241da891c1a22210e7e75f85796dea528bf8bf12b45Sunny Goyal && pkgFilter.matches(widgetInfo.providerName.getPackageName())) { 324253f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal widgetInfo.restoreStatus &= 324353f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY & 324453f9672b30b8a36bfae9f6492f732ccfb87723a4Sunny Goyal ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED; 324584b4adc3fb2301466468828ccbd742209619e597Sunny Goyal 324684b4adc3fb2301466468828ccbd742209619e597Sunny Goyal // adding this flag ensures that launcher shows 'click to setup' 324784b4adc3fb2301466468828ccbd742209619e597Sunny Goyal // if the widget has a config activity. In case there is no config 324884b4adc3fb2301466468828ccbd742209619e597Sunny Goyal // activity, it will be marked as 'restored' during bind. 324984b4adc3fb2301466468828ccbd742209619e597Sunny Goyal widgetInfo.restoreStatus |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY; 325084b4adc3fb2301466468828ccbd742209619e597Sunny Goyal 32514390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal widgets.add(widgetInfo); 32524390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal updateItemInDatabase(context, widgetInfo); 32534390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 3254b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3255b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3256b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3257b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal 3258d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal bindUpdatedShortcuts(updatedShortcuts, removedShortcuts, mUser); 3259d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (!removedShortcuts.isEmpty()) { 3260d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal deleteItemsFromDatabase(context, removedShortcuts); 32614390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal } 3262d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 32634390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (!widgets.isEmpty()) { 32643bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal final Callbacks callbacks = getCallback(); 32654390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal mHandler.post(new Runnable() { 32664390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void run() { 3267e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 32684390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (callbacks == cb && cb != null) { 32694390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal callbacks.bindWidgetsRestored(widgets); 3270b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3271b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3272b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal }); 3273b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3274b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal } 3275b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal 32763bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal final HashSet<String> removedPackages = new HashSet<>(); 32773bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal final HashSet<ComponentName> removedComponents = new HashSet<>(); 32783bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal if (mOp == OP_REMOVE) { 3279df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Mark all packages in the broadcast to be removed 32803bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal Collections.addAll(removedPackages, packages); 32813bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal 32823bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal // No need to update the removedComponents as 32833bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal // removedPackages is a super-set of removedComponents 3284df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } else if (mOp == OP_UPDATE) { 3285df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Mark disabled packages in the broadcast to be removed 3286df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung for (int i=0; i<N; i++) { 3287ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (isPackageDisabled(context, packages[i], mUser)) { 32883bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal removedPackages.add(packages[i]); 328964359a53dc827797917a8d9a0697a91996789801Winson Chung } 329064359a53dc827797917a8d9a0697a91996789801Winson Chung } 32913bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal 32923bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal // Update removedComponents as some components can get removed during package update 32933bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal for (AppInfo info : removedApps) { 32943bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal removedComponents.add(info.componentName); 32953bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal } 3296df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } 32971a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 32983bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) { 32993bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal for (String pn : removedPackages) { 33003bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal deletePackageFromDatabase(context, pn, mUser); 33013bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal } 33023bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal for (ComponentName cn : removedComponents) { 33033bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal deleteItemsFromDatabase(context, getItemInfoForComponentName(cn, mUser)); 33041a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal } 33051a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal 3306df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Remove any queued items from the install queue 33073bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal InstallShortcutReceiver.removeFromInstallQueue(context, removedPackages, mUser); 33083bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal 3309df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung // Call the components-removed callback 33103bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal final Callbacks callbacks = getCallback(); 33113bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal mHandler.post(new Runnable() { 33123bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal public void run() { 33133bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal Callbacks cb = getCallback(); 33143bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal if (callbacks == cb && cb != null) { 33153bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal callbacks.bindWorkspaceComponentsRemoved( 33163bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal removedPackages, removedComponents, mUser); 33173bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal } 33183bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal } 33193bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal }); 33203bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal } 33213bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal 33223bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal if (!removedApps.isEmpty()) { 33233bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal // Remove corresponding apps from All-Apps 33243bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal final Callbacks callbacks = getCallback(); 33253611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mHandler.post(new Runnable() { 33263611578579b4bfb25616085dafdb1a45207394f9Joe Onorato public void run() { 3327e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal Callbacks cb = getCallback(); 3328cd2b01416febb5bf50ed5ede1544dea33fee3b0bWinson Chung if (callbacks == cb && cb != null) { 33293bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal callbacks.bindAppInfosRemoved(removedApps); 33303611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 33313611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 33323611578579b4bfb25616085dafdb1a45207394f9Joe Onorato }); 3333be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 3334227239e7c05d26c4098980b991d3472077c01ccbHyunyoung Song 33352e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal // Notify launcher of widget update. From marshmallow onwards we use AppWidgetHost to 33362e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal // get widget update signals. 33372e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal if (!Utilities.ATLEAST_MARSHMALLOW && 33382e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal (mOp == OP_ADD || mOp == OP_REMOVE || mOp == OP_UPDATE)) { 33393bbbabc54ac73a4451b0a862a3faac6426b1b7b4Sunny Goyal final Callbacks callbacks = getCallback(); 33402e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal mHandler.post(new Runnable() { 33412e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal public void run() { 33422e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal Callbacks cb = getCallback(); 33432e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal if (callbacks == cb && cb != null) { 33442e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal callbacks.notifyWidgetProvidersChanged(); 33453dc7beea3c7f9a60070e767aa43f5877a467d3edSunny Goyal } 33462d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal } 33472e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal }); 33482d648b057fa2d6410b1472c1b9dd5b65cd9c9414Sunny Goyal } 334931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 335031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 335131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 335210923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal /** 335310923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal * Repopulates the shortcut info, possibly updating any icon already on the workspace. 335410923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal */ 335510923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal public void updateShortcutInfo(final ShortcutInfoCompat fullDetail, final ShortcutInfo info) { 335610923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal enqueueItemUpdatedTask(new Runnable() { 335710923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal @Override 335810923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal public void run() { 335910923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal info.updateFromDeepShortcutInfo( 336010923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal fullDetail, LauncherAppState.getInstance().getContext()); 336110923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal ArrayList<ShortcutInfo> update = new ArrayList<ShortcutInfo>(); 336210923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal update.add(info); 336310923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal bindUpdatedShortcuts(update, fullDetail.getUserHandle()); 336410923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal } 336510923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal }); 336610923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal } 336710923b30a22b4ec8d10cf8536bddf3f176e6c26fSunny Goyal 3368bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham private class ShortcutsChangedTask implements Runnable { 336950941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal private final String mPackageName; 337050941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal private final List<ShortcutInfoCompat> mShortcuts; 337150941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal private final UserHandleCompat mUser; 337250941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal private final boolean mUpdateIdMap; 3373bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 3374bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham public ShortcutsChangedTask(String packageName, List<ShortcutInfoCompat> shortcuts, 337550941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal UserHandleCompat user, boolean updateIdMap) { 3376bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mPackageName = packageName; 3377bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mShortcuts = shortcuts; 3378bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mUser = user; 337950941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal mUpdateIdMap = updateIdMap; 3380bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 3381bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 3382bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham @Override 3383bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham public void run() { 3384bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham mDeepShortcutManager.onShortcutsChanged(mShortcuts); 3385bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 3386bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham // Find ShortcutInfo's that have changed on the workspace. 33877695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham final ArrayList<ShortcutInfo> removedShortcutInfos = new ArrayList<>(); 3388bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham MultiHashMap<String, ShortcutInfo> idsToWorkspaceShortcutInfos = new MultiHashMap<>(); 3389bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham for (ItemInfo itemInfo : sBgItemsIdMap) { 3390bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) { 3391bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham ShortcutInfo si = (ShortcutInfo) itemInfo; 3392fc02c1b446ee54561ac7351fb6ff0f8294785f0eTony Wickham if (si.getPromisedIntent().getPackage().equals(mPackageName) 3393fc02c1b446ee54561ac7351fb6ff0f8294785f0eTony Wickham && si.user.equals(mUser)) { 33947695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham idsToWorkspaceShortcutInfos.addToList(si.getDeepShortcutId(), si); 3395bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 3396bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 3397bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 3398bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 33997695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham final Context context = LauncherAppState.getInstance().getContext(); 34007695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham final ArrayList<ShortcutInfo> updatedShortcutInfos = new ArrayList<>(); 34017695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham if (!idsToWorkspaceShortcutInfos.isEmpty()) { 34027695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // Update the workspace to reflect the changes to updated shortcuts residing on it. 34037695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham List<ShortcutInfoCompat> shortcuts = mDeepShortcutManager.queryForFullDetails( 34047695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham mPackageName, new ArrayList<>(idsToWorkspaceShortcutInfos.keySet()), mUser); 34057695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham for (ShortcutInfoCompat fullDetails : shortcuts) { 34067695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham List<ShortcutInfo> shortcutInfos = idsToWorkspaceShortcutInfos 34077695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham .remove(fullDetails.getId()); 34087695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham if (!fullDetails.isPinned()) { 34097695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // The shortcut was previously pinned but is no longer, so remove it from 34107695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // the workspace and our pinned shortcut counts. 34117695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // Note that we put this check here, after querying for full details, 34127695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // because there's a possible race condition between pinning and 34137695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // receiving this callback. 34147695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham removedShortcutInfos.addAll(shortcutInfos); 34157695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham continue; 34167695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham } 34177695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham for (ShortcutInfo shortcutInfo : shortcutInfos) { 34187695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham shortcutInfo.updateFromDeepShortcutInfo(fullDetails, context); 34197695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham updatedShortcutInfos.add(shortcutInfo); 34207695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham } 3421bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 3422bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 34237695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham 34247695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // If there are still entries in idsToWorkspaceShortcutInfos, that means that 34257695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // the corresponding shortcuts weren't passed in onShortcutsChanged(). This 34267695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham // means they were cleared, so we remove and unpin them now. 34277695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham for (String id : idsToWorkspaceShortcutInfos.keySet()) { 34287695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham removedShortcutInfos.addAll(idsToWorkspaceShortcutInfos.get(id)); 34297695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham } 34307695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham 34317695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham bindUpdatedShortcuts(updatedShortcutInfos, removedShortcutInfos, mUser); 34327695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham if (!removedShortcutInfos.isEmpty()) { 34337695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham deleteItemsFromDatabase(context, removedShortcutInfos); 34347695e603bf1f4369115ba64c24e8b09c213b4e9cTony Wickham } 3435bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 343650941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal if (mUpdateIdMap) { 343750941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal // Update the deep shortcut map if the list of ids has changed for an activity. 343850941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal updateDeepShortcutMap(mPackageName, mUser, mShortcuts); 343950941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal bindDeepShortcuts(); 344050941fb8a6ba4e1b6fca6cbf35e1a5efca7156f3Sunny Goyal } 3441bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 3442bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham } 3443bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham 3444d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal /** 3445d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal * Task to handle changing of lock state of the user 3446d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal */ 3447d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal private class UserLockStateChangedTask implements Runnable { 3448d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 3449d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal private final UserHandleCompat mUser; 3450d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 3451d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal public UserLockStateChangedTask(UserHandleCompat user) { 3452d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal mUser = user; 3453d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3454d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 3455d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal @Override 3456d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal public void run() { 3457d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal boolean isUserUnlocked = mUserManager.isUserUnlocked(mUser); 3458d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Context context = mApp.getContext(); 3459d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 3460d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal HashMap<ShortcutKey, ShortcutInfoCompat> pinnedShortcuts = new HashMap<>(); 3461d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (isUserUnlocked) { 346249f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal List<ShortcutInfoCompat> shortcuts = 346349f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal mDeepShortcutManager.queryForPinnedShortcuts(null, mUser); 346449f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal if (mDeepShortcutManager.wasLastCallSuccess()) { 346549f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal for (ShortcutInfoCompat shortcut : shortcuts) { 346649f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal pinnedShortcuts.put(ShortcutKey.fromInfo(shortcut), shortcut); 346749f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal } 346849f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal } else { 346949f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal // Shortcut manager can fail due to some race condition when the lock state 347049f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal // changes too frequently. For the purpose of the update, 347149f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal // consider it as still locked. 347249f4f03dc8ed3925e80d379634e43eb24eea25b9Sunny Goyal isUserUnlocked = false; 3473d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3474d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3475d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 3476d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // Update the workspace to reflect the changes to updated shortcuts residing on it. 3477d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal ArrayList<ShortcutInfo> updatedShortcutInfos = new ArrayList<>(); 3478d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal ArrayList<ShortcutInfo> deletedShortcutInfos = new ArrayList<>(); 3479d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal for (ItemInfo itemInfo : sBgItemsIdMap) { 3480d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT 3481d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal && mUser.equals(itemInfo.user)) { 3482d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal ShortcutInfo si = (ShortcutInfo) itemInfo; 3483d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (isUserUnlocked) { 3484d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal ShortcutInfoCompat shortcut = 3485fc02c1b446ee54561ac7351fb6ff0f8294785f0eTony Wickham pinnedShortcuts.get(ShortcutKey.fromShortcutInfo(si)); 3486d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // We couldn't verify the shortcut during loader. If its no longer available 3487d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // (probably due to clear data), delete the workspace item as well 3488d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (shortcut == null) { 3489d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal deletedShortcutInfos.add(si); 3490d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal continue; 3491d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3492d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal si.isDisabled &= ~ShortcutInfo.FLAG_DISABLED_LOCKED_USER; 3493d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal si.updateFromDeepShortcutInfo(shortcut, context); 3494d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } else { 3495d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal si.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER; 3496d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3497d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal updatedShortcutInfos.add(si); 3498d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3499d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3500d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal bindUpdatedShortcuts(updatedShortcutInfos, deletedShortcutInfos, mUser); 3501d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (!deletedShortcutInfos.isEmpty()) { 3502d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal deleteItemsFromDatabase(context, deletedShortcutInfos); 3503d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3504d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 3505d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal // Remove shortcut id map for that user 3506d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Iterator<ComponentKey> keysIter = mBgDeepShortcutMap.keySet().iterator(); 3507d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal while (keysIter.hasNext()) { 3508d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (keysIter.next().user.equals(mUser)) { 3509d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal keysIter.remove(); 3510d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3511d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3512d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 3513d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal if (isUserUnlocked) { 3514d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal updateDeepShortcutMap(null, mUser, mDeepShortcutManager.queryForAllShortcuts(mUser)); 3515d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3516d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal bindDeepShortcuts(); 3517d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3518d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 3519d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal 35202e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal private void bindWidgetsModel(final Callbacks callbacks, final WidgetsModel model) { 35212e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal mHandler.post(new Runnable() { 35222e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal @Override 35232e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal public void run() { 35242e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal Callbacks cb = getCallback(); 35252e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal if (callbacks == cb && cb != null) { 35262e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal callbacks.bindWidgetsModel(model); 352726ace12135a662ad864678c9fede9817e5c02b67Robin Lee } 35285940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 35292e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal }); 35305940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen } 35315940042d39b576553c2499bcf3d0641281e6ad52Adam Cohen 35322e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal public void refreshAndBindWidgetsAndShortcuts( 35332e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal final Callbacks callbacks, final boolean bindFirst) { 3534eaf291b9feba4e332d258b6d53ff119c88dc0d39Hyunyoung Song runOnWorkerThread(new Runnable() { 3535d4af1484447129d489203130e0d654f81a10437dHyunyoung Song @Override 3536d4af1484447129d489203130e0d654f81a10437dHyunyoung Song public void run() { 35372e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal if (bindFirst && !mBgWidgetsModel.isEmpty()) { 35382e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal bindWidgetsModel(callbacks, mBgWidgetsModel.clone()); 35392e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal } 35402e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal final WidgetsModel model = mBgWidgetsModel.updateAndClone(mApp.getContext()); 35412e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal bindWidgetsModel(callbacks, model); 35428821ca9a6a5bf34308f9b70c2cabf9da17330497Hyunyoung Song // update the Widget entries inside DB on the worker thread. 35432bd3d7d1cb5e4d8d826982d11b456739fed6b817Hyunyoung Song LauncherAppState.getInstance().getWidgetCache().removeObsoletePreviews( 35442e1efb480a9b77a97cb623d4f5faf6802a417422Sunny Goyal model.getRawList()); 3545d4af1484447129d489203130e0d654f81a10437dHyunyoung Song } 3546d4af1484447129d489203130e0d654f81a10437dHyunyoung Song }); 3547d4af1484447129d489203130e0d654f81a10437dHyunyoung Song } 3548d4af1484447129d489203130e0d654f81a10437dHyunyoung Song 3549091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static boolean isPackageDisabled(Context context, String packageName, 3550ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user) { 3551ed13187a745866483139e2878037e1f8427ce567Kenny Guy final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3552ed13187a745866483139e2878037e1f8427ce567Kenny Guy return !launcherApps.isPackageEnabledForProfile(packageName, user); 3553df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung } 3554556f6135f992dcd5bfbfffe0172627bfbf57d24eAdam Cohen 3555ed13187a745866483139e2878037e1f8427ce567Kenny Guy public static boolean isValidPackageActivity(Context context, ComponentName cn, 3556ed13187a745866483139e2878037e1f8427ce567Kenny Guy UserHandleCompat user) { 3557ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung if (cn == null) { 3558ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung return false; 3559ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3560ed13187a745866483139e2878037e1f8427ce567Kenny Guy final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3561ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (!launcherApps.isPackageEnabledForProfile(cn.getPackageName(), user)) { 3562ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung return false; 3563ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3564ed13187a745866483139e2878037e1f8427ce567Kenny Guy return launcherApps.isActivityEnabledForProfile(cn, user); 3565ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung } 3566ee055715cfe5085aa7c1ff1f8a14348bd0cef604Winson Chung 3567a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen public static boolean isValidPackage(Context context, String packageName, 3568a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen UserHandleCompat user) { 3569a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen if (packageName == null) { 3570a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen return false; 3571a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen } 3572a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context); 3573a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen return launcherApps.isPackageEnabledForProfile(packageName, user); 3574a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen } 3575a28b78e8385f0f590b144038157afc7d34cd48b7Adam Cohen 35769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato /** 3577f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * Make an ShortcutInfo object for a restored application or shortcut item that points 3578f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * to a package that is not yet installed on the system. 3579f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren */ 3580d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal public ShortcutInfo getRestoredItemInfo(Cursor c, Intent intent, 3581d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal int promiseType, int itemType, CursorIconInfo iconInfo) { 3582f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren final ShortcutInfo info = new ShortcutInfo(); 3583349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.user = UserHandleCompat.myUserHandle(); 35844e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal 3585d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Bitmap icon = iconInfo.loadIcon(c, info); 35864e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal // the fallback icon 35874e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (icon == null) { 35884e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal mIconCache.getTitleAndIcon(info, intent, info.user, false /* useLowResIcon */); 35894e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } else { 35904e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal info.setIcon(icon); 35914e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal } 3592349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 3593349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if ((promiseType & ShortcutInfo.FLAG_RESTORED_ICON) != 0) { 3594d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal String title = iconInfo.getTitle(c); 3595349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (!TextUtils.isEmpty(title)) { 359682b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.title = Utilities.trim(title); 3597349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 3598349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } else if ((promiseType & ShortcutInfo.FLAG_AUTOINTALL_ICON) != 0) { 3599349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal if (TextUtils.isEmpty(info.title)) { 3600d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info.title = iconInfo.getTitle(c); 3601349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal } 3602f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } else { 3603349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal throw new InvalidParameterException("Invalid restoreType " + promiseType); 3604f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3605349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal 360682b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); 3607c22841bfd1961781a84cfccb98d1c2937a9adee4Sunny Goyal info.itemType = itemType; 3608349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal info.promisedIntent = intent; 3609756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal info.status = promiseType; 3610f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren return info; 3611f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3612f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 3613f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren /** 3614f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * Make an Intent object for a restored application or shortcut item that points 3615f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren * to the market page for the item. 3616f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren */ 3617091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Intent getRestoredItemIntent(Cursor c, Context context, Intent intent) { 3618f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren ComponentName componentName = intent.getComponent(); 3619e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return getMarketIntent(componentName.getPackageName()); 3620e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal } 3621e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal 3622e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal static Intent getMarketIntent(String packageName) { 3623e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal return new Intent(Intent.ACTION_VIEW) 3624e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .setData(new Uri.Builder() 3625f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren .scheme("market") 3626f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren .authority("details") 3627e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .appendQueryParameter("id", packageName) 3628e7b8cd9e4f8d38d0445f3a032fafd44332f70878Sunny Goyal .build()); 3629f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren } 3630f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren 3631f4d081107f5984bfb92cb1a627667fea5bf1498cChris Wren /** 363256d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * Make an ShortcutInfo object for a shortcut that is an application. 363356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * 363456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato * If c is not null, then it will be used to fill in missing data like the title and icon. 363556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato */ 3636d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal public ShortcutInfo getAppShortcutInfo(Intent intent, 3637d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal UserHandleCompat user, Cursor c, CursorIconInfo iconInfo, 363834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal boolean allowMissingTarget, boolean useLowResIcon) { 3639ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (user == null) { 3640ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "Null user found in getShortcutInfo"); 3641ed13187a745866483139e2878037e1f8427ce567Kenny Guy return null; 3642ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3643ed13187a745866483139e2878037e1f8427ce567Kenny Guy 364456d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato ComponentName componentName = intent.getComponent(); 3645ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (componentName == null) { 3646b740f59c7d572d54402e3a74fb2a23c0f1b1af48Sunny Goyal Log.d(TAG, "Missing component found in getShortcutInfo"); 36479c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return null; 364831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 364931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3650ed13187a745866483139e2878037e1f8427ce567Kenny Guy Intent newIntent = new Intent(intent.getAction(), null); 3651ed13187a745866483139e2878037e1f8427ce567Kenny Guy newIntent.addCategory(Intent.CATEGORY_LAUNCHER); 3652ed13187a745866483139e2878037e1f8427ce567Kenny Guy newIntent.setComponent(componentName); 3653ed13187a745866483139e2878037e1f8427ce567Kenny Guy LauncherActivityInfoCompat lai = mLauncherApps.resolveActivity(newIntent, user); 3654f599ccfe96eae7e4854bddfedd3df945feb9b7f5Sunny Goyal if ((lai == null) && !allowMissingTarget) { 3655ed13187a745866483139e2878037e1f8427ce567Kenny Guy Log.d(TAG, "Missing activity found in getShortcutInfo: " + componentName); 3656ed13187a745866483139e2878037e1f8427ce567Kenny Guy return null; 3657ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3658ed13187a745866483139e2878037e1f8427ce567Kenny Guy 3659ed13187a745866483139e2878037e1f8427ce567Kenny Guy final ShortcutInfo info = new ShortcutInfo(); 366034b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal mIconCache.getTitleAndIcon(info, componentName, lai, user, false, useLowResIcon); 36614fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (mIconCache.isDefaultIcon(info.getIcon(mIconCache), user) && c != null) { 3662d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Bitmap icon = iconInfo.loadIcon(c); 36634fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal info.setIcon(icon == null ? mIconCache.getDefaultIcon(user) : icon); 3664ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 3665ed13187a745866483139e2878037e1f8427ce567Kenny Guy 3666d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal if (lai != null && PackageManagerHelper.isAppSuspended(lai.getApplicationInfo())) { 3667d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal info.isDisabled = ShortcutInfo.FLAG_DISABLED_SUSPENDED; 3668d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal } 3669d09c37052ef9a70d4dde53ece6619f04de5f97cbSunny Goyal 367056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // from the db 36714fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal if (TextUtils.isEmpty(info.title) && c != null) { 3672d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info.title = iconInfo.getTitle(c); 367356d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato } 36744fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 367556d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato // fall back to the class name of the activity 36769c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato if (info.title == null) { 367756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.title = componentName.getClassName(); 36789c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 36794fbc3828c5ae1e8c5789ede974447fa365f3c5a1Sunny Goyal 36809c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; 3681ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = user; 368282b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); 3683fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal if (lai != null) { 3684fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal info.flags = AppInfo.initFlags(lai); 3685fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal } 36869c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato return info; 36879c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 368831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3689e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal static ArrayList<ItemInfo> filterItemInfos(Iterable<ItemInfo> infos, 369064359a53dc827797917a8d9a0697a91996789801Winson Chung ItemInfoFilter f) { 369164359a53dc827797917a8d9a0697a91996789801Winson Chung HashSet<ItemInfo> filtered = new HashSet<ItemInfo>(); 369264359a53dc827797917a8d9a0697a91996789801Winson Chung for (ItemInfo i : infos) { 369364359a53dc827797917a8d9a0697a91996789801Winson Chung if (i instanceof ShortcutInfo) { 369464359a53dc827797917a8d9a0697a91996789801Winson Chung ShortcutInfo info = (ShortcutInfo) i; 3695349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ComponentName cn = info.getTargetComponent(); 369664359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(null, info, cn)) { 369764359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(info); 369864359a53dc827797917a8d9a0697a91996789801Winson Chung } 369964359a53dc827797917a8d9a0697a91996789801Winson Chung } else if (i instanceof FolderInfo) { 370064359a53dc827797917a8d9a0697a91996789801Winson Chung FolderInfo info = (FolderInfo) i; 370164359a53dc827797917a8d9a0697a91996789801Winson Chung for (ShortcutInfo s : info.contents) { 3702349426234e8c5a0e5bcf2c8d94dbb9844b5f724aSunny Goyal ComponentName cn = s.getTargetComponent(); 370364359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(info, s, cn)) { 370464359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(s); 37058a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 37068a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 370764359a53dc827797917a8d9a0697a91996789801Winson Chung } else if (i instanceof LauncherAppWidgetInfo) { 370864359a53dc827797917a8d9a0697a91996789801Winson Chung LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) i; 370964359a53dc827797917a8d9a0697a91996789801Winson Chung ComponentName cn = info.providerName; 371064359a53dc827797917a8d9a0697a91996789801Winson Chung if (cn != null && f.filterItem(null, info, cn)) { 371164359a53dc827797917a8d9a0697a91996789801Winson Chung filtered.add(info); 371264359a53dc827797917a8d9a0697a91996789801Winson Chung } 37138a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 37148a4351063f02c0e8d64ee3ace651b227e9f8321fWinson Chung } 371564359a53dc827797917a8d9a0697a91996789801Winson Chung return new ArrayList<ItemInfo>(filtered); 371664359a53dc827797917a8d9a0697a91996789801Winson Chung } 371764359a53dc827797917a8d9a0697a91996789801Winson Chung 3718091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk ArrayList<ItemInfo> getItemInfoForComponentName(final ComponentName cname, 3719ed13187a745866483139e2878037e1f8427ce567Kenny Guy final UserHandleCompat user) { 372064359a53dc827797917a8d9a0697a91996789801Winson Chung ItemInfoFilter filter = new ItemInfoFilter() { 372164359a53dc827797917a8d9a0697a91996789801Winson Chung @Override 372264359a53dc827797917a8d9a0697a91996789801Winson Chung public boolean filterItem(ItemInfo parent, ItemInfo info, ComponentName cn) { 3723ed13187a745866483139e2878037e1f8427ce567Kenny Guy if (info.user == null) { 3724ed13187a745866483139e2878037e1f8427ce567Kenny Guy return cn.equals(cname); 3725ed13187a745866483139e2878037e1f8427ce567Kenny Guy } else { 3726ed13187a745866483139e2878037e1f8427ce567Kenny Guy return cn.equals(cname) && info.user.equals(user); 3727ed13187a745866483139e2878037e1f8427ce567Kenny Guy } 372864359a53dc827797917a8d9a0697a91996789801Winson Chung } 372964359a53dc827797917a8d9a0697a91996789801Winson Chung }; 3730e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal return filterItemInfos(sBgItemsIdMap, filter); 373164359a53dc827797917a8d9a0697a91996789801Winson Chung } 373264359a53dc827797917a8d9a0697a91996789801Winson Chung 37331a745e8f18e54aff152ff51743ae7595adde6927Sunny Goyal /** 37340589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Make an ShortcutInfo object for a shortcut that isn't an application. 37359c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato */ 3736d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal @Thunk ShortcutInfo getShortcutInfo(Cursor c, CursorIconInfo iconInfo) { 3737c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 3738ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Non-app shortcuts are only supported for current user. 3739ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = UserHandleCompat.myUserHandle(); 37409c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato info.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; 37417376faefbbcbe30cc4e3f706ab95c254a4707d98The Android Open Source Project 37428ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato // TODO: If there's an explicit component and we can't install that, delete it. 37438ddc4fdba06cfa786950c306475b7a4e3f6846abJoe Onorato 3744d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal loadInfoFromCursor(info, c, iconInfo); 3745d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal return info; 3746d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal } 374756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 3748d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal /** 3749d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal * Make an ShortcutInfo object for a shortcut that isn't an application. 3750d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal */ 3751d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal public void loadInfoFromCursor(ShortcutInfo info, Cursor c, CursorIconInfo iconInfo) { 3752d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal info.title = iconInfo.getTitle(c); 3753d3b87ef1963fb96177ca85bcd6a25879e27e419cSunny Goyal Bitmap icon = iconInfo.loadIcon(c, info); 37544e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal // the fallback icon 37554e5cc64eaf1f63d866d51ce0a6bbafb3d4085c21Sunny Goyal if (icon == null) { 3756ed13187a745866483139e2878037e1f8427ce567Kenny Guy icon = mIconCache.getDefaultIcon(info.user); 375756d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato info.usingFallbackIcon = true; 375831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 3759d8d22da5ca3e8d3e8d2e3616305b038d37486f32Joe Onorato info.setIcon(icon); 3760f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 376131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 37622350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal ShortcutInfo infoFromShortcutIntent(Context context, Intent data) { 37630589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); 37640589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); 37650589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON); 37660589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 3767d919882006a457d16dea46bd546472e6534b5c19Adam Cohen if (intent == null) { 3768d919882006a457d16dea46bd546472e6534b5c19Adam Cohen // If the intent is null, we can't construct a valid ShortcutInfo, so we return null 3769d919882006a457d16dea46bd546472e6534b5c19Adam Cohen Log.e(TAG, "Can't construct ShorcutInfo with null intent"); 3770d919882006a457d16dea46bd546472e6534b5c19Adam Cohen return null; 3771d919882006a457d16dea46bd546472e6534b5c19Adam Cohen } 3772d919882006a457d16dea46bd546472e6534b5c19Adam Cohen 37730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Bitmap icon = null; 37740589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato boolean customIcon = false; 37750589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutIconResource iconResource = null; 37760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 37772fce90c38a79d318e96a28107dea287e42509861Sunny Goyal if (bitmap instanceof Bitmap) { 37782fce90c38a79d318e96a28107dea287e42509861Sunny Goyal icon = Utilities.createIconBitmap((Bitmap) bitmap, context); 37790589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato customIcon = true; 37800589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } else { 37810589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE); 3782b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal if (extra instanceof ShortcutIconResource) { 3783b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal iconResource = (ShortcutIconResource) extra; 3784b50cc8c5d6125715b139d978887830a5341971aaSunny Goyal icon = Utilities.createIconBitmap(iconResource.packageName, 378553d7ee4285842732517edcccbdcaa92dccb1e107Sunny Goyal iconResource.resourceName, context); 37860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 37870589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 37880589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 3789c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka final ShortcutInfo info = new ShortcutInfo(); 379056d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 3791ed13187a745866483139e2878037e1f8427ce567Kenny Guy // Only support intents for current user for now. Intents sent from other 3792ed13187a745866483139e2878037e1f8427ce567Kenny Guy // users wouldn't get here without intent forwarding anyway. 3793ed13187a745866483139e2878037e1f8427ce567Kenny Guy info.user = UserHandleCompat.myUserHandle(); 37940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (icon == null) { 37952350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal icon = mIconCache.getDefaultIcon(info.user); 37962350bc97851eea1662eee43d61290eb7a8382021Sunny Goyal info.usingFallbackIcon = true; 37970589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 37980589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.setIcon(icon); 379956d8291af6a28c6ba64113120efdf84a785e816cJoe Onorato 380082b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.title = Utilities.trim(name); 380182b016cb56540fe26213e817dd0dd668099c8e20Winson Chung info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user); 38020589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.intent = intent; 38030589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato info.iconResource = iconResource; 38040589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 38050589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return info; 38060589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 38070589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 380831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 3809df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * Return an existing FolderInfo object if we have encountered this ID previously, 38109c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato * or make a new one. 381131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 3812e2df0620c13b9dc7e63224153b98fdbb48546f9bSunny Goyal @Thunk static FolderInfo findOrMakeFolder(LongArrayMap<FolderInfo> folders, long id) { 38139c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // See if a placeholder was created for us already 38149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato FolderInfo folderInfo = folders.get(id); 3815df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (folderInfo == null) { 38169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato // No placeholder -- create a new instance 3817c9d95c5897fc5ebbf53903d4ab18ad13d196f643Michael Jurka folderInfo = new FolderInfo(); 38189c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato folders.put(id, folderInfo); 381931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 3820df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return folderInfo; 382131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 382231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3823be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato 3824651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal static boolean isValidProvider(AppWidgetProviderInfo provider) { 3825651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal return (provider != null) && (provider.provider != null) 3826651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal && (provider.provider.getPackageName() != null); 3827651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal } 3828651077bdd603bb182be039925fd17bdf0da15016Sunny Goyal 3829be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato public void dumpState() { 3830be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato Log.d(TAG, "mCallbacks=" + mCallbacks); 3831eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.data", mBgAllAppsList.data); 3832eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.added", mBgAllAppsList.added); 3833eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.removed", mBgAllAppsList.removed); 3834eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka AppInfo.dumpApplicationInfoList(TAG, "mAllAppsList.modified", mBgAllAppsList.modified); 38353611578579b4bfb25616085dafdb1a45207394f9Joe Onorato if (mLoaderTask != null) { 38363611578579b4bfb25616085dafdb1a45207394f9Joe Onorato mLoaderTask.dumpState(); 38373611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } else { 38383611578579b4bfb25616085dafdb1a45207394f9Joe Onorato Log.d(TAG, "mLoaderTask=null"); 38393611578579b4bfb25616085dafdb1a45207394f9Joe Onorato } 3840be38609f875f9b9374ceaf723135c0a624637fcbJoe Onorato } 3841e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal 3842e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal public Callbacks getCallback() { 3843e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal return mCallbacks != null ? mCallbacks.get() : null; 3844e0f58d73646871497596fb8f7321d407e7565c28Sunny Goyal } 384518bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal 384618bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal /** 384718bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal * @return {@link FolderInfo} if its already loaded. 384818bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal */ 384918bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal public FolderInfo findFolderById(Long folderId) { 385018bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal synchronized (sBgLock) { 385118bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal return sBgFolders.get(folderId); 385218bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal } 385318bf8e2ffde3444d53aaa9654da02cdedd0b7cd1Sunny Goyal } 3854756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal 3855527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal @Thunk class DeferredMainThreadExecutor implements Executor { 3856527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 3857527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal @Override 3858527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal public void execute(Runnable command) { 3859527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal runOnMainThread(command); 3860527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 3861527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal } 3862527c7d3460345953e6b3427a74b1dacaddcb1111Sunny Goyal 3863756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal /** 3864756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal * @return the looper for the worker thread which can be used to start background tasks. 3865756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal */ 3866756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal public static Looper getWorkerLooper() { 3867756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal return sWorkerThread.getLooper(); 3868756adbc3e41ee1edb53c580b8c679f343924fab5Sunny Goyal } 386931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 3870