Update capability related api in Shortcut

Create dedicated classes for capability to decouple related apis from
native types for future extensibility.

Bug: 216590966
Test: atest CtsShortcutManagerTestCases
Change-Id: I6d7b9a00141ad8ad55ababb4a8446ed28e55031b
This commit is contained in:
Pinyao Ting
2022-02-04 19:14:06 +00:00
parent 98a2f3a88b
commit e5aec04daa
9 changed files with 544 additions and 89 deletions

View File

@@ -11230,6 +11230,33 @@ package android.content.pm {
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.Attribution> CREATOR;
}
public final class Capability implements android.os.Parcelable {
method public int describeContents();
method @NonNull public String getName();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.Capability> CREATOR;
}
public static final class Capability.Builder {
ctor public Capability.Builder(@NonNull String);
method @NonNull public android.content.pm.Capability build();
}
public final class CapabilityParams implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.List<java.lang.String> getAliases();
method @NonNull public String getName();
method @NonNull public String getValue();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.CapabilityParams> CREATOR;
}
public static final class CapabilityParams.Builder {
ctor public CapabilityParams.Builder(@NonNull String, @NonNull String);
method @NonNull public android.content.pm.CapabilityParams.Builder addAlias(@NonNull String);
method @NonNull public android.content.pm.CapabilityParams build();
}
public final class ChangedPackages implements android.os.Parcelable {
ctor public ChangedPackages(int, @NonNull java.util.List<java.lang.String>);
method public int describeContents();
@@ -12291,7 +12318,8 @@ package android.content.pm {
method @NonNull public static android.content.pm.ShortcutInfo createFromGenericDocument(@NonNull android.content.Context, @NonNull android.app.appsearch.GenericDocument);
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 @NonNull public java.util.List<android.content.pm.Capability> getCapabilities();
method @NonNull public java.util.List<android.content.pm.CapabilityParams> getCapabilityParams(@NonNull android.content.pm.Capability);
method @Nullable public java.util.Set<java.lang.String> getCategories();
method @Nullable public CharSequence getDisabledMessage();
method public int getDisabledReason();
@@ -12306,7 +12334,6 @@ 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();
@@ -12331,7 +12358,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.Builder addCapabilityBinding(@NonNull android.content.pm.Capability, @Nullable android.content.pm.CapabilityParams);
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>);

View File

@@ -349,7 +349,7 @@ public class AppSearchShortcutInfo extends GenericDocument {
.setDisabledReason(shortcutInfo.getDisabledReason())
.setPersons(shortcutInfo.getPersons())
.setLocusId(shortcutInfo.getLocusId())
.setCapabilityBindings(shortcutInfo.getCapabilityBindings())
.setCapabilityBindings(shortcutInfo.getCapabilityBindingsInternal())
.setTtlMillis(SHORTCUT_TTL)
.build();
}

View File

@@ -0,0 +1,18 @@
/*
* Copyright (C) 2022 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 android.content.pm;
parcelable Capability;

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2022 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 android.content.pm;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* Represents a capability that can be performed by an app, also known as App Action.
* Capabilities can be associated with a {@link ShortcutInfo}.
*
* @see ShortcutInfo.Builder#addCapabilityBinding(Capability, CapabilityParams)
*/
public final class Capability implements Parcelable {
@NonNull
private final String mName;
/**
* Constructor.
* @param name Name of the capability, usually maps to a built-in intent,
* e.g. actions.intent.GET_MESSAGE. Note the character "/" is not permitted.
* @throws IllegalArgumentException If specified capability name contains the character "/".
*
* @hide
*/
Capability(@NonNull final String name) {
Objects.requireNonNull(name);
if (name.contains("/")) {
throw new IllegalArgumentException("'/' is not permitted in the capability name");
}
mName = name;
}
/**
* Copy constructor.
*
* @hide
*/
Capability(@NonNull final Capability orig) {
this(orig.mName);
}
private Capability(@NonNull final Builder builder) {
this(builder.mName);
}
private Capability(@NonNull final Parcel in) {
mName = in.readString();
}
/**
* Returns the name of the capability. e.g. actions.intent.GET_MESSAGE.
*/
@NonNull
public String getName() {
return mName;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Capability)) {
return false;
}
return mName.equals(((Capability) obj).mName);
}
@Override
public int hashCode() {
return mName.hashCode();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mName);
}
@Override
public int describeContents() {
return 0;
}
@NonNull
public static final Parcelable.Creator<Capability> CREATOR =
new Parcelable.Creator<Capability>() {
@Override
public Capability[] newArray(int size) {
return new Capability[size];
}
@Override
public Capability createFromParcel(@NonNull Parcel in) {
return new Capability(in);
}
};
/**
* Builder class for {@link Capability}.
*/
public static final class Builder {
@NonNull
private final String mName;
/**
* Constructor.
* @param name Name of the capability, usually maps to a built-in intent,
* e.g. actions.intent.GET_MESSAGE. Note the character "/" is not permitted.
* @throws IllegalArgumentException If specified capability name contains the character "/".
*/
public Builder(@NonNull final String name) {
Objects.requireNonNull(name);
if (name.contains("/")) {
throw new IllegalArgumentException("'/' is not permitted in the capability name");
}
mName = name;
}
/**
* Creates an instance of {@link Capability}
*/
@NonNull
public Capability build() {
return new Capability(this);
}
}
}

