diff options
| author | Eugene Susla <eugenesusla@google.com> | 2020-11-02 14:38:46 -0800 |
|---|---|---|
| committer | Eugene Susla <eugenesusla@google.com> | 2020-11-04 16:02:06 -0800 |
| commit | 10864c6764ddd880febfe08a55f00ff38e63c7d1 (patch) | |
| tree | a6a8bd05caea52ef944d604af2acccf470673635 /core/java | |
| parent | 3f1e82b12c5b8b96f0cc8c556033c5d97049a511 (diff) | |
CDM profile API
This introduces API for devs to request a "watch" profile,
as well as an optional "persistent CDM grants", e.g. for devices
with wifi/LTE.
This also introduces a permission that will be mandatory for apps
to declare in the manifest when opting into the above
CTS-Coverage-Bug: 172290699
Bug: 165951651
Test: presubmit
Change-Id: Ie5016c92855f33edb46fa8eb7ae2a9226e29cdda
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/companion/AssociationRequest.java | 340 |
1 files changed, 268 insertions, 72 deletions
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java index 8170bf92ae1e..57b0828b334c 100644 --- a/core/java/android/companion/AssociationRequest.java +++ b/core/java/android/companion/AssociationRequest.java @@ -16,8 +16,11 @@ package android.companion; +import static com.android.internal.util.CollectionUtils.emptyIfNull; + import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.StringDef; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; @@ -25,7 +28,7 @@ import android.os.Parcelable; import android.provider.OneTimeUseBuilder; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.CollectionUtils; +import com.android.internal.util.DataClass; import java.util.ArrayList; import java.util.List; @@ -43,23 +46,66 @@ import java.util.Objects; * You can also set {@link Builder#setSingleDevice single device} to request a popup with single * device to be shown instead of a list to choose from */ +@DataClass( + genToString = true, + genEqualsHashCode = true, + genHiddenGetters = true, + genParcelable = true, + genHiddenConstructor = true, + genBuilder = false) public final class AssociationRequest implements Parcelable { - private final boolean mSingleDevice; - private final List<DeviceFilter<?>> mDeviceFilters; - private String mCallingPackage; + /** + * Device profile: watch. + * + * @see AssociationRequest.Builder#setDeviceProfile + */ + public static final String DEVICE_PROFILE_WATCH = + "android.app.role.COMPANION_DEVICE_WATCH"; - private AssociationRequest( - boolean singleDevice, @Nullable List<DeviceFilter<?>> deviceFilters) { - this.mSingleDevice = singleDevice; - this.mDeviceFilters = CollectionUtils.emptyIfNull(deviceFilters); + /** @hide */ + @StringDef(value = { DEVICE_PROFILE_WATCH }) + public @interface DeviceProfile {} + + /** + * Whether only a single device should match the provided filter. + * + * When scanning for a single device with a specifc {@link BluetoothDeviceFilter} mac + * address, bonded devices are also searched among. This allows to obtain the necessary app + * privileges even if the device is already paired. + */ + private boolean mSingleDevice = false; + + /** + * If set, only devices matching either of the given filters will be shown to the user + */ + @DataClass.PluralOf("deviceFilter") + private @NonNull List<DeviceFilter<?>> mDeviceFilters = new ArrayList<>(); + + /** + * If set, association will be requested as a corresponding kind of device + */ + private @Nullable @DeviceProfile String mDeviceProfile = null; + + /** + * The app package making the request. + * + * Populated by the system. + * + * @hide + */ + private @Nullable String mCallingPackage = null; + + /** @hide */ + public void setCallingPackage(@NonNull String pkg) { + mCallingPackage = pkg; } - private AssociationRequest(Parcel in) { - this( - in.readByte() != 0, - in.readParcelableList(new ArrayList<>(), AssociationRequest.class.getClassLoader())); - setCallingPackage(in.readString()); + private void onConstructed() { + if (mDeviceProfile != null + && !Objects.equals(mDeviceProfile, DEVICE_PROFILE_WATCH)) { + throw new IllegalArgumentException("Invalid device profile: " + mDeviceProfile); + } } /** @hide */ @@ -75,70 +121,13 @@ public final class AssociationRequest implements Parcelable { return mDeviceFilters; } - /** @hide */ - public String getCallingPackage() { - return mCallingPackage; - } - - /** @hide */ - public void setCallingPackage(String pkg) { - mCallingPackage = pkg; - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - AssociationRequest that = (AssociationRequest) o; - return mSingleDevice == that.mSingleDevice - && Objects.equals(mDeviceFilters, that.mDeviceFilters) - && Objects.equals(mCallingPackage, that.mCallingPackage); - } - - @Override - public int hashCode() { - return Objects.hash(mSingleDevice, mDeviceFilters, mCallingPackage); - } - - @Override - public String toString() { - return "AssociationRequest{" - + "mSingleDevice=" + mSingleDevice - + ", mDeviceFilters=" + mDeviceFilters - + ", mCallingPackage=" + mCallingPackage - + '}'; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeByte((byte) (mSingleDevice ? 1 : 0)); - dest.writeParcelableList(mDeviceFilters, flags); - dest.writeString(mCallingPackage); - } - - @Override - public int describeContents() { - return 0; - } - - public static final @android.annotation.NonNull Creator<AssociationRequest> CREATOR = new Creator<AssociationRequest>() { - @Override - public AssociationRequest createFromParcel(Parcel in) { - return new AssociationRequest(in); - } - - @Override - public AssociationRequest[] newArray(int size) { - return new AssociationRequest[size]; - } - }; - /** * A builder for {@link AssociationRequest} */ public static final class Builder extends OneTimeUseBuilder<AssociationRequest> { private boolean mSingleDevice = false; @Nullable private ArrayList<DeviceFilter<?>> mDeviceFilters = null; + private @Nullable String mDeviceProfile = null; public Builder() {} @@ -172,12 +161,219 @@ public final class AssociationRequest implements Parcelable { return this; } + /** + * If set, association will be requested as a corresponding kind of device + */ + @NonNull + public Builder setDeviceProfile(@NonNull @DeviceProfile String deviceProfile) { + checkNotUsed(); + mDeviceProfile = deviceProfile; + return this; + } + /** @inheritDoc */ @NonNull @Override public AssociationRequest build() { markUsed(); - return new AssociationRequest(mSingleDevice, mDeviceFilters); + return new AssociationRequest( + mSingleDevice, emptyIfNull(mDeviceFilters), + mDeviceProfile, null); } } + + + + + // Code below generated by codegen v1.0.20. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/companion/AssociationRequest.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + /** + * Creates a new AssociationRequest. + * + * @param singleDevice + * Whether only a single device should match the provided filter. + * + * When scanning for a single device with a specifc {@link BluetoothDeviceFilter} mac + * address, bonded devices are also searched among. This allows to obtain the necessary app + * privileges even if the device is already paired. + * @param deviceFilters + * If set, only devices matching either of the given filters will be shown to the user + * @param deviceProfile + * If set, association will be requested as a corresponding kind of device + * @param callingPackage + * The app package making the request. + * + * Populated by the system. + * @hide + */ + @DataClass.Generated.Member + public AssociationRequest( + boolean singleDevice, + @NonNull List<DeviceFilter<?>> deviceFilters, + @Nullable @DeviceProfile String deviceProfile, + @Nullable String callingPackage) { + this.mSingleDevice = singleDevice; + this.mDeviceFilters = deviceFilters; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mDeviceFilters); + this.mDeviceProfile = deviceProfile; + com.android.internal.util.AnnotationValidations.validate( + DeviceProfile.class, null, mDeviceProfile); + this.mCallingPackage = callingPackage; + + onConstructed(); + } + + /** + * If set, association will be requested as a corresponding kind of device + * + * @hide + */ + @DataClass.Generated.Member + public @Nullable @DeviceProfile String getDeviceProfile() { + return mDeviceProfile; + } + + /** + * The app package making the request. + * + * Populated by the system. + * + * @hide + */ + @DataClass.Generated.Member + public @Nullable String getCallingPackage() { + return mCallingPackage; + } + + @Override + @DataClass.Generated.Member + public String toString() { + // You can override field toString logic by defining methods like: + // String fieldNameToString() { ... } + + return "AssociationRequest { " + + "singleDevice = " + mSingleDevice + ", " + + "deviceFilters = " + mDeviceFilters + ", " + + "deviceProfile = " + mDeviceProfile + ", " + + "callingPackage = " + mCallingPackage + + " }"; + } + + @Override + @DataClass.Generated.Member + public boolean equals(@Nullable Object o) { + // You can override field equality logic by defining either of the methods like: + // boolean fieldNameEquals(AssociationRequest other) { ... } + // boolean fieldNameEquals(FieldType otherValue) { ... } + + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + @SuppressWarnings("unchecked") + AssociationRequest that = (AssociationRequest) o; + //noinspection PointlessBooleanExpression + return true + && mSingleDevice == that.mSingleDevice + && Objects.equals(mDeviceFilters, that.mDeviceFilters) + && Objects.equals(mDeviceProfile, that.mDeviceProfile) + && Objects.equals(mCallingPackage, that.mCallingPackage); + } + + @Override + @DataClass.Generated.Member + public int hashCode() { + // You can override field hashCode logic by defining methods like: + // int fieldNameHashCode() { ... } + + int _hash = 1; + _hash = 31 * _hash + Boolean.hashCode(mSingleDevice); + _hash = 31 * _hash + Objects.hashCode(mDeviceFilters); + _hash = 31 * _hash + Objects.hashCode(mDeviceProfile); + _hash = 31 * _hash + Objects.hashCode(mCallingPackage); + return _hash; + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@NonNull Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + byte flg = 0; + if (mSingleDevice) flg |= 0x1; + if (mDeviceProfile != null) flg |= 0x4; + if (mCallingPackage != null) flg |= 0x8; + dest.writeByte(flg); + dest.writeParcelableList(mDeviceFilters, flags); + if (mDeviceProfile != null) dest.writeString(mDeviceProfile); + if (mCallingPackage != null) dest.writeString(mCallingPackage); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + /* package-private */ AssociationRequest(@NonNull Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + byte flg = in.readByte(); + boolean singleDevice = (flg & 0x1) != 0; + List<DeviceFilter<?>> deviceFilters = new ArrayList<>(); + in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader()); + String deviceProfile = (flg & 0x4) == 0 ? null : in.readString(); + String callingPackage = (flg & 0x8) == 0 ? null : in.readString(); + + this.mSingleDevice = singleDevice; + this.mDeviceFilters = deviceFilters; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mDeviceFilters); + this.mDeviceProfile = deviceProfile; + com.android.internal.util.AnnotationValidations.validate( + DeviceProfile.class, null, mDeviceProfile); + this.mCallingPackage = callingPackage; + + onConstructed(); + } + + @DataClass.Generated.Member + public static final @NonNull Parcelable.Creator<AssociationRequest> CREATOR + = new Parcelable.Creator<AssociationRequest>() { + @Override + public AssociationRequest[] newArray(int size) { + return new AssociationRequest[size]; + } + + @Override + public AssociationRequest createFromParcel(@NonNull Parcel in) { + return new AssociationRequest(in); + } + }; + + @DataClass.Generated( + time = 1604534468409L, + codegenVersion = "1.0.20", + sourceFile = "frameworks/base/core/java/android/companion/AssociationRequest.java", + inputSignatures = "public static final java.lang.String DEVICE_PROFILE_WATCH\nprivate boolean mSingleDevice\nprivate @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.String mCallingPackage\npublic void setCallingPackage(java.lang.String)\nprivate void onConstructed()\npublic @android.compat.annotation.UnsupportedAppUsage boolean isSingleDevice()\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genHiddenConstructor=true, genBuilder=false)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + } |
