diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2016-11-16 09:23:42 -0800 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2016-11-30 05:47:57 +0530 |
commit | 2bcbe13c642efa4c94df570441c700b7aa8e353d (patch) | |
tree | 42528a9bf5d9282314cdae2092ce8982c73ad6db /src | |
parent | 6f59cff0d66db55913e62f9f9452be5828970672 (diff) |
Moving ShortcutInfo creation in InstallShortcutReceiver to background thread
> Creating shortcut info requires iconCache access
Bug: 21325319
Change-Id: I3317d8b6824aa05b836f3ed3626f169d4d34f783
Diffstat (limited to 'src')
5 files changed, 108 insertions, 50 deletions
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java index 056facba57..d2f25a4a05 100644 --- a/src/com/android/launcher3/InstallShortcutReceiver.java +++ b/src/com/android/launcher3/InstallShortcutReceiver.java @@ -33,6 +33,8 @@ import com.android.launcher3.compat.LauncherAppsCompat; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserManagerCompat; import com.android.launcher3.util.PackageManagerHelper; +import com.android.launcher3.util.Preconditions; +import com.android.launcher3.util.Provider; import com.android.launcher3.util.Thunk; import org.json.JSONException; @@ -44,6 +46,7 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; public class InstallShortcutReceiver extends BroadcastReceiver { @@ -76,11 +79,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver { String encoded = info.encodeToString(); if (encoded != null) { Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null); - if (strings == null) { - strings = new HashSet<String>(1); - } else { - strings = new HashSet<String>(strings); - } + strings = (strings != null) ? new HashSet<>(strings) : new HashSet<String>(1); strings.add(encoded); sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, strings).apply(); } @@ -115,16 +114,15 @@ public class InstallShortcutReceiver extends BroadcastReceiver { } } - private static ArrayList<PendingInstallShortcutInfo> getAndClearInstallQueue( - SharedPreferences sharedPrefs, Context context) { + private static ArrayList<PendingInstallShortcutInfo> getAndClearInstallQueue(Context context) { + SharedPreferences sharedPrefs = Utilities.getPrefs(context); synchronized(sLock) { + ArrayList<PendingInstallShortcutInfo> infos = new ArrayList<>(); Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null); if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings); if (strings == null) { - return new ArrayList<PendingInstallShortcutInfo>(); + return infos; } - ArrayList<PendingInstallShortcutInfo> infos = - new ArrayList<PendingInstallShortcutInfo>(); for (String encoded : strings) { PendingInstallShortcutInfo info = decode(encoded, context); if (info != null) { @@ -212,36 +210,12 @@ public class InstallShortcutReceiver extends BroadcastReceiver { mUseInstallQueue = false; flushInstallQueue(context); } - static void flushInstallQueue(Context context) { - SharedPreferences sp = Utilities.getPrefs(context); - ArrayList<PendingInstallShortcutInfo> installQueue = getAndClearInstallQueue(sp, context); - if (!installQueue.isEmpty()) { - Iterator<PendingInstallShortcutInfo> iter = installQueue.iterator(); - ArrayList<ItemInfo> addShortcuts = new ArrayList<ItemInfo>(); - while (iter.hasNext()) { - final PendingInstallShortcutInfo pendingInfo = iter.next(); - - // If the intent specifies a package, make sure the package exists - String packageName = pendingInfo.getTargetPackage(); - if (!TextUtils.isEmpty(packageName)) { - UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle(); - if (!LauncherAppsCompat.getInstance(context) - .isPackageEnabledForProfile(packageName, myUserHandle)) { - if (DBG) Log.d(TAG, "Ignoring shortcut for absent package: " - + pendingInfo.launchIntent); - continue; - } - } - // Generate a shortcut info to add into the model - addShortcuts.add(pendingInfo.getShortcutInfo()); - } - - // Add the new apps to the model and bind them - if (!addShortcuts.isEmpty()) { - LauncherAppState app = LauncherAppState.getInstance(); - app.getModel().addAndBindAddedWorkspaceItems(addShortcuts); - } + static void flushInstallQueue(Context context) { + ArrayList<PendingInstallShortcutInfo> items = getAndClearInstallQueue(context); + if (!items.isEmpty()) { + LauncherAppState.getInstance().getModel().addAndBindAddedWorkspaceItems( + new LazyShortcutsProvider(context.getApplicationContext(), items)); } } @@ -445,4 +419,40 @@ public class InstallShortcutReceiver extends BroadcastReceiver { // Ignore any conflicts in the label name, as that can change based on locale. return new PendingInstallShortcutInfo(info, original.mContext); } + + private static class LazyShortcutsProvider extends Provider<List<ItemInfo>> { + + private final Context mContext; + private final ArrayList<PendingInstallShortcutInfo> mPendingItems; + + public LazyShortcutsProvider(Context context, ArrayList<PendingInstallShortcutInfo> items) { + mContext = context; + mPendingItems = items; + } + + /** + * This must be called on the background thread as this requires multiple calls to + * packageManager and icon cache. + */ + @Override + public ArrayList<ItemInfo> get() { + Preconditions.assertNonUiThread(); + ArrayList<ItemInfo> installQueue = new ArrayList<>(); + LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext); + for (PendingInstallShortcutInfo pendingInfo : mPendingItems) { + // If the intent specifies a package, make sure the package exists + String packageName = pendingInfo.getTargetPackage(); + if (!TextUtils.isEmpty(packageName) && !launcherApps.isPackageEnabledForProfile( + packageName, pendingInfo.user)) { + if (DBG) Log.d(TAG, "Ignoring shortcut for absent package: " + + pendingInfo.launchIntent); + continue; + } + + // Generate a shortcut info to add into the model + installQueue.add(pendingInfo.getShortcutInfo()); + } + return installQueue; + } + } } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index c70a47595d..3daa2c30f1 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -84,6 +84,7 @@ import com.android.launcher3.util.ManagedProfileHeuristic; import com.android.launcher3.util.MultiHashMap; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Preconditions; +import com.android.launcher3.util.Provider; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.ViewOnDrawExecutor; @@ -261,9 +262,16 @@ public class LauncherModel extends BroadcastReceiver /** * Adds the provided items to the workspace. */ + public void addAndBindAddedWorkspaceItems(List<ItemInfo> workspaceApps) { + addAndBindAddedWorkspaceItems(Provider.of(workspaceApps)); + } + + /** + * Adds the provided items to the workspace. + */ public void addAndBindAddedWorkspaceItems( - final ArrayList<? extends ItemInfo> workspaceApps) { - enqueueModelUpdateTask(new AddWorkspaceItemsTask(workspaceApps)); + Provider<List<ItemInfo>> appsProvider) { + enqueueModelUpdateTask(new AddWorkspaceItemsTask(appsProvider)); } /** diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java index 986e163e6f..97335cb256 100644 --- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java +++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java @@ -33,26 +33,29 @@ import com.android.launcher3.LauncherSettings; import com.android.launcher3.ShortcutInfo; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.util.GridOccupancy; +import com.android.launcher3.util.Provider; import java.util.ArrayList; +import java.util.List; /** * Task to add auto-created workspace items. */ public class AddWorkspaceItemsTask extends ExtendedModelTask { - private final ArrayList<? extends ItemInfo> mWorkspaceApps; + private final Provider<List<ItemInfo>> mAppsProvider; /** - * @param workspaceApps items to add on the workspace + * @param appsProvider items to add on the workspace */ - public AddWorkspaceItemsTask(ArrayList<? extends ItemInfo> workspaceApps) { - mWorkspaceApps = workspaceApps; + public AddWorkspaceItemsTask(Provider<List<ItemInfo>> appsProvider) { + mAppsProvider = appsProvider; } @Override public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) { - if (mWorkspaceApps.isEmpty()) { + List<ItemInfo> workspaceApps = mAppsProvider.get(); + if (workspaceApps.isEmpty()) { return; } Context context = app.getContext(); @@ -65,7 +68,7 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask { // called. ArrayList<Long> workspaceScreens = LauncherModel.loadWorkspaceScreensDb(context); synchronized(dataModel) { - for (ItemInfo item : mWorkspaceApps) { + for (ItemInfo item : workspaceApps) { if (item instanceof ShortcutInfo) { // Short-circuit this logic if the icon exists somewhere on the workspace if (shortcutExists(dataModel, item.getIntent(), item.user)) { @@ -258,5 +261,4 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask { } return occupied.findVacantCell(xy, spanX, spanY); } - } diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java index 78b7a3eee3..817a38ad5c 100644 --- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java +++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java @@ -121,7 +121,7 @@ public class ManagedProfileHeuristic { // getting filled with the managed user apps, when it start with a fresh DB (or after // a very long time). if (userAppsExisted && !homescreenApps.isEmpty()) { - mModel.addAndBindAddedWorkspaceItems(homescreenApps); + mModel.addAndBindAddedWorkspaceItems(new ArrayList<ItemInfo>(homescreenApps)); } } @@ -173,7 +173,7 @@ public class ManagedProfileHeuristic { } // Add the item to home screen and DB. This also generates an item id synchronously. - ArrayList<ItemInfo> itemList = new ArrayList<ItemInfo>(1); + ArrayList<ItemInfo> itemList = new ArrayList<>(1); itemList.add(workFolder); mModel.addAndBindAddedWorkspaceItems(itemList); mPrefs.edit().putLong(folderIdKey, workFolder.id).apply(); diff --git a/src/com/android/launcher3/util/Provider.java b/src/com/android/launcher3/util/Provider.java new file mode 100644 index 0000000000..1cdd8d6aa0 --- /dev/null +++ b/src/com/android/launcher3/util/Provider.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.util; + +/** + * Utility class to allow lazy initialization of objects. + */ +public abstract class Provider<T> { + + /** + * Initializes and returns the object. This may contain expensive operations not suitable + * to UI thread. + */ + public abstract T get(); + + public static <T> Provider<T> of (final T value) { + return new Provider<T>() { + @Override + public T get() { + return value; + } + }; + } +} |