下面列出了android.content.pm.ShortcutInfo#isVisibleToPublisher() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Remove all dynamic shortcuts.
*/
public void deleteAllDynamicShortcuts(boolean ignoreInvisible) {
final long now = mShortcutUser.mService.injectCurrentTimeMillis();
boolean changed = false;
for (int i = mShortcuts.size() - 1; i >= 0; i--) {
final ShortcutInfo si = mShortcuts.valueAt(i);
if (si.isDynamic() && (!ignoreInvisible || si.isVisibleToPublisher())) {
changed = true;
si.setTimestamp(now);
si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
si.setRank(0); // It may still be pinned, so clear the rank.
}
}
if (changed) {
removeOrphans();
}
}
private void ensureNotImmutable(@Nullable ShortcutInfo shortcut, boolean ignoreInvisible) {
if (shortcut != null && shortcut.isImmutable()
&& (!ignoreInvisible || shortcut.isVisibleToPublisher())) {
throw new IllegalArgumentException(
"Manifest shortcut ID=" + shortcut.getId()
+ " may not be manipulated via APIs");
}
}
@Nullable
private ShortcutInfo deleteOrDisableWithId(@NonNull String shortcutId, boolean disable,
boolean overrideImmutable, boolean ignoreInvisible, int disabledReason) {
Preconditions.checkState(
(disable == (disabledReason != ShortcutInfo.DISABLED_REASON_NOT_DISABLED)),
"disable and disabledReason disagree: " + disable + " vs " + disabledReason);
final ShortcutInfo oldShortcut = mShortcuts.get(shortcutId);
if (oldShortcut == null || !oldShortcut.isEnabled()
&& (ignoreInvisible && !oldShortcut.isVisibleToPublisher())) {
return null; // Doesn't exist or already disabled.
}
if (!overrideImmutable) {
ensureNotImmutable(oldShortcut, /*ignoreInvisible=*/ true);
}
if (oldShortcut.isPinned()) {
oldShortcut.setRank(0);
oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST);
if (disable) {
oldShortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
// Do not overwrite the disabled reason if one is alreay set.
if (oldShortcut.getDisabledReason() == ShortcutInfo.DISABLED_REASON_NOT_DISABLED) {
oldShortcut.setDisabledReason(disabledReason);
}
}
oldShortcut.setTimestamp(mShortcutUser.mService.injectCurrentTimeMillis());
// See ShortcutRequestPinProcessor.directPinShortcut().
if (mShortcutUser.mService.isDummyMainActivity(oldShortcut.getActivity())) {
oldShortcut.setActivity(null);
}
return oldShortcut;
} else {
forceDeleteShortcutInner(shortcutId);
return null;
}
}
/**
* Handle {@link android.content.pm.ShortcutManager#requestPinShortcut)}.
*/
@NonNull
private PinItemRequest requestPinShortcutLocked(ShortcutInfo inShortcut,
IntentSender resultIntentOriginal, Pair<ComponentName, Integer> confirmActivity) {
final ShortcutPackage ps = mService.getPackageShortcutsForPublisherLocked(
inShortcut.getPackage(), inShortcut.getUserId());
final ShortcutInfo existing = ps.findShortcutById(inShortcut.getId());
final boolean existsAlready = existing != null;
final boolean existingIsVisible = existsAlready && existing.isVisibleToPublisher();
if (DEBUG) {
Slog.d(TAG, "requestPinnedShortcut: package=" + inShortcut.getPackage()
+ " existsAlready=" + existsAlready
+ " existingIsVisible=" + existingIsVisible
+ " shortcut=" + inShortcut.toInsecureString());
}
// This is the shortcut that'll be sent to the launcher.
final ShortcutInfo shortcutForLauncher;
final String launcherPackage = confirmActivity.first.getPackageName();
final int launcherUserId = confirmActivity.second;
IntentSender resultIntentToSend = resultIntentOriginal;
if (existsAlready) {
validateExistingShortcut(existing);
final boolean isAlreadyPinned = mService.getLauncherShortcutsLocked(
launcherPackage, existing.getUserId(), launcherUserId).hasPinned(existing);
if (isAlreadyPinned) {
// When the shortcut is already pinned by this launcher, the request will always
// succeed, so just send the result at this point.
sendResultIntent(resultIntentOriginal, null);
// So, do not send the intent again.
resultIntentToSend = null;
}
// Pass a clone, not the original.
// Note this will remove the intent and icons.
shortcutForLauncher = existing.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
if (!isAlreadyPinned) {
// FLAG_PINNED may still be set, if it's pinned by other launchers.
shortcutForLauncher.clearFlags(ShortcutInfo.FLAG_PINNED);
}
} else {
// If the shortcut has no default activity, try to set the main activity.
// But in the request-pin case, it's optional, so it's okay even if the caller
// has no default activity.
if (inShortcut.getActivity() == null) {
inShortcut.setActivity(mService.injectGetDefaultMainActivity(
inShortcut.getPackage(), inShortcut.getUserId()));
}
// It doesn't exist, so it must have all mandatory fields.
mService.validateShortcutForPinRequest(inShortcut);
// Initialize the ShortcutInfo for pending approval.
inShortcut.resolveResourceStrings(mService.injectGetResourcesForApplicationAsUser(
inShortcut.getPackage(), inShortcut.getUserId()));
if (DEBUG) {
Slog.d(TAG, "Resolved shortcut=" + inShortcut.toInsecureString());
}
// We should strip out the intent, but should preserve the icon.
shortcutForLauncher = inShortcut.clone(
ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER_APPROVAL);
}
if (DEBUG) {
Slog.d(TAG, "Sending to launcher=" + shortcutForLauncher.toInsecureString());
}
// Create a request object.
final PinShortcutRequestInner inner =
new PinShortcutRequestInner(this, inShortcut, shortcutForLauncher,
resultIntentToSend, launcherPackage, launcherUserId,
mService.injectGetPackageUid(launcherPackage, launcherUserId),
existsAlready);
return new PinItemRequest(inner, PinItemRequest.REQUEST_TYPE_SHORTCUT);
}
public boolean isShortcutExistsAndInvisibleToPublisher(String id) {
ShortcutInfo si = findShortcutById(id);
return si != null && !si.isVisibleToPublisher();
}
public boolean isShortcutExistsAndVisibleToPublisher(String id) {
ShortcutInfo si = findShortcutById(id);
return si != null && si.isVisibleToPublisher();
}
@Override
public boolean updateShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
verifyShortcutInfoPackages(packageName, newShortcuts);
final int size = newShortcuts.size();
final boolean unlimited = injectHasUnlimitedShortcutsApiCallsPermission(
injectBinderCallingPid(), injectBinderCallingUid());
synchronized (mLock) {
throwIfUserLockedL(userId);
final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
ps.ensureImmutableShortcutsNotIncluded(newShortcuts, /*ignoreInvisible=*/ true);
// For update, don't fill in the default activity. Having null activity means
// "don't update the activity" here.
ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE);
// Throttling.
if (!ps.tryApiCall(unlimited)) {
return false;
}
// Initialize the implicit ranks for ShortcutPackage.adjustRanks().
ps.clearAllImplicitRanks();
assignImplicitRanks(newShortcuts);
for (int i = 0; i < size; i++) {
final ShortcutInfo source = newShortcuts.get(i);
fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);
final ShortcutInfo target = ps.findShortcutById(source.getId());
// Invisible shortcuts can't be updated.
if (target == null || !target.isVisibleToPublisher()) {
continue;
}
if (target.isEnabled() != source.isEnabled()) {
Slog.w(TAG,
"ShortcutInfo.enabled cannot be changed with updateShortcuts()");
}
// When updating the rank, we need to insert between existing ranks, so set
// this setRankChanged, and also copy the implicit rank fo adjustRanks().
if (source.hasRank()) {
target.setRankChanged();
target.setImplicitRank(source.getImplicitRank());
}
final boolean replacingIcon = (source.getIcon() != null);
if (replacingIcon) {
removeIconLocked(target);
}
// Note copyNonNullFieldsFrom() does the "updatable with?" check too.
target.copyNonNullFieldsFrom(source);
target.setTimestamp(injectCurrentTimeMillis());
if (replacingIcon) {
saveIconAndFixUpShortcutLocked(target);
}
// When we're updating any resource related fields, re-extract the res names and
// the values.
if (replacingIcon || source.hasStringResources()) {
fixUpShortcutResourceNamesAndValues(target);
}
}
// Lastly, adjust the ranks.
ps.adjustRanks();
}
packageShortcutsChanged(packageName, userId);
verifyStates();
return true;
}