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:
@@ -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>);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
18
core/java/android/content/pm/Capability.aidl
Normal file
18
core/java/android/content/pm/Capability.aidl
Normal 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;
|
||||
143
core/java/android/content/pm/Capability.java
Normal file
143
core/java/android/content/pm/Capability.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
core/java/android/content/pm/CapabilityParams.aidl
Normal file
18
core/java/android/content/pm/CapabilityParams.aidl
Normal 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;
|
||||
215
core/java/android/content/pm/CapabilityParams.java
Normal file
215
core/java/android/content/pm/CapabilityParams.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user