Removing static reference of deep shortcut manager
Bug: 141376165 Change-Id: Ie60b82be63a8926825598c681d8b2a1b2ace6413
This commit is contained in:
parent
98833d525c
commit
fa39536570
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2018 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.shortcuts;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.notification.NotificationKeyData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Performs operations related to deep shortcuts, such as querying for them, pinning them, etc.
|
||||
*/
|
||||
public class DeepShortcutManager {
|
||||
|
||||
private static final DeepShortcutManager sInstance = new DeepShortcutManager();
|
||||
|
||||
public static DeepShortcutManager getInstance(Context context) {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private final QueryResult mFailure = new QueryResult();
|
||||
|
||||
private DeepShortcutManager() { }
|
||||
|
||||
/**
|
||||
* Queries for the shortcuts with the package name and provided ids.
|
||||
*
|
||||
* This method is intended to get the full details for shortcuts when they are added or updated,
|
||||
* because we only get "key" fields in onShortcutsChanged().
|
||||
*/
|
||||
public QueryResult queryForFullDetails(String packageName,
|
||||
List<String> shortcutIds, UserHandle user) {
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the manifest and dynamic shortcuts associated with the given package and user,
|
||||
* to be displayed in the shortcuts container on long press.
|
||||
*/
|
||||
public QueryResult queryForShortcutsContainer(ComponentName activity,
|
||||
UserHandle user) {
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given shortcut from the current list of pinned shortcuts.
|
||||
* (Runs on background thread)
|
||||
*/
|
||||
public void unpinShortcut(final ShortcutKey key) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given shortcut to the current list of pinned shortcuts.
|
||||
* (Runs on background thread)
|
||||
*/
|
||||
public void pinShortcut(final ShortcutKey key) {
|
||||
}
|
||||
|
||||
public void startShortcut(String packageName, String id, Rect sourceBounds,
|
||||
Bundle startActivityOptions, UserHandle user) {
|
||||
}
|
||||
|
||||
public Drawable getShortcutIconDrawable(ShortcutInfo shortcutInfo, int density) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id's of pinned shortcuts associated with the given package and user.
|
||||
*
|
||||
* If packageName is null, returns all pinned shortcuts regardless of package.
|
||||
*/
|
||||
public QueryResult queryForPinnedShortcuts(String packageName, UserHandle user) {
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
public QueryResult queryForPinnedShortcuts(String packageName,
|
||||
List<String> shortcutIds, UserHandle user) {
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
public QueryResult queryForAllShortcuts(UserHandle user) {
|
||||
return mFailure;
|
||||
}
|
||||
|
||||
public boolean hasHostPermission() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static class QueryResult extends ArrayList<ShortcutInfo> {
|
||||
|
||||
public boolean wasSuccess() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,8 +44,8 @@ import com.android.launcher3.WorkspaceItemInfo;
|
|||
import com.android.launcher3.allapps.AllAppsStore;
|
||||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.InstantAppResolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -167,11 +167,7 @@ public class DynamicItemCache {
|
|||
|
||||
@WorkerThread
|
||||
private WorkspaceItemInfo loadShortcutWorker(ShortcutKey shortcutKey) {
|
||||
DeepShortcutManager mgr = DeepShortcutManager.getInstance(mContext);
|
||||
List<ShortcutInfo> details = mgr.queryForFullDetails(
|
||||
shortcutKey.componentName.getPackageName(),
|
||||
Collections.<String>singletonList(shortcutKey.getId()),
|
||||
shortcutKey.user);
|
||||
List<ShortcutInfo> details = shortcutKey.buildRequest(mContext).query(ShortcutRequest.ALL);
|
||||
if (!details.isEmpty()) {
|
||||
WorkspaceItemInfo si = new WorkspaceItemInfo(details.get(0), mContext);
|
||||
try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
@ -24,7 +25,12 @@ import android.app.Activity;
|
|||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.ContextThemeWrapper;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
@ -47,6 +53,8 @@ import java.util.ArrayList;
|
|||
public abstract class BaseActivity extends Activity
|
||||
implements UserEventDelegate, LogStateProvider, ActivityContext {
|
||||
|
||||
private static final String TAG = "BaseActivity";
|
||||
|
||||
public static final int INVISIBLE_BY_STATE_HANDLER = 1 << 0;
|
||||
public static final int INVISIBLE_BY_APP_TRANSITIONS = 1 << 1;
|
||||
public static final int INVISIBLE_BY_PENDING_FLAGS = 1 << 2;
|
||||
|
@ -312,6 +320,22 @@ public abstract class BaseActivity extends Activity
|
|||
writer.println(prefix + "mForceInvisible: " + mForceInvisible);
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper around the platform method with Launcher specific checks
|
||||
*/
|
||||
public void startShortcut(String packageName, String id, Rect sourceBounds,
|
||||
Bundle startActivityOptions, UserHandle user) {
|
||||
if (GO_DISABLE_WIDGETS) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
getSystemService(LauncherApps.class).startShortcut(packageName, id, sourceBounds,
|
||||
startActivityOptions, user);
|
||||
} catch (SecurityException | IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to start shortcut", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T extends BaseActivity> T fromContext(Context context) {
|
||||
if (context instanceof BaseActivity) {
|
||||
return (T) context;
|
||||
|
|
|
@ -35,7 +35,6 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import com.android.launcher3.LauncherSettings.Favorites;
|
||||
import com.android.launcher3.model.AppLaunchTracker;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.uioverrides.DisplayRotationListener;
|
||||
import com.android.launcher3.uioverrides.WallpaperColorInfo;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
@ -198,8 +197,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
|
|||
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
|
||||
String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
|
||||
String packageName = intent.getPackage();
|
||||
DeepShortcutManager.getInstance(this).startShortcut(
|
||||
packageName, id, intent.getSourceBounds(), optsBundle, info.user);
|
||||
startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
|
||||
AppLaunchTracker.INSTANCE.get(this).onStartShortcut(packageName, id, info.user,
|
||||
sourceContainer);
|
||||
} else {
|
||||
|
|
|
@ -49,8 +49,8 @@ import com.android.launcher3.icons.BitmapInfo;
|
|||
import com.android.launcher3.icons.GraphicsUtils;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.pm.UserCache;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
@ -538,12 +538,9 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
|||
return new PendingInstallShortcutInfo(info, context);
|
||||
}
|
||||
} else if (decoder.optBoolean(DEEPSHORTCUT_TYPE_KEY)) {
|
||||
DeepShortcutManager sm = DeepShortcutManager.getInstance(context);
|
||||
List<ShortcutInfo> si = sm.queryForFullDetails(
|
||||
decoder.launcherIntent.getPackage(),
|
||||
Arrays.asList(decoder.launcherIntent.getStringExtra(
|
||||
ShortcutKey.EXTRA_SHORTCUT_ID)),
|
||||
decoder.user);
|
||||
List<ShortcutInfo> si = ShortcutKey.fromIntent(decoder.launcherIntent, decoder.user)
|
||||
.buildRequest(context)
|
||||
.query(ShortcutRequest.ALL);
|
||||
if (si.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
|
|
|
@ -20,6 +20,7 @@ import static com.android.launcher3.LauncherAppState.ACTION_FORCE_ROLOAD;
|
|||
import static com.android.launcher3.config.FeatureFlags.IS_DOGFOOD_BUILD;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -54,7 +55,7 @@ import com.android.launcher3.model.UserLockStateChangedTask;
|
|||
import com.android.launcher3.pm.InstallSessionTracker;
|
||||
import com.android.launcher3.pm.PackageInstallInfo;
|
||||
import com.android.launcher3.pm.UserCache;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.IntSparseArrayMap;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
|
@ -113,12 +114,9 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
|
|||
private final Runnable mShortcutPermissionCheckRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mModelLoaded) {
|
||||
boolean hasShortcutHostPermission =
|
||||
DeepShortcutManager.getInstance(mApp.getContext()).hasHostPermission();
|
||||
if (hasShortcutHostPermission != sBgDataModel.hasShortcutHostPermission) {
|
||||
forceReload();
|
||||
}
|
||||
if (mModelLoaded && hasShortcutsPermission(mApp.getContext())
|
||||
!= sBgDataModel.hasShortcutHostPermission) {
|
||||
forceReload();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -220,8 +218,8 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
|
|||
Context context = mApp.getContext();
|
||||
onPackageChanged(packageName, user);
|
||||
|
||||
List<ShortcutInfo> pinnedShortcuts = DeepShortcutManager.getInstance(context)
|
||||
.queryForPinnedShortcuts(packageName, user);
|
||||
List<ShortcutInfo> pinnedShortcuts = new ShortcutRequest(context, user)
|
||||
.forPackage(packageName).query(ShortcutRequest.PINNED);
|
||||
if (!pinnedShortcuts.isEmpty()) {
|
||||
enqueueModelUpdateTask(new ShortcutsChangedTask(packageName, pinnedShortcuts, user,
|
||||
false));
|
||||
|
|
|
@ -65,9 +65,10 @@ import com.android.launcher3.graphics.RotationMode;
|
|||
import com.android.launcher3.graphics.TintedDrawableSpan;
|
||||
import com.android.launcher3.icons.IconProvider;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.icons.ShortcutCachingLogic;
|
||||
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.views.Transposable;
|
||||
|
@ -540,15 +541,14 @@ public final class Utilities {
|
|||
outObj[0] = activityInfo;
|
||||
return activityInfo.getFullResIcon(appState.getIconCache());
|
||||
}
|
||||
ShortcutKey key = ShortcutKey.fromItemInfo(info);
|
||||
DeepShortcutManager sm = DeepShortcutManager.getInstance(launcher);
|
||||
List<ShortcutInfo> si = sm.queryForFullDetails(
|
||||
key.componentName.getPackageName(), Arrays.asList(key.getId()), key.user);
|
||||
List<ShortcutInfo> si = ShortcutKey.fromItemInfo(info)
|
||||
.buildRequest(launcher)
|
||||
.query(ShortcutRequest.ALL);
|
||||
if (si.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
outObj[0] = si.get(0);
|
||||
return sm.getShortcutIconDrawable(si.get(0),
|
||||
return ShortcutCachingLogic.getIcon(launcher, si.get(0),
|
||||
appState.getInvariantDeviceProfile().fillResIconDpi);
|
||||
}
|
||||
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
|
||||
|
|
|
@ -15,13 +15,14 @@
|
|||
*/
|
||||
package com.android.launcher3.allapps;
|
||||
|
||||
import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.android.launcher3.AppInfo;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.LabelComparator;
|
||||
|
@ -398,7 +399,7 @@ public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener {
|
|||
|
||||
private boolean shouldShowWorkFooter() {
|
||||
return mIsWork && Utilities.ATLEAST_P &&
|
||||
(DeepShortcutManager.getInstance(mLauncher).hasHostPermission()
|
||||
(hasShortcutsPermission(mLauncher)
|
||||
|| mLauncher.checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
|
||||
== PackageManager.PERMISSION_GRANTED);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import com.android.launcher3.LauncherAppState;
|
|||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.graphics.IconShape;
|
||||
import com.android.launcher3.model.PackageItemInfo;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
@ -133,8 +132,8 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable {
|
|||
|
||||
public BitmapInfo createShortcutIconLegacy(ShortcutInfo shortcutInfo, boolean badged,
|
||||
@Nullable Supplier<ItemInfoWithIcon> fallbackIconProvider) {
|
||||
Drawable unbadgedDrawable = DeepShortcutManager.getInstance(mContext)
|
||||
.getShortcutIconDrawable(shortcutInfo, mFillResIconDpi);
|
||||
Drawable unbadgedDrawable = ShortcutCachingLogic.getIcon(
|
||||
mContext, shortcutInfo, mFillResIconDpi);
|
||||
IconCache cache = LauncherAppState.getInstance(mContext).getIconCache();
|
||||
final Bitmap unbadgedBitmap;
|
||||
if (unbadgedDrawable != null) {
|
||||
|
|
|
@ -16,19 +16,22 @@
|
|||
|
||||
package com.android.launcher3.icons;
|
||||
|
||||
import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.icons.cache.CachingLogic;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
||||
|
@ -37,6 +40,8 @@ import com.android.launcher3.util.Themes;
|
|||
*/
|
||||
public class ShortcutCachingLogic implements CachingLogic<ShortcutInfo> {
|
||||
|
||||
private static final String TAG = "ShortcutCachingLogic";
|
||||
|
||||
@Override
|
||||
public ComponentName getComponent(ShortcutInfo info) {
|
||||
return ShortcutKey.fromInfo(info).componentName;
|
||||
|
@ -56,8 +61,8 @@ public class ShortcutCachingLogic implements CachingLogic<ShortcutInfo> {
|
|||
@Override
|
||||
public BitmapInfo loadIcon(Context context, ShortcutInfo info) {
|
||||
try (LauncherIcons li = LauncherIcons.obtain(context)) {
|
||||
Drawable unbadgedDrawable = DeepShortcutManager.getInstance(context)
|
||||
.getShortcutIconDrawable(info, LauncherAppState.getIDP(context).fillResIconDpi);
|
||||
Drawable unbadgedDrawable = ShortcutCachingLogic.getIcon(
|
||||
context, info, LauncherAppState.getIDP(context).fillResIconDpi);
|
||||
if (unbadgedDrawable == null) return BitmapInfo.LOW_RES_INFO;
|
||||
return new BitmapInfo(li.createScaledBitmapWithoutShadow(
|
||||
unbadgedDrawable, 0), Themes.getColorAccent(context));
|
||||
|
@ -76,4 +81,21 @@ public class ShortcutCachingLogic implements CachingLogic<ShortcutInfo> {
|
|||
public boolean addToMemCache() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link LauncherApps#getShortcutIconDrawable(ShortcutInfo, int)} with additional
|
||||
* Launcher specific checks
|
||||
*/
|
||||
public static Drawable getIcon(Context context, ShortcutInfo shortcutInfo, int density) {
|
||||
if (GO_DISABLE_WIDGETS) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return context.getSystemService(LauncherApps.class)
|
||||
.getShortcutIconDrawable(shortcutInfo, density);
|
||||
} catch (SecurityException | IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to get shortcut icon", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
*/
|
||||
package com.android.launcher3.model;
|
||||
|
||||
import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
|
||||
import static com.android.launcher3.shortcuts.ShortcutRequest.PINNED;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
|
@ -29,15 +33,15 @@ import com.android.launcher3.ItemInfo;
|
|||
import com.android.launcher3.LauncherAppWidgetInfo;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.PromiseAppInfo;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.logging.DumpTargetWrapper;
|
||||
import com.android.launcher3.model.nano.LauncherDumpProto;
|
||||
import com.android.launcher3.model.nano.LauncherDumpProto.ContainerType;
|
||||
import com.android.launcher3.model.nano.LauncherDumpProto.DumpTarget;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.IntSet;
|
||||
|
@ -59,6 +63,8 @@ import java.util.HashSet;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* All the data stored in-memory and managed by the LauncherModel
|
||||
|
@ -287,7 +293,7 @@ public class BgDataModel {
|
|||
if ((count == null || --count.value == 0)
|
||||
&& !InstallShortcutReceiver.getPendingShortcuts(context)
|
||||
.contains(pinnedShortcut)) {
|
||||
DeepShortcutManager.getInstance(context).unpinShortcut(pinnedShortcut);
|
||||
unpinShortcut(context, pinnedShortcut);
|
||||
}
|
||||
// Fall through.
|
||||
}
|
||||
|
@ -324,7 +330,7 @@ public class BgDataModel {
|
|||
|
||||
// Since this is a new item, pin the shortcut in the system server.
|
||||
if (newItem && count.value == 1) {
|
||||
DeepShortcutManager.getInstance(context).pinShortcut(pinnedShortcut);
|
||||
updatePinnedShortcuts(context, pinnedShortcut, List::add);
|
||||
}
|
||||
// Fall through
|
||||
}
|
||||
|
@ -354,6 +360,36 @@ public class BgDataModel {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given shortcut from the current list of pinned shortcuts.
|
||||
* (Runs on background thread)
|
||||
*/
|
||||
public void unpinShortcut(Context context, ShortcutKey key) {
|
||||
updatePinnedShortcuts(context, key, List::remove);
|
||||
}
|
||||
|
||||
private void updatePinnedShortcuts(Context context, ShortcutKey key,
|
||||
BiConsumer<List<String>, String> idOp) {
|
||||
if (GO_DISABLE_WIDGETS) {
|
||||
return;
|
||||
}
|
||||
String packageName = key.componentName.getPackageName();
|
||||
String id = key.getId();
|
||||
UserHandle user = key.user;
|
||||
List<String> pinnedIds = new ShortcutRequest(context, user)
|
||||
.forPackage(packageName)
|
||||
.query(PINNED)
|
||||
.stream()
|
||||
.map(ShortcutInfo::getId)
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
idOp.accept(pinnedIds, id);
|
||||
try {
|
||||
context.getSystemService(LauncherApps.class).pinShortcuts(packageName, pinnedIds, user);
|
||||
} catch (SecurityException | IllegalStateException e) {
|
||||
Log.w(TAG, "Failed to pin shortcut", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an existing FolderInfo object if we have encountered this ID previously,
|
||||
* or make a new one.
|
||||
|
|
|
@ -21,6 +21,7 @@ import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
|
|||
import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
|
||||
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
|
||||
import static com.android.launcher3.util.PackageManagerHelper.isSystemApp;
|
||||
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
|
@ -72,8 +73,9 @@ import com.android.launcher3.pm.PackageInstallInfo;
|
|||
import com.android.launcher3.pm.UserCache;
|
||||
import com.android.launcher3.provider.ImportDataTask;
|
||||
import com.android.launcher3.qsb.QsbContainerView;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest.QueryResult;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.IOUtils;
|
||||
import com.android.launcher3.util.LooperIdleLock;
|
||||
|
@ -114,7 +116,6 @@ public class LoaderTask implements Runnable {
|
|||
private final UserManager mUserManager;
|
||||
private final UserCache mUserCache;
|
||||
|
||||
private final DeepShortcutManager mShortcutManager;
|
||||
private final InstallSessionHelper mSessionHelper;
|
||||
private final IconCache mIconCache;
|
||||
|
||||
|
@ -130,7 +131,6 @@ public class LoaderTask implements Runnable {
|
|||
mLauncherApps = mApp.getContext().getSystemService(LauncherApps.class);
|
||||
mUserManager = mApp.getContext().getSystemService(UserManager.class);
|
||||
mUserCache = UserCache.INSTANCE.get(mApp.getContext());
|
||||
mShortcutManager = DeepShortcutManager.getInstance(mApp.getContext());
|
||||
mSessionHelper = InstallSessionHelper.INSTANCE.get(mApp.getContext());
|
||||
mIconCache = mApp.getIconCache();
|
||||
}
|
||||
|
@ -349,8 +349,8 @@ public class LoaderTask implements Runnable {
|
|||
|
||||
// We can only query for shortcuts when the user is unlocked.
|
||||
if (userUnlocked) {
|
||||
DeepShortcutManager.QueryResult pinnedShortcuts =
|
||||
mShortcutManager.queryForPinnedShortcuts(null, user);
|
||||
QueryResult pinnedShortcuts = new ShortcutRequest(context, user)
|
||||
.query(ShortcutRequest.PINNED);
|
||||
if (pinnedShortcuts.wasSuccess()) {
|
||||
for (ShortcutInfo shortcut : pinnedShortcuts) {
|
||||
shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
|
||||
|
@ -786,7 +786,7 @@ public class LoaderTask implements Runnable {
|
|||
if ((numTimesPinned == null || numTimesPinned.value == 0)
|
||||
&& !pendingShortcuts.contains(key)) {
|
||||
// Shortcut is pinned but doesn't exist on the workspace; unpin it.
|
||||
mShortcutManager.unpinShortcut(key);
|
||||
mBgDataModel.unpinShortcut(context, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -884,12 +884,12 @@ public class LoaderTask implements Runnable {
|
|||
private List<ShortcutInfo> loadDeepShortcuts() {
|
||||
List<ShortcutInfo> allShortcuts = new ArrayList<>();
|
||||
mBgDataModel.deepShortcutMap.clear();
|
||||
mBgDataModel.hasShortcutHostPermission = mShortcutManager.hasHostPermission();
|
||||
mBgDataModel.hasShortcutHostPermission = hasShortcutsPermission(mApp.getContext());
|
||||
if (mBgDataModel.hasShortcutHostPermission) {
|
||||
for (UserHandle user : mUserCache.getUserProfiles()) {
|
||||
if (mUserManager.isUserUnlocked(user)) {
|
||||
List<ShortcutInfo> shortcuts =
|
||||
mShortcutManager.queryForAllShortcuts(user);
|
||||
List<ShortcutInfo> shortcuts = new ShortcutRequest(mApp.getContext(), user)
|
||||
.query(ShortcutRequest.ALL);
|
||||
allShortcuts.addAll(shortcuts);
|
||||
mBgDataModel.updateDeepShortcutCounts(null, user, shortcuts);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ import com.android.launcher3.icons.BitmapInfo;
|
|||
import com.android.launcher3.icons.IconCache;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.logging.FileLog;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.util.FlagOp;
|
||||
import com.android.launcher3.util.IntSparseArrayMap;
|
||||
|
@ -208,10 +208,11 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
|
|||
if (si.isPromise() && isNewApkAvailable) {
|
||||
boolean isTargetValid = true;
|
||||
if (si.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
|
||||
List<ShortcutInfo> shortcut = DeepShortcutManager
|
||||
.getInstance(context).queryForPinnedShortcuts(
|
||||
cn.getPackageName(),
|
||||
Arrays.asList(si.getDeepShortcutId()), mUser);
|
||||
List<ShortcutInfo> shortcut =
|
||||
new ShortcutRequest(context, mUser)
|
||||
.forPackage(cn.getPackageName(),
|
||||
si.getDeepShortcutId())
|
||||
.query(ShortcutRequest.PINNED);
|
||||
if (shortcut.isEmpty()) {
|
||||
isTargetValid = false;
|
||||
} else {
|
||||
|
|
|
@ -24,8 +24,8 @@ import com.android.launcher3.LauncherAppState;
|
|||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.MultiHashMap;
|
||||
|
||||
|
@ -54,8 +54,6 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask {
|
|||
@Override
|
||||
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
|
||||
final Context context = app.getContext();
|
||||
DeepShortcutManager deepShortcutManager = DeepShortcutManager.getInstance(context);
|
||||
|
||||
// Find WorkspaceItemInfo's that have changed on the workspace.
|
||||
HashSet<ShortcutKey> removedKeys = new HashSet<>();
|
||||
MultiHashMap<ShortcutKey, WorkspaceItemInfo> keyToShortcutInfo = new MultiHashMap<>();
|
||||
|
@ -74,8 +72,9 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask {
|
|||
final ArrayList<WorkspaceItemInfo> updatedWorkspaceItemInfos = new ArrayList<>();
|
||||
if (!keyToShortcutInfo.isEmpty()) {
|
||||
// Update the workspace to reflect the changes to updated shortcuts residing on it.
|
||||
List<ShortcutInfo> shortcuts = deepShortcutManager.queryForFullDetails(
|
||||
mPackageName, new ArrayList<>(allIds), mUser);
|
||||
List<ShortcutInfo> shortcuts = new ShortcutRequest(context, mUser)
|
||||
.forPackage(mPackageName, new ArrayList<>(allIds))
|
||||
.query(ShortcutRequest.ALL);
|
||||
for (ShortcutInfo fullDetails : shortcuts) {
|
||||
ShortcutKey key = ShortcutKey.fromInfo(fullDetails);
|
||||
List<WorkspaceItemInfo> workspaceItemInfos = keyToShortcutInfo.remove(key);
|
||||
|
|
|
@ -27,8 +27,9 @@ import com.android.launcher3.LauncherAppState;
|
|||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest.QueryResult;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
|
||||
|
@ -52,12 +53,11 @@ public class UserLockStateChangedTask extends BaseModelUpdateTask {
|
|||
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
|
||||
Context context = app.getContext();
|
||||
boolean isUserUnlocked = context.getSystemService(UserManager.class).isUserUnlocked(mUser);
|
||||
DeepShortcutManager deepShortcutManager = DeepShortcutManager.getInstance(context);
|
||||
|
||||
HashMap<ShortcutKey, ShortcutInfo> pinnedShortcuts = new HashMap<>();
|
||||
if (isUserUnlocked) {
|
||||
DeepShortcutManager.QueryResult shortcuts =
|
||||
deepShortcutManager.queryForPinnedShortcuts(null, mUser);
|
||||
QueryResult shortcuts = new ShortcutRequest(context, mUser)
|
||||
.query(ShortcutRequest.PINNED);
|
||||
if (shortcuts.wasSuccess()) {
|
||||
for (ShortcutInfo shortcut : shortcuts) {
|
||||
pinnedShortcuts.put(ShortcutKey.fromInfo(shortcut), shortcut);
|
||||
|
@ -115,7 +115,8 @@ public class UserLockStateChangedTask extends BaseModelUpdateTask {
|
|||
|
||||
if (isUserUnlocked) {
|
||||
dataModel.updateDeepShortcutCounts(
|
||||
null, mUser, deepShortcutManager.queryForAllShortcuts(mUser));
|
||||
null, mUser,
|
||||
new ShortcutRequest(context, mUser).query(ShortcutRequest.ALL));
|
||||
}
|
||||
bindDeepShortcuts(dataModel);
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ import com.android.launcher3.icons.LauncherIcons;
|
|||
import com.android.launcher3.notification.NotificationInfo;
|
||||
import com.android.launcher3.notification.NotificationKeyData;
|
||||
import com.android.launcher3.notification.NotificationListener;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutView;
|
||||
import com.android.launcher3.shortcuts.ShortcutRequest;
|
||||
import com.android.launcher3.util.PackageUserKey;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -144,8 +144,9 @@ public class PopupPopulator {
|
|||
uiHandler.post(() -> container.applyNotificationInfos(infos));
|
||||
}
|
||||
|
||||
List<ShortcutInfo> shortcuts = DeepShortcutManager.getInstance(launcher)
|
||||
.queryForShortcutsContainer(activity, user);
|
||||
List<ShortcutInfo> shortcuts = new ShortcutRequest(launcher, user)
|
||||
.withContainer(activity)
|
||||
.query(ShortcutRequest.PUBLISHED);
|
||||
String shortcutIdToDeDupe = notificationKeys.isEmpty() ? null
|
||||
: notificationKeys.get(0).shortcutId;
|
||||
shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts, shortcutIdToDeDupe);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.android.launcher3.shortcuts;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.UserHandle;
|
||||
|
@ -29,6 +30,14 @@ public class ShortcutKey extends ComponentKey {
|
|||
return componentName.getClassName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link ShortcutRequest} for this key
|
||||
*/
|
||||
public ShortcutRequest buildRequest(Context context) {
|
||||
return new ShortcutRequest(context, user)
|
||||
.forPackage(componentName.getPackageName(), getId());
|
||||
}
|
||||
|
||||
public static ShortcutKey fromInfo(ShortcutInfo shortcutInfo) {
|
||||
return new ShortcutKey(shortcutInfo.getPackage(), shortcutInfo.getUserHandle(),
|
||||
shortcutInfo.getId());
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2020 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.shortcuts;
|
||||
|
||||
import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.LauncherApps.ShortcutQuery;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class to streamline Shortcut query
|
||||
*/
|
||||
public class ShortcutRequest {
|
||||
|
||||
private static final String TAG = "ShortcutRequest";
|
||||
|
||||
public static final int ALL = ShortcutQuery.FLAG_MATCH_DYNAMIC
|
||||
| ShortcutQuery.FLAG_MATCH_MANIFEST | ShortcutQuery.FLAG_MATCH_PINNED;
|
||||
public static final int PUBLISHED = ShortcutQuery.FLAG_MATCH_DYNAMIC
|
||||
| ShortcutQuery.FLAG_MATCH_MANIFEST;
|
||||
public static final int PINNED = ShortcutQuery.FLAG_MATCH_PINNED;
|
||||
|
||||
private final ShortcutQuery mQuery = GO_DISABLE_WIDGETS ? null : new ShortcutQuery();
|
||||
|
||||
private final Context mContext;
|
||||
private final UserHandle mUserHandle;
|
||||
|
||||
boolean mFailed = false;
|
||||
|
||||
public ShortcutRequest(Context context, UserHandle userHandle) {
|
||||
mContext = context;
|
||||
mUserHandle = userHandle;
|
||||
}
|
||||
|
||||
public ShortcutRequest forPackage(String packageName, String... shortcutIds) {
|
||||
return forPackage(packageName, Arrays.asList(shortcutIds));
|
||||
}
|
||||
|
||||
public ShortcutRequest forPackage(String packageName, @Nullable List<String> shortcutIds) {
|
||||
if (!GO_DISABLE_WIDGETS && packageName != null) {
|
||||
mQuery.setPackage(packageName);
|
||||
mQuery.setShortcutIds(shortcutIds);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ShortcutRequest withContainer(@Nullable ComponentName activity) {
|
||||
if (!GO_DISABLE_WIDGETS) {
|
||||
if (activity == null) {
|
||||
mFailed = true;
|
||||
} else {
|
||||
mQuery.setActivity(activity);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryResult query(int flags) {
|
||||
if (GO_DISABLE_WIDGETS || mFailed) {
|
||||
return QueryResult.DEFAULT;
|
||||
}
|
||||
mQuery.setQueryFlags(flags);
|
||||
|
||||
try {
|
||||
return new QueryResult(mContext.getSystemService(LauncherApps.class)
|
||||
.getShortcuts(mQuery, mUserHandle));
|
||||
} catch (SecurityException | IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to query for shortcuts", e);
|
||||
return QueryResult.DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public static class QueryResult extends ArrayList<ShortcutInfo> {
|
||||
|
||||
static final QueryResult DEFAULT = new QueryResult(GO_DISABLE_WIDGETS);
|
||||
|
||||
private final boolean mWasSuccess;
|
||||
|
||||
QueryResult(List<ShortcutInfo> result) {
|
||||
super(result == null ? Collections.emptyList() : result);
|
||||
mWasSuccess = true;
|
||||
}
|
||||
|
||||
QueryResult(boolean wasSuccess) {
|
||||
mWasSuccess = wasSuccess;
|
||||
}
|
||||
|
||||
|
||||
public boolean wasSuccess() {
|
||||
return mWasSuccess;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -332,4 +332,17 @@ public class PackageManagerHelper {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Launcher has the permission to access shortcuts.
|
||||
* @see LauncherApps#hasShortcutHostPermission()
|
||||
*/
|
||||
public static boolean hasShortcutsPermission(Context context) {
|
||||
try {
|
||||
return context.getSystemService(LauncherApps.class).hasShortcutHostPermission();
|
||||
} catch (SecurityException | IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to make shortcut manager call", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
* 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.shortcuts;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.LauncherApps.ShortcutQuery;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Performs operations related to deep shortcuts, such as querying for them, pinning them, etc.
|
||||
*/
|
||||
public class DeepShortcutManager {
|
||||
private static final String TAG = "DeepShortcutManager";
|
||||
|
||||
private static final int FLAG_GET_ALL = ShortcutQuery.FLAG_MATCH_DYNAMIC
|
||||
| ShortcutQuery.FLAG_MATCH_MANIFEST | ShortcutQuery.FLAG_MATCH_PINNED;
|
||||
|
||||
private static DeepShortcutManager sInstance;
|
||||
|
||||
public static DeepShortcutManager getInstance(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new DeepShortcutManager(context.getApplicationContext());
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private final LauncherApps mLauncherApps;
|
||||
|
||||
private DeepShortcutManager(Context context) {
|
||||
mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for the shortcuts with the package name and provided ids.
|
||||
*
|
||||
* This method is intended to get the full details for shortcuts when they are added or updated,
|
||||
* because we only get "key" fields in onShortcutsChanged().
|
||||
*/
|
||||
public QueryResult queryForFullDetails(String packageName,
|
||||
List<String> shortcutIds, UserHandle user) {
|
||||
return query(FLAG_GET_ALL, packageName, null, shortcutIds, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the manifest and dynamic shortcuts associated with the given package and user,
|
||||
* to be displayed in the shortcuts container on long press.
|
||||
*/
|
||||
public QueryResult queryForShortcutsContainer(@Nullable ComponentName activity,
|
||||
UserHandle user) {
|
||||
if (activity == null) return QueryResult.FAILURE;
|
||||
return query(ShortcutQuery.FLAG_MATCH_MANIFEST | ShortcutQuery.FLAG_MATCH_DYNAMIC,
|
||||
activity.getPackageName(), activity, null, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given shortcut from the current list of pinned shortcuts.
|
||||
* (Runs on background thread)
|
||||
*/
|
||||
public void unpinShortcut(final ShortcutKey key) {
|
||||
String packageName = key.componentName.getPackageName();
|
||||
String id = key.getId();
|
||||
UserHandle user = key.user;
|
||||
List<String> pinnedIds = extractIds(queryForPinnedShortcuts(packageName, user));
|
||||
pinnedIds.remove(id);
|
||||
try {
|
||||
mLauncherApps.pinShortcuts(packageName, pinnedIds, user);
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.w(TAG, "Failed to unpin shortcut", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given shortcut to the current list of pinned shortcuts.
|
||||
* (Runs on background thread)
|
||||
*/
|
||||
public void pinShortcut(final ShortcutKey key) {
|
||||
String packageName = key.componentName.getPackageName();
|
||||
String id = key.getId();
|
||||
UserHandle user = key.user;
|
||||
List<String> pinnedIds = extractIds(queryForPinnedShortcuts(packageName, user));
|
||||
pinnedIds.add(id);
|
||||
try {
|
||||
mLauncherApps.pinShortcuts(packageName, pinnedIds, user);
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.w(TAG, "Failed to pin shortcut", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void startShortcut(String packageName, String id, Rect sourceBounds,
|
||||
Bundle startActivityOptions, UserHandle user) {
|
||||
try {
|
||||
mLauncherApps.startShortcut(packageName, id, sourceBounds,
|
||||
startActivityOptions, user);
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to start shortcut", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Drawable getShortcutIconDrawable(ShortcutInfo shortcutInfo, int density) {
|
||||
try {
|
||||
return mLauncherApps.getShortcutIconDrawable(shortcutInfo, density);
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to get shortcut icon", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id's of pinned shortcuts associated with the given package and user.
|
||||
*
|
||||
* If packageName is null, returns all pinned shortcuts regardless of package.
|
||||
*/
|
||||
public QueryResult queryForPinnedShortcuts(String packageName, UserHandle user) {
|
||||
return queryForPinnedShortcuts(packageName, null, user);
|
||||
}
|
||||
|
||||
public QueryResult queryForPinnedShortcuts(String packageName, List<String> shortcutIds,
|
||||
UserHandle user) {
|
||||
return query(ShortcutQuery.FLAG_MATCH_PINNED, packageName, null, shortcutIds, user);
|
||||
}
|
||||
|
||||
public QueryResult queryForAllShortcuts(UserHandle user) {
|
||||
return query(FLAG_GET_ALL, null, null, null, user);
|
||||
}
|
||||
|
||||
private static List<String> extractIds(List<ShortcutInfo> shortcuts) {
|
||||
List<String> shortcutIds = new ArrayList<>(shortcuts.size());
|
||||
for (ShortcutInfo shortcut : shortcuts) {
|
||||
shortcutIds.add(shortcut.getId());
|
||||
}
|
||||
return shortcutIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the system server for all the shortcuts matching the given parameters.
|
||||
* If packageName == null, we query for all shortcuts with the passed flags, regardless of app.
|
||||
*
|
||||
* TODO: Use the cache to optimize this so we don't make an RPC every time.
|
||||
*/
|
||||
private QueryResult query(int flags, String packageName, ComponentName activity,
|
||||
List<String> shortcutIds, UserHandle user) {
|
||||
ShortcutQuery q = new ShortcutQuery();
|
||||
q.setQueryFlags(flags);
|
||||
if (packageName != null) {
|
||||
q.setPackage(packageName);
|
||||
q.setActivity(activity);
|
||||
q.setShortcutIds(shortcutIds);
|
||||
}
|
||||
try {
|
||||
return new QueryResult(mLauncherApps.getShortcuts(q, user));
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to query for shortcuts", e);
|
||||
return QueryResult.FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasHostPermission() {
|
||||
try {
|
||||
return mLauncherApps.hasShortcutHostPermission();
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to make shortcut manager call", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class QueryResult extends ArrayList<ShortcutInfo> {
|
||||
|
||||
static QueryResult FAILURE = new QueryResult();
|
||||
|
||||
private final boolean mWasSuccess;
|
||||
|
||||
QueryResult(List<ShortcutInfo> result) {
|
||||
super(result == null ? Collections.emptyList() : result);
|
||||
mWasSuccess = true;
|
||||
}
|
||||
|
||||
QueryResult() {
|
||||
mWasSuccess = false;
|
||||
}
|
||||
|
||||
|
||||
public boolean wasSuccess() {
|
||||
return mWasSuccess;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue