update:2021.03.19
fix:重新提交 add:
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.uiuios.model;
|
||||
|
||||
import com.android.uiuios.AllAppsList;
|
||||
import com.android.uiuios.LauncherAppState;
|
||||
import com.android.uiuios.LauncherModel.Callbacks;
|
||||
import com.android.uiuios.util.ComponentKey;
|
||||
import com.android.uiuios.widget.WidgetListRowEntry;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Helper class to handle results of {@link com.android.uiuios.model.LoaderTask}.
|
||||
*/
|
||||
public class LoaderResults extends BaseLoaderResults {
|
||||
|
||||
public LoaderResults(LauncherAppState app, BgDataModel dataModel,
|
||||
AllAppsList allAppsList, int pageToBindFirst, WeakReference<Callbacks> callbacks) {
|
||||
super(app, dataModel, allAppsList, pageToBindFirst, callbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindDeepShortcuts() {
|
||||
final HashMap<ComponentKey, Integer> shortcutMapCopy;
|
||||
synchronized (mBgDataModel) {
|
||||
shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap);
|
||||
}
|
||||
executeCallbacksTask(c -> c.bindDeepShortcutMap(shortcutMapCopy), mUiExecutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindWidgets() {
|
||||
final ArrayList<WidgetListRowEntry> widgets =
|
||||
mBgDataModel.widgetsModel.getWidgetsList(mApp.getContext());
|
||||
executeCallbacksTask(c -> c.bindAllWidgets(widgets), mUiExecutor);
|
||||
}
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
|
||||
package com.android.uiuios.model;
|
||||
|
||||
import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_HIDE_FROM_PICKER;
|
||||
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.uiuios.AppFilter;
|
||||
import com.android.uiuios.icons.ComponentWithLabel;
|
||||
import com.android.uiuios.icons.IconCache;
|
||||
import com.android.uiuios.InvariantDeviceProfile;
|
||||
import com.android.uiuios.LauncherAppState;
|
||||
import com.android.uiuios.LauncherAppWidgetProviderInfo;
|
||||
import com.android.uiuios.Utilities;
|
||||
import com.android.uiuios.compat.AlphabeticIndexCompat;
|
||||
import com.android.uiuios.compat.AppWidgetManagerCompat;
|
||||
import com.android.uiuios.compat.LauncherAppsCompat;
|
||||
import com.android.uiuios.compat.ShortcutConfigActivityInfo;
|
||||
import com.android.uiuios.config.FeatureFlags;
|
||||
import com.android.uiuios.util.MultiHashMap;
|
||||
import com.android.uiuios.util.PackageUserKey;
|
||||
import com.android.uiuios.util.Preconditions;
|
||||
import com.android.uiuios.widget.WidgetItemComparator;
|
||||
import com.android.uiuios.widget.WidgetListRowEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Widgets data model that is used by the adapters of the widget views and controllers.
|
||||
*
|
||||
* <p> The widgets and shortcuts are organized using package name as its index.
|
||||
*/
|
||||
public class WidgetsModel {
|
||||
|
||||
private static final String TAG = "WidgetsModel";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
/* Map of widgets and shortcuts that are tracked per package. */
|
||||
private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList = new MultiHashMap<>();
|
||||
|
||||
private AppFilter mAppFilter;
|
||||
|
||||
/**
|
||||
* Returns a list of {@link WidgetListRowEntry}. All {@link WidgetItem} in a single row
|
||||
* are sorted (based on label and user), but the overall list of {@link WidgetListRowEntry}s
|
||||
* is not sorted. This list is sorted at the UI when using
|
||||
* {@link com.android.uiuios.widget.WidgetsDiffReporter}
|
||||
*
|
||||
* @see com.android.uiuios.widget.WidgetsListAdapter#setWidgets(ArrayList)
|
||||
*/
|
||||
public synchronized ArrayList<WidgetListRowEntry> getWidgetsList(Context context) {
|
||||
ArrayList<WidgetListRowEntry> result = new ArrayList<>();
|
||||
AlphabeticIndexCompat indexer = new AlphabeticIndexCompat(context);
|
||||
|
||||
WidgetItemComparator widgetComparator = new WidgetItemComparator();
|
||||
for (Map.Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : mWidgetsList.entrySet()) {
|
||||
WidgetListRowEntry row = new WidgetListRowEntry(entry.getKey(), entry.getValue());
|
||||
row.titleSectionName = (row.pkgItem.title == null) ? "" :
|
||||
indexer.computeSectionName(row.pkgItem.title);
|
||||
Collections.sort(row.widgets, widgetComparator);
|
||||
result.add(row);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
|
||||
* only widgets and shortcuts associated with the package/user are.
|
||||
*/
|
||||
public List<ComponentWithLabel> update(LauncherAppState app, @Nullable PackageUserKey packageUser) {
|
||||
Preconditions.assertWorkerThread();
|
||||
|
||||
Context context = app.getContext();
|
||||
final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
|
||||
List<ComponentWithLabel> updatedItems = new ArrayList<>();
|
||||
try {
|
||||
InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
|
||||
PackageManager pm = app.getContext().getPackageManager();
|
||||
|
||||
// Widgets
|
||||
AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(context);
|
||||
for (AppWidgetProviderInfo widgetInfo : widgetManager.getAllProviders(packageUser)) {
|
||||
LauncherAppWidgetProviderInfo launcherWidgetInfo =
|
||||
LauncherAppWidgetProviderInfo.fromProviderInfo(context, widgetInfo);
|
||||
|
||||
widgetsAndShortcuts.add(new WidgetItem(
|
||||
launcherWidgetInfo, idp, app.getIconCache()));
|
||||
updatedItems.add(launcherWidgetInfo);
|
||||
}
|
||||
|
||||
// Shortcuts
|
||||
for (ShortcutConfigActivityInfo info : LauncherAppsCompat.getInstance(context)
|
||||
.getCustomShortcutActivityList(packageUser)) {
|
||||
widgetsAndShortcuts.add(new WidgetItem(info, app.getIconCache(), pm));
|
||||
updatedItems.add(info);
|
||||
}
|
||||
setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser);
|
||||
} catch (Exception e) {
|
||||
if (!FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isBinderSizeError(e)) {
|
||||
// the returned value may be incomplete and will not be refreshed until the next
|
||||
// time Launcher starts.
|
||||
// TODO: after figuring out a repro step, introduce a dirty bit to check when
|
||||
// onResume is called to refresh the widget provider list.
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
app.getWidgetCache().removeObsoletePreviews(widgetsAndShortcuts, packageUser);
|
||||
return updatedItems;
|
||||
}
|
||||
|
||||
private synchronized void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
|
||||
LauncherAppState app, @Nullable PackageUserKey packageUser) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
|
||||
}
|
||||
|
||||
// Temporary list for {@link PackageItemInfos} to avoid having to go through
|
||||
// {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList}
|
||||
HashMap<String, PackageItemInfo> tmpPackageItemInfos = new HashMap<>();
|
||||
|
||||
// clear the lists.
|
||||
if (packageUser == null) {
|
||||
mWidgetsList.clear();
|
||||
} else {
|
||||
// Only clear the widgets for the given package/user.
|
||||
PackageItemInfo packageItem = null;
|
||||
for (PackageItemInfo item : mWidgetsList.keySet()) {
|
||||
if (item.packageName.equals(packageUser.mPackageName)) {
|
||||
packageItem = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (packageItem != null) {
|
||||
// We want to preserve the user that was on the packageItem previously,
|
||||
// so add it to tmpPackageItemInfos here to avoid creating a new entry.
|
||||
tmpPackageItemInfos.put(packageItem.packageName, packageItem);
|
||||
|
||||
Iterator<WidgetItem> widgetItemIterator = mWidgetsList.get(packageItem).iterator();
|
||||
while (widgetItemIterator.hasNext()) {
|
||||
WidgetItem nextWidget = widgetItemIterator.next();
|
||||
if (nextWidget.componentName.getPackageName().equals(packageUser.mPackageName)
|
||||
&& nextWidget.user.equals(packageUser.mUser)) {
|
||||
widgetItemIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
|
||||
UserHandle myUser = Process.myUserHandle();
|
||||
|
||||
// add and update.
|
||||
for (WidgetItem item : rawWidgetsShortcuts) {
|
||||
if (item.widgetInfo != null) {
|
||||
if ((item.widgetInfo.getWidgetFeatures() & WIDGET_FEATURE_HIDE_FROM_PICKER) != 0) {
|
||||
// Widget is hidden from picker
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ensure that all widgets we show can be added on a workspace of this size
|
||||
int minSpanX = Math.min(item.widgetInfo.spanX, item.widgetInfo.minSpanX);
|
||||
int minSpanY = Math.min(item.widgetInfo.spanY, item.widgetInfo.minSpanY);
|
||||
if (minSpanX > idp.numColumns || minSpanY > idp.numRows) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format(
|
||||
"Widget %s : (%d X %d) can't fit on this device",
|
||||
item.componentName, minSpanX, minSpanY));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (mAppFilter == null) {
|
||||
mAppFilter = AppFilter.newInstance(app.getContext());
|
||||
}
|
||||
if (!mAppFilter.shouldShowApp(item.componentName)) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format("%s is filtered and not added to the widget tray.",
|
||||
item.componentName));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
String packageName = item.componentName.getPackageName();
|
||||
PackageItemInfo pInfo = tmpPackageItemInfos.get(packageName);
|
||||
if (pInfo == null) {
|
||||
pInfo = new PackageItemInfo(packageName);
|
||||
pInfo.user = item.user;
|
||||
tmpPackageItemInfos.put(packageName, pInfo);
|
||||
} else if (!myUser.equals(pInfo.user)) {
|
||||
// Keep updating the user, until we get the primary user.
|
||||
pInfo.user = item.user;
|
||||
}
|
||||
mWidgetsList.addToList(pInfo, item);
|
||||
}
|
||||
|
||||
// Update each package entry
|
||||
IconCache iconCache = app.getIconCache();
|
||||
for (PackageItemInfo p : tmpPackageItemInfos.values()) {
|
||||
iconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
|
||||
}
|
||||
}
|
||||
|
||||
public void onPackageIconsUpdated(Set<String> packageNames, UserHandle user,
|
||||
LauncherAppState app) {
|
||||
for (Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : mWidgetsList.entrySet()) {
|
||||
if (packageNames.contains(entry.getKey().packageName)) {
|
||||
ArrayList<WidgetItem> items = entry.getValue();
|
||||
int count = items.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
WidgetItem item = items.get(i);
|
||||
if (item.user.equals(user)) {
|
||||
if (item.activityInfo != null) {
|
||||
items.set(i, new WidgetItem(item.activityInfo, app.getIconCache(),
|
||||
app.getContext().getPackageManager()));
|
||||
} else {
|
||||
items.set(i, new WidgetItem(item.widgetInfo,
|
||||
app.getInvariantDeviceProfile(), app.getIconCache()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,223 +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.uiuios.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 com.android.uiuios.ItemInfo;
|
||||
import com.android.uiuios.LauncherSettings;
|
||||
import com.android.uiuios.WorkspaceItemInfo;
|
||||
|
||||
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;
|
||||
private static final Object sInstanceLock = new Object();
|
||||
|
||||
public static DeepShortcutManager getInstance(Context context) {
|
||||
synchronized (sInstanceLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new DeepShortcutManager(context.getApplicationContext());
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
|
||||
private final LauncherApps mLauncherApps;
|
||||
private boolean mWasLastCallSuccess;
|
||||
|
||||
private DeepShortcutManager(Context context) {
|
||||
mLauncherApps = (LauncherApps) context.getSystemService(Context.LAUNCHER_APPS_SERVICE);
|
||||
}
|
||||
|
||||
public static boolean supportsShortcuts(ItemInfo info) {
|
||||
boolean isItemPromise = info instanceof WorkspaceItemInfo
|
||||
&& ((WorkspaceItemInfo) info).hasPromiseIconUi();
|
||||
return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
|
||||
&& !info.isDisabled() && !isItemPromise;
|
||||
}
|
||||
|
||||
public boolean wasLastCallSuccess() {
|
||||
return mWasLastCallSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 List<ShortcutInfo> 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 List<ShortcutInfo> queryForShortcutsContainer(ComponentName activity,
|
||||
UserHandle user) {
|
||||
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);
|
||||
mWasLastCallSuccess = true;
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.w(TAG, "Failed to unpin shortcut", e);
|
||||
mWasLastCallSuccess = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
mWasLastCallSuccess = true;
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.w(TAG, "Failed to pin shortcut", e);
|
||||
mWasLastCallSuccess = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void startShortcut(String packageName, String id, Rect sourceBounds,
|
||||
Bundle startActivityOptions, UserHandle user) {
|
||||
try {
|
||||
mLauncherApps.startShortcut(packageName, id, sourceBounds,
|
||||
startActivityOptions, user);
|
||||
mWasLastCallSuccess = true;
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to start shortcut", e);
|
||||
mWasLastCallSuccess = false;
|
||||
}
|
||||
}
|
||||
|
||||
public Drawable getShortcutIconDrawable(ShortcutInfo shortcutInfo, int density) {
|
||||
try {
|
||||
Drawable icon = mLauncherApps.getShortcutIconDrawable(shortcutInfo, density);
|
||||
mWasLastCallSuccess = true;
|
||||
return icon;
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to get shortcut icon", e);
|
||||
mWasLastCallSuccess = false;
|
||||
}
|
||||
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 List<ShortcutInfo> queryForPinnedShortcuts(String packageName, UserHandle user) {
|
||||
return queryForPinnedShortcuts(packageName, null, user);
|
||||
}
|
||||
|
||||
public List<ShortcutInfo> queryForPinnedShortcuts(String packageName,
|
||||
List<String> shortcutIds, UserHandle user) {
|
||||
return query(ShortcutQuery.FLAG_MATCH_PINNED, packageName, null, shortcutIds, user);
|
||||
}
|
||||
|
||||
public List<ShortcutInfo> queryForAllShortcuts(UserHandle user) {
|
||||
return query(FLAG_GET_ALL, null, null, null, user);
|
||||
}
|
||||
|
||||
private 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 List<ShortcutInfo> 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);
|
||||
}
|
||||
List<ShortcutInfo> shortcutInfos = null;
|
||||
try {
|
||||
shortcutInfos = mLauncherApps.getShortcuts(q, user);
|
||||
mWasLastCallSuccess = true;
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to query for shortcuts", e);
|
||||
mWasLastCallSuccess = false;
|
||||
}
|
||||
if (shortcutInfos == null) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
return shortcutInfos;
|
||||
}
|
||||
|
||||
public boolean hasHostPermission() {
|
||||
try {
|
||||
return mLauncherApps.hasShortcutHostPermission();
|
||||
} catch (SecurityException|IllegalStateException e) {
|
||||
Log.e(TAG, "Failed to make shortcut manager call", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user