View File

@@ -0,0 +1,18 @@
/*
* Copyright (C) 2022 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 android.content.pm;
parcelable CapabilityParams;

View File

@@ -0,0 +1,215 @@
/*
* Copyright (C) 2022 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 android.content.pm;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.ArraySet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* Represents the parameters and its matching names which can be associated with a
* {@link Capability}.
*
* @see ShortcutInfo.Builder#addCapabilityBinding(Capability, CapabilityParams)
*/
public final class CapabilityParams implements Parcelable {
@NonNull
private final String mName;
@NonNull
private final String mPrimaryValue;
@NonNull
private final List<String> mAliases;
/**
* Constructor.
* @param name Name of the capability parameter.
* Note the character "/" is not permitted.
* @param primaryValue The primary value of the parameter.
* @param aliases Alternative values of the parameter.
*/
private CapabilityParams(@NonNull final String name,
@NonNull final String primaryValue, @Nullable final Collection<String> aliases) {
Objects.requireNonNull(name);
Objects.requireNonNull(primaryValue);
mName = name;
mPrimaryValue = primaryValue;
mAliases = aliases == null ? Collections.emptyList()
: Collections.unmodifiableList(new ArrayList<>(aliases));
}
/**
* Copy constructor.
* @hide
*/
CapabilityParams(@NonNull final CapabilityParams orig) {
this(orig.mName, orig.mPrimaryValue, orig.mAliases);
}
private CapabilityParams(@NonNull final Builder builder) {
this(builder.mKey, builder.mPrimaryValue, builder.mAliases);
}
private CapabilityParams(@NonNull final Parcel in) {
mName = in.readString();
mPrimaryValue = in.readString();
final List<String> values = new ArrayList<>();
in.readStringList(values);
mAliases = Collections.unmodifiableList(values);
}
/**
* Name of the parameter.
*/
@NonNull
public String getName() {
return mName;
}
/**
* Returns the primary name of values in this parameter.
*/
@NonNull
public String getValue() {
return mPrimaryValue;
}
/**
* Returns the aliases of the values in ths parameter. Returns an empty list if there are no
* aliases.
*/
@NonNull
public List<String> getAliases() {
return new ArrayList<>(mAliases);
}
/**
* A list of values for this parameter. The first value will be the primary name, while the
* rest will be alternative names.
* @hide
*/
@NonNull
List<String> getValues() {
if (mAliases == null) {
return new ArrayList<>(Collections.singletonList(mPrimaryValue));
}
final List<String> ret = new ArrayList<>(mAliases.size() + 1);
ret.add(mPrimaryValue);
ret.addAll(mAliases);
return ret;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CapabilityParams)) {
return false;
}
final CapabilityParams target = (CapabilityParams) obj;
return mName.equals(target.mName) && mPrimaryValue.equals(target.mPrimaryValue)
&& mAliases.equals(target.mAliases);
}
@Override
public int hashCode() {
return Objects.hash(mName, mPrimaryValue, mAliases);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mName);
dest.writeString(mPrimaryValue);
dest.writeStringList(mAliases);
}
@NonNull
public static final Parcelable.Creator<CapabilityParams> CREATOR =
new Parcelable.Creator<CapabilityParams>() {
@Override
public CapabilityParams[] newArray(int size) {
return new CapabilityParams[size];
}
@Override
public CapabilityParams createFromParcel(@NonNull Parcel in) {
return new CapabilityParams(in);
}
};
/**
* Builder class for {@link CapabilityParams}.
*/
public static final class Builder {
@NonNull
private final String mKey;
@NonNull
private String mPrimaryValue;
@NonNull
private Set<String> mAliases;
/**
* Constructor.
* @param key key of the capability parameter.
* Note the character "/" is not permitted.
* @param value The primary name of value in the {@link CapabilityParams}, cannot be empty.
*/
public Builder(@NonNull final String key, @NonNull final String value) {
Objects.requireNonNull(key);
if (TextUtils.isEmpty(value)) {
throw new IllegalArgumentException("Primary value cannot be empty or null");
}
mPrimaryValue = value;
mKey = key;
}
/**
* Add an alias in the {@link CapabilityParams}.
*/
@NonNull
public Builder addAlias(@NonNull final String alias) {
if (mAliases == null) {
mAliases = new ArraySet<>(1);
}
mAliases.add(alias);
return this;
}
/**
* Creates an instance of {@link CapabilityParams}
* @throws IllegalArgumentException If the specified value is empty.
*/
@NonNull
public CapabilityParams build() {
return new CapabilityParams(this);
}
}
}

