Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -8947,6 +8947,7 @@ package android.companion { public final class AssociationInfo implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.os.Parcelable getAssociatedDevice(); method @Nullable public android.net.MacAddress getDeviceMacAddress(); method @Nullable public String getDeviceProfile(); method @Nullable public CharSequence getDisplayName(); core/java/android/companion/AssociatedDevice.java 0 → 100644 +133 −0 Original line number Diff line number Diff line /* * 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.companion; import android.os.Parcel; import android.os.Parcelable; import androidx.annotation.NonNull; import androidx.annotation.Nullable; /** * Loose wrapper around device parcelable. Device can be one of three types: * * <ul> * <li>for classic Bluetooth - {@link android.bluetooth.BluetoothDevice}</li> * <li>for Bluetooth LE - {@link android.bluetooth.le.ScanResult}</li> * <li>for WiFi - {@link android.net.wifi.ScanResult}</li> * </ul> * * This class serves as temporary wrapper to deliver a loosely-typed parcelable object from * {@link com.android.companiondevicemanager.CompanionDeviceActivity} to the Companion app, * and should only be used internally. * * @hide */ public final class AssociatedDevice implements Parcelable { private static final int CLASSIC_BLUETOOTH = 0; private static final int BLUETOOTH_LE = 1; private static final int WIFI = 2; @NonNull private final Parcelable mDevice; public AssociatedDevice(@NonNull Parcelable device) { mDevice = device; } private AssociatedDevice(Parcel in) { Creator<? extends Parcelable> creator = getDeviceCreator(in.readInt()); mDevice = creator.createFromParcel(in); } /** * Return device info. Cast to expected device type. */ @NonNull public Parcelable getDevice() { return mDevice; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { // Parcel device type with int for efficiency dest.writeInt(getDeviceType()); mDevice.writeToParcel(dest, flags); } @Override public int describeContents() { return 0; } private int getDeviceType() { if (mDevice instanceof android.bluetooth.BluetoothDevice) return CLASSIC_BLUETOOTH; if (mDevice instanceof android.bluetooth.le.ScanResult) return BLUETOOTH_LE; if (mDevice instanceof android.net.wifi.ScanResult) return WIFI; throw new UnsupportedOperationException("Unsupported device type."); } private static Creator<? extends Parcelable> getDeviceCreator(int deviceType) { switch (deviceType) { case CLASSIC_BLUETOOTH: return android.bluetooth.BluetoothDevice.CREATOR; case BLUETOOTH_LE: return android.bluetooth.le.ScanResult.CREATOR; case WIFI: return android.net.wifi.ScanResult.CREATOR; default: throw new UnsupportedOperationException("Unsupported device type."); } } @NonNull public static final Parcelable.Creator<AssociatedDevice> CREATOR = new Parcelable.Creator<AssociatedDevice>() { @Override public AssociatedDevice[] newArray(int size) { return new AssociatedDevice[size]; } @Override public AssociatedDevice createFromParcel(@NonNull Parcel in) { return new AssociatedDevice(in); } }; @Override public String toString() { return "AssociatedDevice { " + "device = " + mDevice + " }"; } @Override public boolean equals(@Nullable Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AssociatedDevice that = (AssociatedDevice) o; if (getDeviceType() != that.getDeviceType()) return false; // TODO(b/31972115): Take out this whole part ¯\_(ツ)_/¯ if (mDevice instanceof android.bluetooth.le.ScanResult || mDevice instanceof android.net.wifi.ScanResult) { return mDevice.toString().equals(that.mDevice.toString()); } return java.util.Objects.equals(mDevice, that.mDevice); } @Override public int hashCode() { return java.util.Objects.hash(mDevice); } } core/java/android/companion/AssociationInfo.java +31 −5 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ public final class AssociationInfo implements Parcelable { private final @Nullable MacAddress mDeviceMacAddress; private final @Nullable CharSequence mDisplayName; private final @Nullable String mDeviceProfile; private final @Nullable AssociatedDevice mAssociatedDevice; private final boolean mSelfManaged; private final boolean mNotifyOnDeviceNearby; Loading @@ -78,8 +79,9 @@ public final class AssociationInfo implements Parcelable { */ public AssociationInfo(int id, @UserIdInt int userId, @NonNull String packageName, @Nullable MacAddress macAddress, @Nullable CharSequence displayName, @Nullable String deviceProfile, boolean selfManaged, boolean notifyOnDeviceNearby, boolean revoked, long timeApprovedMs, long lastTimeConnectedMs) { @Nullable String deviceProfile, @Nullable AssociatedDevice associatedDevice, boolean selfManaged, boolean notifyOnDeviceNearby, boolean revoked, long timeApprovedMs, long lastTimeConnectedMs) { if (id <= 0) { throw new IllegalArgumentException("Association ID should be greater than 0"); } Loading @@ -96,6 +98,7 @@ public final class AssociationInfo implements Parcelable { mDeviceMacAddress = macAddress; mDisplayName = displayName; mDeviceProfile = deviceProfile; mAssociatedDevice = associatedDevice; mSelfManaged = selfManaged; mNotifyOnDeviceNearby = notifyOnDeviceNearby; Loading Loading @@ -159,6 +162,24 @@ public final class AssociationInfo implements Parcelable { return mDeviceProfile; } /** * Companion device that was associated. Note that this field is not persisted across sessions. * * Cast to expected device type before use: * * <ul> * <li>for classic Bluetooth - {@link android.bluetooth.BluetoothDevice}</li> * <li>for Bluetooth LE - {@link android.bluetooth.le.ScanResult}</li> * <li>for WiFi - {@link android.net.wifi.ScanResult}</li> * </ul> * * @return the companion device that was associated, or {@code null} if the device is * self-managed. */ public @Nullable Parcelable getAssociatedDevice() { return mAssociatedDevice == null ? null : mAssociatedDevice.getDevice(); } /** * @return whether the association is managed by the companion application it belongs to. * @see AssociationRequest.Builder#setSelfManaged(boolean) Loading Loading @@ -260,6 +281,7 @@ public final class AssociationInfo implements Parcelable { + ", mDisplayName='" + mDisplayName + '\'' + ", mDeviceProfile='" + mDeviceProfile + '\'' + ", mSelfManaged=" + mSelfManaged + ", mAssociatedDevice=" + mAssociatedDevice + ", mNotifyOnDeviceNearby=" + mNotifyOnDeviceNearby + ", mRevoked=" + mRevoked + ", mTimeApprovedMs=" + new Date(mTimeApprovedMs) Loading @@ -284,14 +306,15 @@ public final class AssociationInfo implements Parcelable { && Objects.equals(mPackageName, that.mPackageName) && Objects.equals(mDeviceMacAddress, that.mDeviceMacAddress) && Objects.equals(mDisplayName, that.mDisplayName) && Objects.equals(mDeviceProfile, that.mDeviceProfile); && Objects.equals(mDeviceProfile, that.mDeviceProfile) && Objects.equals(mAssociatedDevice, that.mAssociatedDevice); } @Override public int hashCode() { return Objects.hash(mId, mUserId, mPackageName, mDeviceMacAddress, mDisplayName, mDeviceProfile, mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mTimeApprovedMs, mLastTimeConnectedMs); mDeviceProfile, mAssociatedDevice, mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mTimeApprovedMs, mLastTimeConnectedMs); } @Override Loading @@ -309,6 +332,7 @@ public final class AssociationInfo implements Parcelable { dest.writeTypedObject(mDeviceMacAddress, 0); dest.writeCharSequence(mDisplayName); dest.writeString(mDeviceProfile); dest.writeTypedObject(mAssociatedDevice, 0); dest.writeBoolean(mSelfManaged); dest.writeBoolean(mNotifyOnDeviceNearby); Loading @@ -326,6 +350,7 @@ public final class AssociationInfo implements Parcelable { mDeviceMacAddress = in.readTypedObject(MacAddress.CREATOR); mDisplayName = in.readCharSequence(); mDeviceProfile = in.readString(); mAssociatedDevice = in.readTypedObject(AssociatedDevice.CREATOR); mSelfManaged = in.readBoolean(); mNotifyOnDeviceNearby = in.readBoolean(); Loading Loading @@ -433,6 +458,7 @@ public final class AssociationInfo implements Parcelable { mOriginalInfo.mDeviceMacAddress, mOriginalInfo.mDisplayName, mOriginalInfo.mDeviceProfile, mOriginalInfo.mAssociatedDevice, mOriginalInfo.mSelfManaged, mNotifyOnDeviceNearby, mRevoked, Loading core/java/android/companion/AssociationRequest.java +40 −12 Original line number Diff line number Diff line Loading @@ -153,6 +153,11 @@ public final class AssociationRequest implements Parcelable { */ private @Nullable CharSequence mDisplayName; /** * The device that was associated. Will be null for "self-managed" association. */ private @Nullable AssociatedDevice mAssociatedDevice; /** * Whether the association is to be managed by the companion application. */ Loading Loading @@ -306,6 +311,11 @@ public final class AssociationRequest implements Parcelable { mDisplayName = displayName; } /** @hide */ public void setAssociatedDevice(AssociatedDevice associatedDevice) { mAssociatedDevice = associatedDevice; } /** @hide */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Loading Loading @@ -438,6 +448,16 @@ public final class AssociationRequest implements Parcelable { //@formatter:off /** * The device that was associated. Will be null for "self-managed" association. * * @hide */ @DataClass.Generated.Member public @Nullable AssociatedDevice getAssociatedDevice() { return mAssociatedDevice; } /** * The app package name of the application the association will belong to. * Populated by the system. Loading Loading @@ -503,6 +523,7 @@ public final class AssociationRequest implements Parcelable { "deviceFilters = " + mDeviceFilters + ", " + "deviceProfile = " + mDeviceProfile + ", " + "displayName = " + mDisplayName + ", " + "associatedDevice = " + mAssociatedDevice + ", " + "selfManaged = " + mSelfManaged + ", " + "forceConfirmation = " + mForceConfirmation + ", " + "packageName = " + mPackageName + ", " + Loading Loading @@ -530,6 +551,7 @@ public final class AssociationRequest implements Parcelable { && Objects.equals(mDeviceFilters, that.mDeviceFilters) && Objects.equals(mDeviceProfile, that.mDeviceProfile) && Objects.equals(mDisplayName, that.mDisplayName) && Objects.equals(mAssociatedDevice, that.mAssociatedDevice) && mSelfManaged == that.mSelfManaged && mForceConfirmation == that.mForceConfirmation && Objects.equals(mPackageName, that.mPackageName) Loading @@ -550,6 +572,7 @@ public final class AssociationRequest implements Parcelable { _hash = 31 * _hash + Objects.hashCode(mDeviceFilters); _hash = 31 * _hash + Objects.hashCode(mDeviceProfile); _hash = 31 * _hash + Objects.hashCode(mDisplayName); _hash = 31 * _hash + Objects.hashCode(mAssociatedDevice); _hash = 31 * _hash + Boolean.hashCode(mSelfManaged); _hash = 31 * _hash + Boolean.hashCode(mForceConfirmation); _hash = 31 * _hash + Objects.hashCode(mPackageName); Loading @@ -568,17 +591,19 @@ public final class AssociationRequest implements Parcelable { int flg = 0; if (mSingleDevice) flg |= 0x1; if (mSelfManaged) flg |= 0x10; if (mForceConfirmation) flg |= 0x20; if (mSkipPrompt) flg |= 0x400; if (mSelfManaged) flg |= 0x20; if (mForceConfirmation) flg |= 0x40; if (mSkipPrompt) flg |= 0x800; if (mDeviceProfile != null) flg |= 0x4; if (mDisplayName != null) flg |= 0x8; if (mPackageName != null) flg |= 0x40; if (mDeviceProfilePrivilegesDescription != null) flg |= 0x100; if (mAssociatedDevice != null) flg |= 0x10; if (mPackageName != null) flg |= 0x80; if (mDeviceProfilePrivilegesDescription != null) flg |= 0x200; dest.writeInt(flg); dest.writeParcelableList(mDeviceFilters, flags); if (mDeviceProfile != null) dest.writeString(mDeviceProfile); if (mDisplayName != null) dest.writeCharSequence(mDisplayName); if (mAssociatedDevice != null) dest.writeTypedObject(mAssociatedDevice, flags); if (mPackageName != null) dest.writeString(mPackageName); dest.writeInt(mUserId); if (mDeviceProfilePrivilegesDescription != null) dest.writeString(mDeviceProfilePrivilegesDescription); Loading @@ -598,18 +623,20 @@ public final class AssociationRequest implements Parcelable { int flg = in.readInt(); boolean singleDevice = (flg & 0x1) != 0; boolean selfManaged = (flg & 0x10) != 0; boolean forceConfirmation = (flg & 0x20) != 0; boolean skipPrompt = (flg & 0x400) != 0; boolean selfManaged = (flg & 0x20) != 0; boolean forceConfirmation = (flg & 0x40) != 0; boolean skipPrompt = (flg & 0x800) != 0; List<DeviceFilter<?>> deviceFilters = new ArrayList<>(); in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader(), (Class<android.companion.DeviceFilter<?>>) (Class<?>) android.companion.DeviceFilter.class); String deviceProfile = (flg & 0x4) == 0 ? null : in.readString(); CharSequence displayName = (flg & 0x8) == 0 ? null : (CharSequence) in.readCharSequence(); String packageName = (flg & 0x40) == 0 ? null : in.readString(); AssociatedDevice associatedDevice = (flg & 0x10) == 0 ? null : (AssociatedDevice) in.readTypedObject(AssociatedDevice.CREATOR); String packageName = (flg & 0x80) == 0 ? null : in.readString(); int userId = in.readInt(); String deviceProfilePrivilegesDescription = (flg & 0x100) == 0 ? null : in.readString(); String deviceProfilePrivilegesDescription = (flg & 0x200) == 0 ? null : in.readString(); long creationTime = in.readLong(); this.mSingleDevice = singleDevice; Loading @@ -620,6 +647,7 @@ public final class AssociationRequest implements Parcelable { com.android.internal.util.AnnotationValidations.validate( DeviceProfile.class, null, mDeviceProfile); this.mDisplayName = displayName; this.mAssociatedDevice = associatedDevice; this.mSelfManaged = selfManaged; this.mForceConfirmation = forceConfirmation; this.mPackageName = packageName; Loading Loading @@ -648,10 +676,10 @@ public final class AssociationRequest implements Parcelable { }; @DataClass.Generated( time = 1649179640045L, time = 1663088980513L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/companion/AssociationRequest.java", inputSignatures = "public static final java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_APP_STREAMING\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_AUTOMOTIVE_PROJECTION\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_COMPUTER\nprivate final boolean mSingleDevice\nprivate final @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate final @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate final boolean mSelfManaged\nprivate final boolean mForceConfirmation\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.UserIdInt int mUserId\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate final long mCreationTime\nprivate boolean mSkipPrompt\npublic @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String getDeviceProfile()\npublic @android.annotation.Nullable java.lang.CharSequence getDisplayName()\npublic boolean isSelfManaged()\npublic boolean isForceConfirmation()\npublic boolean isSingleDevice()\npublic void setPackageName(java.lang.String)\npublic void setUserId(int)\npublic void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic void setSkipPrompt(boolean)\npublic void setDisplayName(java.lang.CharSequence)\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\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate boolean mSelfManaged\nprivate boolean mForceConfirmation\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 android.companion.AssociationRequest.Builder setDisplayName(java.lang.CharSequence)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setSelfManaged(boolean)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setForceConfirmation(boolean)\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(genConstructor=false, genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genConstDefs=false)") inputSignatures = "public static final java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_APP_STREAMING\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_AUTOMOTIVE_PROJECTION\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_COMPUTER\nprivate final boolean mSingleDevice\nprivate final @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate final @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate @android.annotation.Nullable android.companion.AssociatedDevice mAssociatedDevice\nprivate final boolean mSelfManaged\nprivate final boolean mForceConfirmation\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.UserIdInt int mUserId\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate final long mCreationTime\nprivate boolean mSkipPrompt\npublic @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String getDeviceProfile()\npublic @android.annotation.Nullable java.lang.CharSequence getDisplayName()\npublic boolean isSelfManaged()\npublic boolean isForceConfirmation()\npublic boolean isSingleDevice()\npublic void setPackageName(java.lang.String)\npublic void setUserId(int)\npublic void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic void setSkipPrompt(boolean)\npublic void setDisplayName(java.lang.CharSequence)\npublic void setAssociatedDevice(android.companion.AssociatedDevice)\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\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate boolean mSelfManaged\nprivate boolean mForceConfirmation\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 android.companion.AssociationRequest.Builder setDisplayName(java.lang.CharSequence)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setSelfManaged(boolean)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setForceConfirmation(boolean)\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(genConstructor=false, genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genConstDefs=false)") @Deprecated private void __metadata() {} Loading core/java/android/companion/CompanionDeviceManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -145,7 +145,7 @@ public final class CompanionDeviceManager { * <li>for WiFi - {@link android.net.wifi.ScanResult}</li> * </ul> * * @deprecated use {@link #EXTRA_ASSOCIATION} instead. * @deprecated use {@link AssociationInfo#getAssociatedDevice()} instead. */ @Deprecated public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE"; Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -8947,6 +8947,7 @@ package android.companion { public final class AssociationInfo implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.os.Parcelable getAssociatedDevice(); method @Nullable public android.net.MacAddress getDeviceMacAddress(); method @Nullable public String getDeviceProfile(); method @Nullable public CharSequence getDisplayName();
core/java/android/companion/AssociatedDevice.java 0 → 100644 +133 −0 Original line number Diff line number Diff line /* * 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.companion; import android.os.Parcel; import android.os.Parcelable; import androidx.annotation.NonNull; import androidx.annotation.Nullable; /** * Loose wrapper around device parcelable. Device can be one of three types: * * <ul> * <li>for classic Bluetooth - {@link android.bluetooth.BluetoothDevice}</li> * <li>for Bluetooth LE - {@link android.bluetooth.le.ScanResult}</li> * <li>for WiFi - {@link android.net.wifi.ScanResult}</li> * </ul> * * This class serves as temporary wrapper to deliver a loosely-typed parcelable object from * {@link com.android.companiondevicemanager.CompanionDeviceActivity} to the Companion app, * and should only be used internally. * * @hide */ public final class AssociatedDevice implements Parcelable { private static final int CLASSIC_BLUETOOTH = 0; private static final int BLUETOOTH_LE = 1; private static final int WIFI = 2; @NonNull private final Parcelable mDevice; public AssociatedDevice(@NonNull Parcelable device) { mDevice = device; } private AssociatedDevice(Parcel in) { Creator<? extends Parcelable> creator = getDeviceCreator(in.readInt()); mDevice = creator.createFromParcel(in); } /** * Return device info. Cast to expected device type. */ @NonNull public Parcelable getDevice() { return mDevice; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { // Parcel device type with int for efficiency dest.writeInt(getDeviceType()); mDevice.writeToParcel(dest, flags); } @Override public int describeContents() { return 0; } private int getDeviceType() { if (mDevice instanceof android.bluetooth.BluetoothDevice) return CLASSIC_BLUETOOTH; if (mDevice instanceof android.bluetooth.le.ScanResult) return BLUETOOTH_LE; if (mDevice instanceof android.net.wifi.ScanResult) return WIFI; throw new UnsupportedOperationException("Unsupported device type."); } private static Creator<? extends Parcelable> getDeviceCreator(int deviceType) { switch (deviceType) { case CLASSIC_BLUETOOTH: return android.bluetooth.BluetoothDevice.CREATOR; case BLUETOOTH_LE: return android.bluetooth.le.ScanResult.CREATOR; case WIFI: return android.net.wifi.ScanResult.CREATOR; default: throw new UnsupportedOperationException("Unsupported device type."); } } @NonNull public static final Parcelable.Creator<AssociatedDevice> CREATOR = new Parcelable.Creator<AssociatedDevice>() { @Override public AssociatedDevice[] newArray(int size) { return new AssociatedDevice[size]; } @Override public AssociatedDevice createFromParcel(@NonNull Parcel in) { return new AssociatedDevice(in); } }; @Override public String toString() { return "AssociatedDevice { " + "device = " + mDevice + " }"; } @Override public boolean equals(@Nullable Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AssociatedDevice that = (AssociatedDevice) o; if (getDeviceType() != that.getDeviceType()) return false; // TODO(b/31972115): Take out this whole part ¯\_(ツ)_/¯ if (mDevice instanceof android.bluetooth.le.ScanResult || mDevice instanceof android.net.wifi.ScanResult) { return mDevice.toString().equals(that.mDevice.toString()); } return java.util.Objects.equals(mDevice, that.mDevice); } @Override public int hashCode() { return java.util.Objects.hash(mDevice); } }
core/java/android/companion/AssociationInfo.java +31 −5 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ public final class AssociationInfo implements Parcelable { private final @Nullable MacAddress mDeviceMacAddress; private final @Nullable CharSequence mDisplayName; private final @Nullable String mDeviceProfile; private final @Nullable AssociatedDevice mAssociatedDevice; private final boolean mSelfManaged; private final boolean mNotifyOnDeviceNearby; Loading @@ -78,8 +79,9 @@ public final class AssociationInfo implements Parcelable { */ public AssociationInfo(int id, @UserIdInt int userId, @NonNull String packageName, @Nullable MacAddress macAddress, @Nullable CharSequence displayName, @Nullable String deviceProfile, boolean selfManaged, boolean notifyOnDeviceNearby, boolean revoked, long timeApprovedMs, long lastTimeConnectedMs) { @Nullable String deviceProfile, @Nullable AssociatedDevice associatedDevice, boolean selfManaged, boolean notifyOnDeviceNearby, boolean revoked, long timeApprovedMs, long lastTimeConnectedMs) { if (id <= 0) { throw new IllegalArgumentException("Association ID should be greater than 0"); } Loading @@ -96,6 +98,7 @@ public final class AssociationInfo implements Parcelable { mDeviceMacAddress = macAddress; mDisplayName = displayName; mDeviceProfile = deviceProfile; mAssociatedDevice = associatedDevice; mSelfManaged = selfManaged; mNotifyOnDeviceNearby = notifyOnDeviceNearby; Loading Loading @@ -159,6 +162,24 @@ public final class AssociationInfo implements Parcelable { return mDeviceProfile; } /** * Companion device that was associated. Note that this field is not persisted across sessions. * * Cast to expected device type before use: * * <ul> * <li>for classic Bluetooth - {@link android.bluetooth.BluetoothDevice}</li> * <li>for Bluetooth LE - {@link android.bluetooth.le.ScanResult}</li> * <li>for WiFi - {@link android.net.wifi.ScanResult}</li> * </ul> * * @return the companion device that was associated, or {@code null} if the device is * self-managed. */ public @Nullable Parcelable getAssociatedDevice() { return mAssociatedDevice == null ? null : mAssociatedDevice.getDevice(); } /** * @return whether the association is managed by the companion application it belongs to. * @see AssociationRequest.Builder#setSelfManaged(boolean) Loading Loading @@ -260,6 +281,7 @@ public final class AssociationInfo implements Parcelable { + ", mDisplayName='" + mDisplayName + '\'' + ", mDeviceProfile='" + mDeviceProfile + '\'' + ", mSelfManaged=" + mSelfManaged + ", mAssociatedDevice=" + mAssociatedDevice + ", mNotifyOnDeviceNearby=" + mNotifyOnDeviceNearby + ", mRevoked=" + mRevoked + ", mTimeApprovedMs=" + new Date(mTimeApprovedMs) Loading @@ -284,14 +306,15 @@ public final class AssociationInfo implements Parcelable { && Objects.equals(mPackageName, that.mPackageName) && Objects.equals(mDeviceMacAddress, that.mDeviceMacAddress) && Objects.equals(mDisplayName, that.mDisplayName) && Objects.equals(mDeviceProfile, that.mDeviceProfile); && Objects.equals(mDeviceProfile, that.mDeviceProfile) && Objects.equals(mAssociatedDevice, that.mAssociatedDevice); } @Override public int hashCode() { return Objects.hash(mId, mUserId, mPackageName, mDeviceMacAddress, mDisplayName, mDeviceProfile, mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mTimeApprovedMs, mLastTimeConnectedMs); mDeviceProfile, mAssociatedDevice, mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mTimeApprovedMs, mLastTimeConnectedMs); } @Override Loading @@ -309,6 +332,7 @@ public final class AssociationInfo implements Parcelable { dest.writeTypedObject(mDeviceMacAddress, 0); dest.writeCharSequence(mDisplayName); dest.writeString(mDeviceProfile); dest.writeTypedObject(mAssociatedDevice, 0); dest.writeBoolean(mSelfManaged); dest.writeBoolean(mNotifyOnDeviceNearby); Loading @@ -326,6 +350,7 @@ public final class AssociationInfo implements Parcelable { mDeviceMacAddress = in.readTypedObject(MacAddress.CREATOR); mDisplayName = in.readCharSequence(); mDeviceProfile = in.readString(); mAssociatedDevice = in.readTypedObject(AssociatedDevice.CREATOR); mSelfManaged = in.readBoolean(); mNotifyOnDeviceNearby = in.readBoolean(); Loading Loading @@ -433,6 +458,7 @@ public final class AssociationInfo implements Parcelable { mOriginalInfo.mDeviceMacAddress, mOriginalInfo.mDisplayName, mOriginalInfo.mDeviceProfile, mOriginalInfo.mAssociatedDevice, mOriginalInfo.mSelfManaged, mNotifyOnDeviceNearby, mRevoked, Loading
core/java/android/companion/AssociationRequest.java +40 −12 Original line number Diff line number Diff line Loading @@ -153,6 +153,11 @@ public final class AssociationRequest implements Parcelable { */ private @Nullable CharSequence mDisplayName; /** * The device that was associated. Will be null for "self-managed" association. */ private @Nullable AssociatedDevice mAssociatedDevice; /** * Whether the association is to be managed by the companion application. */ Loading Loading @@ -306,6 +311,11 @@ public final class AssociationRequest implements Parcelable { mDisplayName = displayName; } /** @hide */ public void setAssociatedDevice(AssociatedDevice associatedDevice) { mAssociatedDevice = associatedDevice; } /** @hide */ @NonNull @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Loading Loading @@ -438,6 +448,16 @@ public final class AssociationRequest implements Parcelable { //@formatter:off /** * The device that was associated. Will be null for "self-managed" association. * * @hide */ @DataClass.Generated.Member public @Nullable AssociatedDevice getAssociatedDevice() { return mAssociatedDevice; } /** * The app package name of the application the association will belong to. * Populated by the system. Loading Loading @@ -503,6 +523,7 @@ public final class AssociationRequest implements Parcelable { "deviceFilters = " + mDeviceFilters + ", " + "deviceProfile = " + mDeviceProfile + ", " + "displayName = " + mDisplayName + ", " + "associatedDevice = " + mAssociatedDevice + ", " + "selfManaged = " + mSelfManaged + ", " + "forceConfirmation = " + mForceConfirmation + ", " + "packageName = " + mPackageName + ", " + Loading Loading @@ -530,6 +551,7 @@ public final class AssociationRequest implements Parcelable { && Objects.equals(mDeviceFilters, that.mDeviceFilters) && Objects.equals(mDeviceProfile, that.mDeviceProfile) && Objects.equals(mDisplayName, that.mDisplayName) && Objects.equals(mAssociatedDevice, that.mAssociatedDevice) && mSelfManaged == that.mSelfManaged && mForceConfirmation == that.mForceConfirmation && Objects.equals(mPackageName, that.mPackageName) Loading @@ -550,6 +572,7 @@ public final class AssociationRequest implements Parcelable { _hash = 31 * _hash + Objects.hashCode(mDeviceFilters); _hash = 31 * _hash + Objects.hashCode(mDeviceProfile); _hash = 31 * _hash + Objects.hashCode(mDisplayName); _hash = 31 * _hash + Objects.hashCode(mAssociatedDevice); _hash = 31 * _hash + Boolean.hashCode(mSelfManaged); _hash = 31 * _hash + Boolean.hashCode(mForceConfirmation); _hash = 31 * _hash + Objects.hashCode(mPackageName); Loading @@ -568,17 +591,19 @@ public final class AssociationRequest implements Parcelable { int flg = 0; if (mSingleDevice) flg |= 0x1; if (mSelfManaged) flg |= 0x10; if (mForceConfirmation) flg |= 0x20; if (mSkipPrompt) flg |= 0x400; if (mSelfManaged) flg |= 0x20; if (mForceConfirmation) flg |= 0x40; if (mSkipPrompt) flg |= 0x800; if (mDeviceProfile != null) flg |= 0x4; if (mDisplayName != null) flg |= 0x8; if (mPackageName != null) flg |= 0x40; if (mDeviceProfilePrivilegesDescription != null) flg |= 0x100; if (mAssociatedDevice != null) flg |= 0x10; if (mPackageName != null) flg |= 0x80; if (mDeviceProfilePrivilegesDescription != null) flg |= 0x200; dest.writeInt(flg); dest.writeParcelableList(mDeviceFilters, flags); if (mDeviceProfile != null) dest.writeString(mDeviceProfile); if (mDisplayName != null) dest.writeCharSequence(mDisplayName); if (mAssociatedDevice != null) dest.writeTypedObject(mAssociatedDevice, flags); if (mPackageName != null) dest.writeString(mPackageName); dest.writeInt(mUserId); if (mDeviceProfilePrivilegesDescription != null) dest.writeString(mDeviceProfilePrivilegesDescription); Loading @@ -598,18 +623,20 @@ public final class AssociationRequest implements Parcelable { int flg = in.readInt(); boolean singleDevice = (flg & 0x1) != 0; boolean selfManaged = (flg & 0x10) != 0; boolean forceConfirmation = (flg & 0x20) != 0; boolean skipPrompt = (flg & 0x400) != 0; boolean selfManaged = (flg & 0x20) != 0; boolean forceConfirmation = (flg & 0x40) != 0; boolean skipPrompt = (flg & 0x800) != 0; List<DeviceFilter<?>> deviceFilters = new ArrayList<>(); in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader(), (Class<android.companion.DeviceFilter<?>>) (Class<?>) android.companion.DeviceFilter.class); String deviceProfile = (flg & 0x4) == 0 ? null : in.readString(); CharSequence displayName = (flg & 0x8) == 0 ? null : (CharSequence) in.readCharSequence(); String packageName = (flg & 0x40) == 0 ? null : in.readString(); AssociatedDevice associatedDevice = (flg & 0x10) == 0 ? null : (AssociatedDevice) in.readTypedObject(AssociatedDevice.CREATOR); String packageName = (flg & 0x80) == 0 ? null : in.readString(); int userId = in.readInt(); String deviceProfilePrivilegesDescription = (flg & 0x100) == 0 ? null : in.readString(); String deviceProfilePrivilegesDescription = (flg & 0x200) == 0 ? null : in.readString(); long creationTime = in.readLong(); this.mSingleDevice = singleDevice; Loading @@ -620,6 +647,7 @@ public final class AssociationRequest implements Parcelable { com.android.internal.util.AnnotationValidations.validate( DeviceProfile.class, null, mDeviceProfile); this.mDisplayName = displayName; this.mAssociatedDevice = associatedDevice; this.mSelfManaged = selfManaged; this.mForceConfirmation = forceConfirmation; this.mPackageName = packageName; Loading Loading @@ -648,10 +676,10 @@ public final class AssociationRequest implements Parcelable { }; @DataClass.Generated( time = 1649179640045L, time = 1663088980513L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/companion/AssociationRequest.java", inputSignatures = "public static final java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_APP_STREAMING\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_AUTOMOTIVE_PROJECTION\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_COMPUTER\nprivate final boolean mSingleDevice\nprivate final @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate final @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate final boolean mSelfManaged\nprivate final boolean mForceConfirmation\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.UserIdInt int mUserId\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate final long mCreationTime\nprivate boolean mSkipPrompt\npublic @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String getDeviceProfile()\npublic @android.annotation.Nullable java.lang.CharSequence getDisplayName()\npublic boolean isSelfManaged()\npublic boolean isForceConfirmation()\npublic boolean isSingleDevice()\npublic void setPackageName(java.lang.String)\npublic void setUserId(int)\npublic void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic void setSkipPrompt(boolean)\npublic void setDisplayName(java.lang.CharSequence)\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\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate boolean mSelfManaged\nprivate boolean mForceConfirmation\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 android.companion.AssociationRequest.Builder setDisplayName(java.lang.CharSequence)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setSelfManaged(boolean)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setForceConfirmation(boolean)\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(genConstructor=false, genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genConstDefs=false)") inputSignatures = "public static final java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_APP_STREAMING\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_AUTOMOTIVE_PROJECTION\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_COMPUTER\nprivate final boolean mSingleDevice\nprivate final @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate final @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate @android.annotation.Nullable android.companion.AssociatedDevice mAssociatedDevice\nprivate final boolean mSelfManaged\nprivate final boolean mForceConfirmation\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.UserIdInt int mUserId\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate final long mCreationTime\nprivate boolean mSkipPrompt\npublic @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String getDeviceProfile()\npublic @android.annotation.Nullable java.lang.CharSequence getDisplayName()\npublic boolean isSelfManaged()\npublic boolean isForceConfirmation()\npublic boolean isSingleDevice()\npublic void setPackageName(java.lang.String)\npublic void setUserId(int)\npublic void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic void setSkipPrompt(boolean)\npublic void setDisplayName(java.lang.CharSequence)\npublic void setAssociatedDevice(android.companion.AssociatedDevice)\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\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate boolean mSelfManaged\nprivate boolean mForceConfirmation\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 android.companion.AssociationRequest.Builder setDisplayName(java.lang.CharSequence)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setSelfManaged(boolean)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setForceConfirmation(boolean)\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(genConstructor=false, genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genConstDefs=false)") @Deprecated private void __metadata() {} Loading
core/java/android/companion/CompanionDeviceManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -145,7 +145,7 @@ public final class CompanionDeviceManager { * <li>for WiFi - {@link android.net.wifi.ScanResult}</li> * </ul> * * @deprecated use {@link #EXTRA_ASSOCIATION} instead. * @deprecated use {@link AssociationInfo#getAssociatedDevice()} instead. */ @Deprecated public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE"; Loading