Loading src/com/android/launcher3/InstallShortcutReceiver.java +49 −39 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading Loading @@ -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)); } } Loading Loading @@ -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; } } } src/com/android/launcher3/LauncherModel.java +10 −2 Original line number Diff line number Diff line Loading @@ -85,6 +85,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; Loading Loading @@ -257,12 +258,19 @@ public class LauncherModel extends BroadcastReceiver CacheDataUpdatedTask.OP_SESSION_UPDATE, UserHandleCompat.myUserHandle(), packages)); } /** * 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)); } /** Loading src/com/android/launcher3/model/AddWorkspaceItemsTask.java +9 −7 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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)) { Loading Loading @@ -258,5 +261,4 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask { } return occupied.findVacantCell(xy, spanX, spanY); } } src/com/android/launcher3/util/ManagedProfileHeuristic.java +2 −2 Original line number Diff line number Diff line Loading @@ -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)); } } Loading Loading @@ -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(); Loading src/com/android/launcher3/util/Provider.java 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * 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; } }; } } Loading
src/com/android/launcher3/InstallShortcutReceiver.java +49 −39 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading Loading @@ -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)); } } Loading Loading @@ -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; } } }
src/com/android/launcher3/LauncherModel.java +10 −2 Original line number Diff line number Diff line Loading @@ -85,6 +85,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; Loading Loading @@ -257,12 +258,19 @@ public class LauncherModel extends BroadcastReceiver CacheDataUpdatedTask.OP_SESSION_UPDATE, UserHandleCompat.myUserHandle(), packages)); } /** * 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)); } /** Loading
src/com/android/launcher3/model/AddWorkspaceItemsTask.java +9 −7 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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)) { Loading Loading @@ -258,5 +261,4 @@ public class AddWorkspaceItemsTask extends ExtendedModelTask { } return occupied.findVacantCell(xy, spanX, spanY); } }
src/com/android/launcher3/util/ManagedProfileHeuristic.java +2 −2 Original line number Diff line number Diff line Loading @@ -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)); } } Loading Loading @@ -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(); Loading
src/com/android/launcher3/util/Provider.java 0 → 100644 +38 −0 Original line number Diff line number Diff line /* * 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; } }; } }