View File

@@ -52,7 +52,7 @@ import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -60,7 +60,6 @@ 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}.
@@ -501,7 +500,8 @@ public final class ShortcutInfo implements Parcelable {
mRank = b.mRank;
mExtras = b.mExtras;
mLocusId = b.mLocusId;
mCapabilityBindings = b.mCapabilityBindings;
mCapabilityBindings =
cloneCapabilityBindings(b.mCapabilityBindings);
mStartingThemeResName = b.mStartingThemeResId != 0
? b.mContext.getResources().getResourceName(b.mStartingThemeResId) : null;
updateTimestamp();
@@ -652,7 +652,8 @@ public final class ShortcutInfo implements Parcelable {
// Set this bit.
mFlags |= FLAG_KEY_FIELDS_ONLY;
}
mCapabilityBindings = source.mCapabilityBindings;
mCapabilityBindings = cloneCapabilityBindings(
source.mCapabilityBindings);
mStartingThemeResName = source.mStartingThemeResName;
}
@@ -1003,7 +1004,8 @@ public final class ShortcutInfo implements Parcelable {
mStartingThemeResName = source.mStartingThemeResName;
}
if (source.mCapabilityBindings != null) {
mCapabilityBindings = source.mCapabilityBindings;
mCapabilityBindings =
cloneCapabilityBindings(source.mCapabilityBindings);
}
}
@@ -1447,43 +1449,25 @@ public final class ShortcutInfo implements Parcelable {
* <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.
* @param capability {@link Capability} associated with the shortcut.
* @param capabilityParams Optional {@link CapabilityParams} associated with given
* capability.
*/
@NonNull
public Builder addCapabilityBinding(@NonNull String capability,
@Nullable String parameterName, @Nullable List<String> parameterValues) {
public Builder addCapabilityBinding(@NonNull final Capability capability,
@Nullable final CapabilityParams capabilityParams) {
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 (!mCapabilityBindings.containsKey(capability.getName())) {
mCapabilityBindings.put(capability.getName(), new ArrayMap<>(0));
}
if (parameterName == null || parameterValues == null || parameterValues.isEmpty()) {
if (capabilityParams == null) {
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()));
final Map<String, List<String>> params = mCapabilityBindings.get(capability.getName());
params.put(capabilityParams.getName(), capabilityParams.getValues());
return this;
}
@@ -2264,41 +2248,78 @@ public final class ShortcutInfo implements Parcelable {
}
/**
* Returns an immutable copy of the capability bindings using internal data structure.
* @hide
*/
public Map<String, Map<String, List<String>>> getCapabilityBindings() {
return mCapabilityBindings;
@Nullable
public Map<String, Map<String, List<String>>> getCapabilityBindingsInternal() {
return cloneCapabilityBindings(mCapabilityBindings);
}
@Nullable
private static Map<String, Map<String, List<String>>> cloneCapabilityBindings(
@Nullable final Map<String, Map<String, List<String>>> orig) {
if (orig == null) {
return null;
}
final Map<String, Map<String, List<String>>> ret = new ArrayMap<>();
for (String capability : orig.keySet()) {
final Map<String, List<String>> params = orig.get(capability);
final Map<String, List<String>> clone;
if (params == null) {
clone = null;
} else {
clone = new ArrayMap<>(params.size());
for (String paramName : params.keySet()) {
final List<String> paramValues = params.get(paramName);
clone.put(paramName, Collections.unmodifiableList(paramValues));
}
}
ret.put(capability, Collections.unmodifiableMap(clone));
}
return Collections.unmodifiableMap(ret);
}
/**
* 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.
* Return a list of {@link Capability} associated with the shortcut.
*/
@NonNull
public List<String> getCapabilityParameterValues(
@NonNull String capability, @NonNull String parameterName) {
Objects.requireNonNull(capability);
Objects.requireNonNull(parameterName);
public List<Capability> getCapabilities() {
if (mCapabilityBindings == null) {
return Collections.emptyList();
return new ArrayList<>(0);
}
final Map<String, List<String>> param = mCapabilityBindings.get(capability);
if (param == null || !param.containsKey(parameterName)) {
return Collections.emptyList();
return mCapabilityBindings.keySet().stream().map(Capability::new)
.collect(Collectors.toList());
}
/**
* Returns the {@link CapabilityParams} in associated with given capability.
*
* @param capability {@link Capability} associated with the shortcut.
*/
@NonNull
public List<CapabilityParams> getCapabilityParams(@NonNull final Capability capability) {
Objects.requireNonNull(capability);
if (mCapabilityBindings == null) {
return new ArrayList<>(0);
}
return param.get(parameterName);
final Map<String, List<String>> param = mCapabilityBindings.get(capability.getName());
if (param == null) {
return new ArrayList<>(0);
}
final List<CapabilityParams> ret = new ArrayList<>(param.size());
for (String key : param.keySet()) {
final List<String> values = param.get(key);
final String primaryValue = values.get(0);
final List<String> aliases = values.size() == 1
? Collections.emptyList() : values.subList(1, values.size());
CapabilityParams.Builder builder = new CapabilityParams.Builder(key, primaryValue);
for (String alias : aliases) {
builder = builder.addAlias(alias);
}
ret.add(builder.build());
}
return ret;
}
private ShortcutInfo(Parcel source) {
@@ -2357,7 +2378,7 @@ public final class ShortcutInfo implements Parcelable {
final Map<String, Map<String, List<String>>> capabilityBindings =
new ArrayMap<>(rawCapabilityBindings.size());
rawCapabilityBindings.forEach(capabilityBindings::put);
mCapabilityBindings = capabilityBindings;
mCapabilityBindings = cloneCapabilityBindings(capabilityBindings);
}
}
@@ -2695,6 +2716,6 @@ public final class ShortcutInfo implements Parcelable {
mPersons = persons;
mLocusId = locusId;
mStartingThemeResName = startingThemeResName;
mCapabilityBindings = capabilityBindings;
mCapabilityBindings = cloneCapabilityBindings(capabilityBindings);
}
}

View File

@@ -1827,9 +1827,9 @@ class ShortcutPackage extends ShortcutPackageItem {
ShortcutService.writeTagExtra(out, TAG_EXTRAS, si.getExtras());
final Map<String, Map<String, List<String>>> capabilityBindings =
si.getCapabilityBindings();
si.getCapabilityBindingsInternal();
if (capabilityBindings != null && !capabilityBindings.isEmpty()) {
XmlUtils.writeMapXml(si.getCapabilityBindings(), NAME_CAPABILITY, out);
XmlUtils.writeMapXml(capabilityBindings, NAME_CAPABILITY, out);
}
}

View File

@@ -16,7 +16,6 @@
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;
@@ -37,6 +36,8 @@ import android.app.Person;
import android.content.ComponentName;
import android.content.Intent;
import android.content.LocusId;
import android.content.pm.Capability;
import android.content.pm.CapabilityParams;
import android.content.pm.ShortcutInfo;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
@@ -258,10 +259,15 @@ 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"))
.addCapabilityBinding(
new Capability.Builder("action.intent.START_EXERCISE").build(),
new CapabilityParams.Builder("exercise.type", "running")
.addAlias("jogging")
.build())
.addCapabilityBinding(
new Capability.Builder("action.intent.START_EXERCISE").build(),
new CapabilityParams.Builder("exercise.duration", "10m")
.build())
.build();
si.addFlags(ShortcutInfo.FLAG_PINNED);
si.setBitmapPath("abc");
@@ -299,13 +305,14 @@ 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"));
assertEquals(list(new Capability.Builder("action.intent.START_EXERCISE").build()),
si.getCapabilities());
assertEquals(list(
new CapabilityParams.Builder("exercise.type", "running")
.addAlias("jogging").build(),
new CapabilityParams.Builder("exercise.duration", "10m").build()),
si.getCapabilityParams(
new Capability.Builder("action.intent.START_EXERCISE").build()));
}
public void testShortcutInfoParcel_resId() {
@@ -959,10 +966,15 @@ 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"))
.addCapabilityBinding(
new Capability.Builder("action.intent.START_EXERCISE").build(),
new CapabilityParams.Builder("exercise.type", "running")
.addAlias("jogging")
.build())
.addCapabilityBinding(
new Capability.Builder("action.intent.START_EXERCISE").build(),
new CapabilityParams.Builder("exercise.duration", "10m")
.build())
.build();
sorig.setTimestamp(mInjectedCurrentTimeMillis);
@@ -1024,13 +1036,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"));
assertEquals(list(new Capability.Builder("action.intent.START_EXERCISE").build()),
si.getCapabilities());
assertEquals(list(
new CapabilityParams.Builder("exercise.type", "running")
.addAlias("jogging").build(),
new CapabilityParams.Builder("exercise.duration", "10m").build()),
si.getCapabilityParams(
new Capability.Builder("action.intent.START_EXERCISE").build()));
// Make sure ranks are saved too. Because of the auto-adjusting, we need two shortcuts
// to test it.