Merge "Adds capability related setters in ShortcutInfo.Builder"
This commit is contained in:
@@ -13475,6 +13475,7 @@ package android.content.pm {
|
||||
public final class ShortcutInfo implements android.os.Parcelable {
|
||||
method public int describeContents();
|
||||
method @Nullable public android.content.ComponentName getActivity();
|
||||
method @NonNull public java.util.List<java.lang.String> getCapabilityParameterValues(@NonNull String, @NonNull String);
|
||||
method @Nullable public java.util.Set<java.lang.String> getCategories();
|
||||
method @Nullable public CharSequence getDisabledMessage();
|
||||
method public int getDisabledReason();
|
||||
@@ -13489,6 +13490,7 @@ package android.content.pm {
|
||||
method public int getRank();
|
||||
method @Nullable public CharSequence getShortLabel();
|
||||
method public android.os.UserHandle getUserHandle();
|
||||
method public boolean hasCapability(@NonNull String);
|
||||
method public boolean hasKeyFieldsOnly();
|
||||
method public boolean isCached();
|
||||
method public boolean isDeclaredInManifest();
|
||||
@@ -13513,6 +13515,7 @@ package android.content.pm {
|
||||
|
||||
public static class ShortcutInfo.Builder {
|
||||
ctor public ShortcutInfo.Builder(android.content.Context, String);
|
||||
method @NonNull public android.content.pm.ShortcutInfo.Builder addCapabilityBinding(@NonNull String, @Nullable String, @Nullable java.util.List<java.lang.String>);
|
||||
method @NonNull public android.content.pm.ShortcutInfo build();
|
||||
method @NonNull public android.content.pm.ShortcutInfo.Builder setActivity(@NonNull android.content.ComponentName);
|
||||
method @NonNull public android.content.pm.ShortcutInfo.Builder setCategories(java.util.Set<java.lang.String>);
|
||||
|
||||
@@ -423,7 +423,7 @@ public class AppSearchShortcutInfo extends GenericDocument {
|
||||
shortLabelResName, longLabel, longLabelResId, longLabelResName, disabledMessage,
|
||||
disabledMessageResId, disabledMessageResName, categoriesSet, intents, rank, extras,
|
||||
getCreationTimestampMillis(), flags, iconResId, iconResName, bitmapPath, iconUri,
|
||||
disabledReason, persons, locusId, null);
|
||||
disabledReason, persons, locusId, null, null);
|
||||
si.setImplicitRank(implicitRank);
|
||||
if ((implicitRank & ShortcutInfo.RANK_CHANGED_BIT) != 0) {
|
||||
si.setRankChanged();
|
||||
|
||||
@@ -41,6 +41,7 @@ import android.os.Parcelable;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.view.contentcapture.ContentCaptureContext;
|
||||
@@ -50,9 +51,15 @@ import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Represents a shortcut that can be published via {@link ShortcutManager}.
|
||||
@@ -463,6 +470,9 @@ public final class ShortcutInfo implements Parcelable {
|
||||
|
||||
private int mExcludedSurfaces;
|
||||
|
||||
@Nullable
|
||||
private Map<String, Map<String, List<String>>> mCapabilityBindings;
|
||||
|
||||
private ShortcutInfo(Builder b) {
|
||||
mUserId = b.mContext.getUserId();
|
||||
|
||||
@@ -490,7 +500,7 @@ public final class ShortcutInfo implements Parcelable {
|
||||
mRank = b.mRank;
|
||||
mExtras = b.mExtras;
|
||||
mLocusId = b.mLocusId;
|
||||
|
||||
mCapabilityBindings = b.mCapabilityBindings;
|
||||
mStartingThemeResName = b.mStartingThemeResId != 0
|
||||
? b.mContext.getResources().getResourceName(b.mStartingThemeResId) : null;
|
||||
updateTimestamp();
|
||||
@@ -602,7 +612,7 @@ public final class ShortcutInfo implements Parcelable {
|
||||
mLocusId = source.mLocusId;
|
||||
mExcludedSurfaces = source.mExcludedSurfaces;
|
||||
|
||||
// Just always keep it since it's cheep.
|
||||
// Just always keep it since it's cheap.
|
||||
mIconResId = source.mIconResId;
|
||||
|
||||
if ((cloneFlags & CLONE_REMOVE_NON_KEY_INFO) == 0) {
|
||||
@@ -641,6 +651,7 @@ public final class ShortcutInfo implements Parcelable {
|
||||
// Set this bit.
|
||||
mFlags |= FLAG_KEY_FIELDS_ONLY;
|
||||
}
|
||||
mCapabilityBindings = source.mCapabilityBindings;
|
||||
mStartingThemeResName = source.mStartingThemeResName;
|
||||
}
|
||||
|
||||
@@ -968,6 +979,9 @@ public final class ShortcutInfo implements Parcelable {
|
||||
if (source.mStartingThemeResName != null && !source.mStartingThemeResName.isEmpty()) {
|
||||
mStartingThemeResName = source.mStartingThemeResName;
|
||||
}
|
||||
if (source.mCapabilityBindings != null) {
|
||||
mCapabilityBindings = source.mCapabilityBindings;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1039,6 +1053,9 @@ public final class ShortcutInfo implements Parcelable {
|
||||
|
||||
private int mStartingThemeResId;
|
||||
|
||||
@Nullable
|
||||
private Map<String, Map<String, List<String>>> mCapabilityBindings;
|
||||
|
||||
private int mExcludedSurfaces;
|
||||
|
||||
/**
|
||||
@@ -1400,6 +1417,53 @@ public final class ShortcutInfo implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates a shortcut with a capability, and a parameter of that capability. Used when
|
||||
* the shortcut is an instance of a capability.
|
||||
*
|
||||
* <P>This method can be called multiple times to add multiple parameters to the same
|
||||
* capability.
|
||||
*
|
||||
* @param capability capability associated with the shortcut. e.g. actions.intent
|
||||
* .START_EXERCISE.
|
||||
* @param parameterName name of the parameter associated with given capability.
|
||||
* e.g. exercise.name.
|
||||
* @param parameterValues a list of values for that parameters. The first value will be
|
||||
* the primary name, while the rest will be alternative names. If
|
||||
* the values are empty, then the parameter will not be saved in
|
||||
* the shortcut.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder addCapabilityBinding(@NonNull String capability,
|
||||
@Nullable String parameterName, @Nullable List<String> parameterValues) {
|
||||
Objects.requireNonNull(capability);
|
||||
if (capability.contains("/")) {
|
||||
throw new IllegalArgumentException("Illegal character '/' is found in capability");
|
||||
}
|
||||
if (mCapabilityBindings == null) {
|
||||
mCapabilityBindings = new ArrayMap<>(1);
|
||||
}
|
||||
if (!mCapabilityBindings.containsKey(capability)) {
|
||||
mCapabilityBindings.put(capability, new ArrayMap<>(0));
|
||||
}
|
||||
if (parameterName == null || parameterValues == null || parameterValues.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
if (parameterName.contains("/")) {
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal character '/' is found in parameter name");
|
||||
}
|
||||
final Map<String, List<String>> params = mCapabilityBindings.get(capability);
|
||||
if (!params.containsKey(parameterName)) {
|
||||
params.put(parameterName, parameterValues);
|
||||
return this;
|
||||
}
|
||||
params.put(parameterName,
|
||||
Stream.of(params.get(parameterName), parameterValues)
|
||||
.flatMap(Collection::stream).collect(Collectors.toList()));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets which surfaces a shortcut will be excluded from.
|
||||
*
|
||||
@@ -2176,6 +2240,44 @@ public final class ShortcutInfo implements Parcelable {
|
||||
return (mExcludedSurfaces & surface) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public Map<String, Map<String, List<String>>> getCapabilityBindings() {
|
||||
return mCapabilityBindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the shortcut is or can be used in specified capability.
|
||||
*/
|
||||
public boolean hasCapability(@NonNull String capability) {
|
||||
Objects.requireNonNull(capability);
|
||||
return mCapabilityBindings != null && mCapabilityBindings.containsKey(capability);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the values of specified parameter in associated with given capability.
|
||||
*
|
||||
* @param capability capability associated with the shortcut. e.g. actions.intent
|
||||
* .START_EXERCISE.
|
||||
* @param parameterName name of the parameter associated with given capability.
|
||||
* e.g. exercise.name.
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getCapabilityParameterValues(
|
||||
@NonNull String capability, @NonNull String parameterName) {
|
||||
Objects.requireNonNull(capability);
|
||||
Objects.requireNonNull(parameterName);
|
||||
if (mCapabilityBindings == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final Map<String, List<String>> param = mCapabilityBindings.get(capability);
|
||||
if (param == null || !param.containsKey(parameterName)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return param.get(parameterName);
|
||||
}
|
||||
|
||||
private ShortcutInfo(Parcel source) {
|
||||
final ClassLoader cl = getClass().getClassLoader();
|
||||
|
||||
@@ -2225,6 +2327,15 @@ public final class ShortcutInfo implements Parcelable {
|
||||
mIconUri = source.readString8();
|
||||
mStartingThemeResName = source.readString8();
|
||||
mExcludedSurfaces = source.readInt();
|
||||
|
||||
final Map<String, Map> rawCapabilityBindings = source.readHashMap(
|
||||
/*loader*/ null, /*clazzKey*/ String.class, /*clazzValue*/ HashMap.class);
|
||||
if (rawCapabilityBindings != null && !rawCapabilityBindings.isEmpty()) {
|
||||
final Map<String, Map<String, List<String>>> capabilityBindings =
|
||||
new ArrayMap<>(rawCapabilityBindings.size());
|
||||
rawCapabilityBindings.forEach(capabilityBindings::put);
|
||||
mCapabilityBindings = capabilityBindings;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2278,6 +2389,7 @@ public final class ShortcutInfo implements Parcelable {
|
||||
dest.writeString8(mIconUri);
|
||||
dest.writeString8(mStartingThemeResName);
|
||||
dest.writeInt(mExcludedSurfaces);
|
||||
dest.writeMap(mCapabilityBindings);
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<ShortcutInfo> CREATOR =
|
||||
@@ -2529,7 +2641,8 @@ public final class ShortcutInfo implements Parcelable {
|
||||
long lastChangedTimestamp,
|
||||
int flags, int iconResId, String iconResName, String bitmapPath, String iconUri,
|
||||
int disabledReason, Person[] persons, LocusId locusId,
|
||||
@Nullable String startingThemeResName) {
|
||||
@Nullable String startingThemeResName,
|
||||
@Nullable Map<String, Map<String, List<String>>> capabilityBindings) {
|
||||
mUserId = userId;
|
||||
mId = id;
|
||||
mPackageName = packageName;
|
||||
@@ -2559,5 +2672,6 @@ public final class ShortcutInfo implements Parcelable {
|
||||
mPersons = persons;
|
||||
mLocusId = locusId;
|
||||
mStartingThemeResName = startingThemeResName;
|
||||
mCapabilityBindings = capabilityBindings;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,8 +146,10 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
private static final String ATTR_PERSON_IS_IMPORTANT = "is-important";
|
||||
|
||||
private static final String NAME_CATEGORIES = "categories";
|
||||
private static final String NAME_CAPABILITY = "capability";
|
||||
|
||||
private static final String TAG_STRING_ARRAY_XMLUTILS = "string-array";
|
||||
private static final String TAG_MAP_XMLUTILS = "map";
|
||||
private static final String ATTR_NAME_XMLUTILS = "name";
|
||||
|
||||
private static final String KEY_DYNAMIC = "dynamic";
|
||||
@@ -1829,6 +1831,12 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
}
|
||||
|
||||
ShortcutService.writeTagExtra(out, TAG_EXTRAS, si.getExtras());
|
||||
|
||||
final Map<String, Map<String, List<String>>> capabilityBindings =
|
||||
si.getCapabilityBindings();
|
||||
if (capabilityBindings != null && !capabilityBindings.isEmpty()) {
|
||||
XmlUtils.writeMapXml(si.getCapabilityBindings(), NAME_CAPABILITY, out);
|
||||
}
|
||||
}
|
||||
|
||||
out.endTag(null, TAG_SHORTCUT);
|
||||
@@ -1961,6 +1969,7 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
int backupVersionCode;
|
||||
ArraySet<String> categories = null;
|
||||
ArrayList<Person> persons = new ArrayList<>();
|
||||
Map<String, Map<String, List<String>>> capabilityBindings = null;
|
||||
|
||||
id = ShortcutService.parseStringAttribute(parser, ATTR_ID);
|
||||
activityComponent = ShortcutService.parseComponentNameAttribute(parser,
|
||||
@@ -2029,6 +2038,13 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case TAG_MAP_XMLUTILS:
|
||||
if (NAME_CAPABILITY.equals(ShortcutService.parseStringAttribute(parser,
|
||||
ATTR_NAME_XMLUTILS))) {
|
||||
capabilityBindings = (Map<String, Map<String, List<String>>>)
|
||||
XmlUtils.readValueXml(parser, new String[1]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw ShortcutService.throwForInvalidTag(depth, tag);
|
||||
}
|
||||
@@ -2064,7 +2080,7 @@ class ShortcutPackage extends ShortcutPackageItem {
|
||||
rank, extras, lastChangedTimestamp, flags,
|
||||
iconResId, iconResName, bitmapPath, iconUri,
|
||||
disabledReason, persons.toArray(new Person[persons.size()]), locusId,
|
||||
splashScreenThemeResName);
|
||||
splashScreenThemeResName, capabilityBindings);
|
||||
}
|
||||
|
||||
private static Intent parseIntent(TypedXmlPullParser parser)
|
||||
|
||||
@@ -459,7 +459,8 @@ public class ShortcutParser {
|
||||
disabledReason,
|
||||
null /* persons */,
|
||||
null /* locusId */,
|
||||
splashScreenThemeResName);
|
||||
splashScreenThemeResName,
|
||||
null /* capabilityBindings */);
|
||||
}
|
||||
|
||||
private static String parseCategory(ShortcutService service, AttributeSet attrs) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.server.pm;
|
||||
|
||||
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertBundlesEqual;
|
||||
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertEmpty;
|
||||
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
|
||||
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
|
||||
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
|
||||
@@ -257,6 +258,10 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
|
||||
.setLongLived(true)
|
||||
.setExtras(pb)
|
||||
.setStartingTheme(android.R.style.Theme_Black_NoTitleBar_Fullscreen)
|
||||
.addCapabilityBinding("action.intent.START_EXERCISE",
|
||||
"exercise.type", list("running", "jogging"))
|
||||
.addCapabilityBinding("action.intent.START_EXERCISE",
|
||||
"exercise.duration", list("10m"))
|
||||
.build();
|
||||
si.addFlags(ShortcutInfo.FLAG_PINNED);
|
||||
si.setBitmapPath("abc");
|
||||
@@ -294,6 +299,13 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
|
||||
assertEquals(null, si.getDisabledMessageResName());
|
||||
assertEquals("android:style/Theme.Black.NoTitleBar.Fullscreen",
|
||||
si.getStartingThemeResName());
|
||||
assertTrue(si.hasCapability("action.intent.START_EXERCISE"));
|
||||
assertFalse(si.hasCapability(""));
|
||||
assertFalse(si.hasCapability("random"));
|
||||
assertEquals(list("running", "jogging"), si.getCapabilityParameterValues(
|
||||
"action.intent.START_EXERCISE", "exercise.type"));
|
||||
assertEmpty(si.getCapabilityParameterValues("action.intent.START_EXERCISE", ""));
|
||||
assertEmpty(si.getCapabilityParameterValues("action.intent.START_EXERCISE", "random"));
|
||||
}
|
||||
|
||||
public void testShortcutInfoParcel_resId() {
|
||||
@@ -947,6 +959,10 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
|
||||
.setRank(123)
|
||||
.setExtras(pb)
|
||||
.setLocusId(new LocusId("1.2.3.4.5"))
|
||||
.addCapabilityBinding("action.intent.START_EXERCISE",
|
||||
"exercise.type", list("running", "jogging"))
|
||||
.addCapabilityBinding("action.intent.START_EXERCISE",
|
||||
"exercise.duration", list("10m"))
|
||||
.build();
|
||||
sorig.setTimestamp(mInjectedCurrentTimeMillis);
|
||||
|
||||
@@ -1008,6 +1024,14 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
|
||||
assertNull(si.getIconUri());
|
||||
assertTrue(si.getLastChangedTimestamp() < now);
|
||||
|
||||
assertTrue(si.hasCapability("action.intent.START_EXERCISE"));
|
||||
assertFalse(si.hasCapability(""));
|
||||
assertFalse(si.hasCapability("random"));
|
||||
assertEquals(list("running", "jogging"), si.getCapabilityParameterValues(
|
||||
"action.intent.START_EXERCISE", "exercise.type"));
|
||||
assertEmpty(si.getCapabilityParameterValues("action.intent.START_EXERCISE", ""));
|
||||
assertEmpty(si.getCapabilityParameterValues("action.intent.START_EXERCISE", "random"));
|
||||
|
||||
// Make sure ranks are saved too. Because of the auto-adjusting, we need two shortcuts
|
||||
// to test it.
|
||||
si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id2", USER_10);
|
||||
|
||||
@@ -394,7 +394,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
|
||||
"disabledMessage", 0, "disabledMessageResName",
|
||||
null, null, 0, null, 0, 0,
|
||||
0, "iconResName", "bitmapPath", null, 0,
|
||||
null, null, null);
|
||||
null, null, null, null);
|
||||
return si;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user