summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt30
-rw-r--r--api/system-current.txt30
-rw-r--r--api/test-current.txt30
-rw-r--r--core/java/android/bluetooth/le/ScanFilter.java12
-rw-r--r--core/java/android/companion/AssociationRequest.java107
-rw-r--r--core/java/android/companion/BluetoothDeviceFilter.java28
-rw-r--r--core/java/android/companion/BluetoothDeviceFilterUtils.java41
-rw-r--r--core/java/android/companion/BluetoothLEDeviceFilter.java191
-rw-r--r--core/java/android/companion/CompanionDeviceManager.java2
-rw-r--r--core/java/android/companion/DeviceFilter.java24
-rw-r--r--core/java/android/companion/WifiDeviceFilter.java125
-rw-r--r--core/java/android/os/Parcel.java15
-rw-r--r--core/java/android/text/TextUtils.java5
-rw-r--r--core/java/com/android/internal/util/ArrayUtils.java29
-rw-r--r--core/java/com/android/internal/util/BitUtils.java58
-rw-r--r--packages/CompanionDeviceManager/AndroidManifest.xml2
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java16
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java197
-rw-r--r--services/print/java/com/android/server/print/CompanionDeviceManagerService.java2
19 files changed, 214 insertions, 730 deletions
diff --git a/api/current.txt b/api/current.txt
index 0d38bc6e3d56..1a5ea853b365 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8183,17 +8183,18 @@ package android.bluetooth.le {
package android.companion {
- public final class AssociationRequest implements android.os.Parcelable {
+ public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
}
- public static final class AssociationRequest.Builder {
- ctor public AssociationRequest.Builder();
- method public android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>);
- method public android.companion.AssociationRequest build();
- method public android.companion.AssociationRequest.Builder setSingleDevice(boolean);
+ public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+ method public android.companion.AssociationRequest<F> build();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+ method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+ method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
}
public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
@@ -8214,20 +8215,17 @@ package android.companion {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
- field public static final int RENAME_PREFIX_LENGTH_LIMIT = 10; // 0xa
}
public static final class BluetoothLEDeviceFilter.Builder {
ctor public BluetoothLEDeviceFilter.Builder();
method public android.companion.BluetoothLEDeviceFilter build();
method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
- method public android.companion.BluetoothLEDeviceFilter.Builder setRawDataFilter(byte[], byte[]);
- method public android.companion.BluetoothLEDeviceFilter.Builder setRename(java.lang.String, java.lang.String, int, int, boolean);
method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
}
public final class CompanionDeviceManager {
- method public void associate(android.companion.AssociationRequest, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+ method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
method public void disassociate(java.lang.String);
method public java.util.List<java.lang.String> getAssociations();
field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -8242,18 +8240,6 @@ package android.companion {
public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
}
- public final class WifiDeviceFilter implements android.companion.DeviceFilter {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.companion.WifiDeviceFilter> CREATOR;
- }
-
- public static final class WifiDeviceFilter.Builder {
- ctor public WifiDeviceFilter.Builder();
- method public android.companion.WifiDeviceFilter build();
- method public android.companion.WifiDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
- }
-
}
package android.content {
diff --git a/api/system-current.txt b/api/system-current.txt
index 16de51039ff4..b5c20e52e913 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8683,17 +8683,18 @@ package android.bluetooth.le {
package android.companion {
- public final class AssociationRequest implements android.os.Parcelable {
+ public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
}
- public static final class AssociationRequest.Builder {
- ctor public AssociationRequest.Builder();
- method public android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>);
- method public android.companion.AssociationRequest build();
- method public android.companion.AssociationRequest.Builder setSingleDevice(boolean);
+ public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+ method public android.companion.AssociationRequest<F> build();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+ method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+ method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
}
public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
@@ -8714,20 +8715,17 @@ package android.companion {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
- field public static final int RENAME_PREFIX_LENGTH_LIMIT = 10; // 0xa
}
public static final class BluetoothLEDeviceFilter.Builder {
ctor public BluetoothLEDeviceFilter.Builder();
method public android.companion.BluetoothLEDeviceFilter build();
method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
- method public android.companion.BluetoothLEDeviceFilter.Builder setRawDataFilter(byte[], byte[]);
- method public android.companion.BluetoothLEDeviceFilter.Builder setRename(java.lang.String, java.lang.String, int, int, boolean);
method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
}
public final class CompanionDeviceManager {
- method public void associate(android.companion.AssociationRequest, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+ method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
method public void disassociate(java.lang.String);
method public java.util.List<java.lang.String> getAssociations();
field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -8742,18 +8740,6 @@ package android.companion {
public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
}
- public final class WifiDeviceFilter implements android.companion.DeviceFilter {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.companion.WifiDeviceFilter> CREATOR;
- }
-
- public static final class WifiDeviceFilter.Builder {
- ctor public WifiDeviceFilter.Builder();
- method public android.companion.WifiDeviceFilter build();
- method public android.companion.WifiDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
- }
-
}
package android.content {
diff --git a/api/test-current.txt b/api/test-current.txt
index 62f76bde349d..57cc998ffb5d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -8210,17 +8210,18 @@ package android.bluetooth.le {
package android.companion {
- public final class AssociationRequest implements android.os.Parcelable {
+ public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
}
- public static final class AssociationRequest.Builder {
- ctor public AssociationRequest.Builder();
- method public android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>);
- method public android.companion.AssociationRequest build();
- method public android.companion.AssociationRequest.Builder setSingleDevice(boolean);
+ public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+ method public android.companion.AssociationRequest<F> build();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+ method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+ method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+ method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
}
public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
@@ -8241,20 +8242,17 @@ package android.companion {
method public int describeContents();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
- field public static final int RENAME_PREFIX_LENGTH_LIMIT = 10; // 0xa
}
public static final class BluetoothLEDeviceFilter.Builder {
ctor public BluetoothLEDeviceFilter.Builder();
method public android.companion.BluetoothLEDeviceFilter build();
method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
- method public android.companion.BluetoothLEDeviceFilter.Builder setRawDataFilter(byte[], byte[]);
- method public android.companion.BluetoothLEDeviceFilter.Builder setRename(java.lang.String, java.lang.String, int, int, boolean);
method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
}
public final class CompanionDeviceManager {
- method public void associate(android.companion.AssociationRequest, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+ method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
method public void disassociate(java.lang.String);
method public java.util.List<java.lang.String> getAssociations();
field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -8269,18 +8267,6 @@ package android.companion {
public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
}
- public final class WifiDeviceFilter implements android.companion.DeviceFilter {
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.companion.WifiDeviceFilter> CREATOR;
- }
-
- public static final class WifiDeviceFilter.Builder {
- ctor public WifiDeviceFilter.Builder();
- method public android.companion.WifiDeviceFilter build();
- method public android.companion.WifiDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
- }
-
}
package android.content {
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 457096bf843e..b89c64a8cac6 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -23,8 +23,6 @@ import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;
-import com.android.internal.util.BitUtils;
-
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -347,7 +345,15 @@ public final class ScanFilter implements Parcelable {
// Check if the uuid pattern matches the particular service uuid.
private static boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
- return BitUtils.maskedEquals(data, uuid, mask);
+ if (mask == null) {
+ return uuid.equals(data);
+ }
+ if ((uuid.getLeastSignificantBits() & mask.getLeastSignificantBits()) !=
+ (data.getLeastSignificantBits() & mask.getLeastSignificantBits())) {
+ return false;
+ }
+ return ((uuid.getMostSignificantBits() & mask.getMostSignificantBits()) ==
+ (data.getMostSignificantBits() & mask.getMostSignificantBits()));
}
// Check whether the data pattern matches the parsed data.
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index 56f5d4483270..d477f43ac8c2 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -16,21 +16,20 @@
package android.companion;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.OneTimeUseBuilder;
-import com.android.internal.util.ArrayUtils;
-
-import java.util.ArrayList;
-import java.util.List;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* A request for the user to select a companion device to associate with.
*
- * You can optionally set {@link Builder#addDeviceFilter filters} for which devices to show to the
+ * You can optionally set a {@link Builder#setDeviceFilter filter} for which devices to show to the
* user to select from.
* The exact type and fields of the filter you can set depend on the
* medium type. See {@link Builder}'s static factory methods for specific protocols that are
@@ -38,22 +37,38 @@ import java.util.List;
*
* 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
+ *
+ * @param <F> Device filter type
*/
-public final class AssociationRequest implements Parcelable {
+public final class AssociationRequest<F extends DeviceFilter> implements Parcelable {
+
+ /** @hide */
+ public static final int MEDIUM_TYPE_BLUETOOTH = 0;
+ /** @hide */
+ public static final int MEDIUM_TYPE_BLUETOOTH_LE = 1;
+ /** @hide */
+ public static final int MEDIUM_TYPE_WIFI = 2;
+
+ /** @hide */
+ @IntDef({MEDIUM_TYPE_BLUETOOTH, MEDIUM_TYPE_BLUETOOTH_LE, MEDIUM_TYPE_WIFI})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MediumType {}
private final boolean mSingleDevice;
- private final List<DeviceFilter<?>> mDeviceFilters;
+ private final int mMediumType;
+ private final F mDeviceFilter;
- private AssociationRequest(
- boolean singleDevice, @Nullable List<DeviceFilter<?>> deviceFilters) {
+ private AssociationRequest(boolean singleDevice, int mMediumType, F deviceFilter) {
this.mSingleDevice = singleDevice;
- this.mDeviceFilters = ArrayUtils.emptyIfNull(deviceFilters);
+ this.mMediumType = mMediumType;
+ this.mDeviceFilter = deviceFilter;
}
private AssociationRequest(Parcel in) {
this(
in.readByte() != 0,
- in.readParcelableList(new ArrayList<>(), AssociationRequest.class.getClassLoader()));
+ in.readInt(),
+ in.readParcelable(AssociationRequest.class.getClassLoader()));
}
/** @hide */
@@ -62,15 +77,22 @@ public final class AssociationRequest implements Parcelable {
}
/** @hide */
- @NonNull
- public List<DeviceFilter<?>> getDeviceFilters() {
- return mDeviceFilters;
+ @MediumType
+ public int getMediumType() {
+ return mMediumType;
+ }
+
+ /** @hide */
+ @Nullable
+ public F getDeviceFilter() {
+ return mDeviceFilter;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (mSingleDevice ? 1 : 0));
- dest.writeParcelableList(mDeviceFilters, flags);
+ dest.writeInt(mMediumType);
+ dest.writeParcelable(mDeviceFilter, flags);
}
@Override
@@ -92,19 +114,45 @@ public final class AssociationRequest implements Parcelable {
/**
* A builder for {@link AssociationRequest}
+ *
+ * @param <F> the type of filter for the request.
*/
- public static final class Builder extends OneTimeUseBuilder<AssociationRequest> {
+ public static final class Builder<F extends DeviceFilter>
+ extends OneTimeUseBuilder<AssociationRequest<F>> {
private boolean mSingleDevice = false;
- @Nullable private ArrayList<DeviceFilter<?>> mDeviceFilters = null;
+ @MediumType private int mMediumType;
+ @Nullable private F mDeviceFilter = null;
+
+ private Builder() {}
+
+ /**
+ * Create a new builder for an association request with a Bluetooth LE device
+ */
+ @NonNull
+ public static Builder<BluetoothLEDeviceFilter> createForBluetoothLEDevice() {
+ return new Builder<BluetoothLEDeviceFilter>()
+ .setMediumType(MEDIUM_TYPE_BLUETOOTH_LE);
+ }
+
+ /**
+ * Create a new builder for an association request with a Bluetooth(non-LE) device
+ */
+ @NonNull
+ public static Builder<BluetoothDeviceFilter> createForBluetoothDevice() {
+ return new Builder<BluetoothDeviceFilter>()
+ .setMediumType(MEDIUM_TYPE_BLUETOOTH);
+ }
- public Builder() {}
+ //TODO implement, once specific filter classes are available
+// public static Builder<> createForWiFiDevice()
+// public static Builder<> createForNanDevice()
/**
* @param singleDevice if true, scanning for a device will stop as soon as at least one
* fitting device is found
*/
@NonNull
- public Builder setSingleDevice(boolean singleDevice) {
+ public Builder<F> setSingleDevice(boolean singleDevice) {
checkNotUsed();
this.mSingleDevice = singleDevice;
return this;
@@ -115,20 +163,29 @@ public final class AssociationRequest implements Parcelable {
* user
*/
@NonNull
- public Builder addDeviceFilter(@Nullable DeviceFilter<?> deviceFilter) {
+ public Builder<F> setDeviceFilter(@Nullable F deviceFilter) {
checkNotUsed();
- if (deviceFilter != null) {
- mDeviceFilters = ArrayUtils.add(mDeviceFilters, deviceFilter);
- }
+ this.mDeviceFilter = deviceFilter;
+ return this;
+ }
+
+ /**
+ * @param deviceType A type of medium over which to discover devices
+ *
+ * @see MediumType
+ */
+ @NonNull
+ private Builder<F> setMediumType(@MediumType int deviceType) {
+ mMediumType = deviceType;
return this;
}
/** @inheritDoc */
@NonNull
@Override
- public AssociationRequest build() {
+ public AssociationRequest<F> build() {
markUsed();
- return new AssociationRequest(mSingleDevice, mDeviceFilters);
+ return new AssociationRequest<>(mSingleDevice, mMediumType, mDeviceFilter);
}
}
}
diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java
index 0f16b7b90165..5a69955429aa 100644
--- a/core/java/android/companion/BluetoothDeviceFilter.java
+++ b/core/java/android/companion/BluetoothDeviceFilter.java
@@ -16,7 +16,6 @@
package android.companion;
-import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
import static android.companion.BluetoothDeviceFilterUtils.matchesAddress;
import static android.companion.BluetoothDeviceFilterUtils.matchesName;
import static android.companion.BluetoothDeviceFilterUtils.matchesServiceUuids;
@@ -41,6 +40,8 @@ import java.util.regex.Pattern;
*/
public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice> {
+ private static BluetoothDeviceFilter NO_OP;
+
private final Pattern mNamePattern;
private final String mAddress;
private final List<ParcelUuid> mServiceUuids;
@@ -66,27 +67,30 @@ public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice
}
private static List<ParcelUuid> readUuids(Parcel in) {
- return in.readParcelableList(new ArrayList<>(), ParcelUuid.class.getClassLoader());
+ final ArrayList<ParcelUuid> list = new ArrayList<>();
+ in.readParcelableList(list, ParcelUuid.class.getClassLoader());
+ return list;
}
/** @hide */
- @Override
- public boolean matches(BluetoothDevice device) {
- return matchesAddress(mAddress, device)
- && matchesServiceUuids(mServiceUuids, mServiceUuidMasks, device)
- && matchesName(getNamePattern(), device);
+ @NonNull
+ public static BluetoothDeviceFilter nullsafe(@Nullable BluetoothDeviceFilter nullable) {
+ return nullable != null ? nullable : noOp();
}
/** @hide */
- @Override
- public String getDeviceDisplayName(BluetoothDevice device) {
- return getDeviceDisplayNameInternal(device);
+ @NonNull
+ public static BluetoothDeviceFilter noOp() {
+ if (NO_OP == null) NO_OP = new Builder().build();
+ return NO_OP;
}
/** @hide */
@Override
- public int getMediumType() {
- return DeviceFilter.MEDIUM_TYPE_BLUETOOTH;
+ public boolean matches(BluetoothDevice device) {
+ return matchesAddress(mAddress, device)
+ && matchesServiceUuids(mServiceUuids, mServiceUuidMasks, device)
+ && matchesName(getNamePattern(), device);
}
/** @hide */
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
index 8a316f19af8e..289f9953a068 100644
--- a/core/java/android/companion/BluetoothDeviceFilterUtils.java
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -23,9 +23,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanFilter;
-import android.net.wifi.ScanResult;
import android.os.ParcelUuid;
-import android.os.Parcelable;
import android.util.Log;
import java.util.Arrays;
@@ -98,47 +96,12 @@ public class BluetoothDeviceFilterUtils {
return result;
}
- static boolean matchesName(@Nullable Pattern namePattern, ScanResult device) {
- boolean result;
- if (namePattern == null) {
- result = true;
- } else if (device == null) {
- result = false;
- } else {
- final String name = device.SSID;
- result = name != null && namePattern.matcher(name).find();
- }
- if (DEBUG) debugLogMatchResult(result, device, namePattern);
- return result;
- }
-
private static void debugLogMatchResult(
boolean result, BluetoothDevice device, Object criteria) {
- Log.i(LOG_TAG, getDeviceDisplayNameInternal(device) + (result ? " ~ " : " !~ ") + criteria);
+ Log.i(LOG_TAG, getDeviceDisplayName(device) + (result ? " ~ " : " !~ ") + criteria);
}
- private static void debugLogMatchResult(
- boolean result, ScanResult device, Object criteria) {
- Log.i(LOG_TAG, getDeviceDisplayNameInternal(device) + (result ? " ~ " : " !~ ") + criteria);
- }
-
- public static String getDeviceDisplayNameInternal(@NonNull BluetoothDevice device) {
+ public static String getDeviceDisplayName(@NonNull BluetoothDevice device) {
return firstNotEmpty(device.getAliasName(), device.getAddress());
}
-
- public static String getDeviceDisplayNameInternal(@NonNull ScanResult device) {
- return firstNotEmpty(device.SSID, device.BSSID);
- }
-
- public static String getDeviceMacAddress(@NonNull Parcelable device) {
- if (device instanceof BluetoothDevice) {
- return ((BluetoothDevice) device).getAddress();
- } else if (device instanceof ScanResult) {
- return ((ScanResult) device).BSSID;
- } else if (device instanceof android.bluetooth.le.ScanResult) {
- return getDeviceMacAddress(((android.bluetooth.le.ScanResult) device).getDevice());
- } else {
- throw new IllegalArgumentException("Unknown device type: " + device);
- }
- }
}
diff --git a/core/java/android/companion/BluetoothLEDeviceFilter.java b/core/java/android/companion/BluetoothLEDeviceFilter.java
index e057fbcc901a..4a481ca80045 100644
--- a/core/java/android/companion/BluetoothLEDeviceFilter.java
+++ b/core/java/android/companion/BluetoothLEDeviceFilter.java
@@ -16,25 +16,18 @@
package android.companion;
-import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
import static android.companion.BluetoothDeviceFilterUtils.patternFromString;
import static android.companion.BluetoothDeviceFilterUtils.patternToString;
-import static com.android.internal.util.Preconditions.checkArgument;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanFilter;
-import android.bluetooth.le.ScanRecord;
-import android.bluetooth.le.ScanResult;
import android.os.Parcel;
import android.provider.OneTimeUseBuilder;
-import android.text.TextUtils;
-import com.android.internal.util.BitUtils;
import com.android.internal.util.ObjectUtils;
-import com.android.internal.util.Preconditions;
import java.util.regex.Pattern;
@@ -43,122 +36,57 @@ import java.util.regex.Pattern;
*
* @see ScanFilter
*/
-public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
+public final class BluetoothLEDeviceFilter implements DeviceFilter<BluetoothDevice> {
- private static final int RENAME_PREFIX_LENGTH_LIMIT = 10;
+ private static BluetoothLEDeviceFilter NO_OP;
private final Pattern mNamePattern;
private final ScanFilter mScanFilter;
- private final byte[] mRawDataFilter;
- private final byte[] mRawDataFilterMask;
- private final String mRenamePrefix;
- private final String mRenameSuffix;
- private final int mRenameBytesFrom;
- private final int mRenameBytesTo;
- private final boolean mRenameBytesReverseOrder;
- private BluetoothLEDeviceFilter(Pattern namePattern, ScanFilter scanFilter,
- byte[] rawDataFilter, byte[] rawDataFilterMask, String renamePrefix,
- String renameSuffix, int renameBytesFrom, int renameBytesTo,
- boolean renameBytesReverseOrder) {
+ private BluetoothLEDeviceFilter(Pattern namePattern, ScanFilter scanFilter) {
mNamePattern = namePattern;
mScanFilter = ObjectUtils.firstNotNull(scanFilter, ScanFilter.EMPTY);
- mRawDataFilter = rawDataFilter;
- mRawDataFilterMask = rawDataFilterMask;
- mRenamePrefix = renamePrefix;
- mRenameSuffix = renameSuffix;
- mRenameBytesFrom = renameBytesFrom;
- mRenameBytesTo = renameBytesTo;
- mRenameBytesReverseOrder = renameBytesReverseOrder;
}
- /** @hide */
- @Nullable
- public Pattern getNamePattern() {
- return mNamePattern;
+ @SuppressLint("ParcelClassLoader")
+ private BluetoothLEDeviceFilter(Parcel in) {
+ this(
+ patternFromString(in.readString()),
+ in.readParcelable(null));
}
/** @hide */
@NonNull
- public ScanFilter getScanFilter() {
- return mScanFilter;
- }
-
- /** @hide */
- @Nullable
- public byte[] getRawDataFilter() {
- return mRawDataFilter;
- }
-
- /** @hide */
- @Nullable
- public byte[] getRawDataFilterMask() {
- return mRawDataFilterMask;
+ public static BluetoothLEDeviceFilter nullsafe(@Nullable BluetoothLEDeviceFilter nullable) {
+ return nullable != null ? nullable : noOp();
}
/** @hide */
- @Nullable
- public String getRenamePrefix() {
- return mRenamePrefix;
+ @NonNull
+ public static BluetoothLEDeviceFilter noOp() {
+ if (NO_OP == null) NO_OP = new Builder().build();
+ return NO_OP;
}
/** @hide */
@Nullable
- public String getRenameSuffix() {
- return mRenameSuffix;
- }
-
- /** @hide */
- public int getRenameBytesFrom() {
- return mRenameBytesFrom;
- }
-
- /** @hide */
- public int getRenameBytesTo() {
- return mRenameBytesTo;
- }
-
- /** @hide */
- public boolean isRenameBytesReverseOrder() {
- return mRenameBytesReverseOrder;
+ public Pattern getNamePattern() {
+ return mNamePattern;
}
/** @hide */
- @Override
- @Nullable
- public String getDeviceDisplayName(ScanResult sr) {
- if (mRenameBytesFrom < 0) return getDeviceDisplayNameInternal(sr.getDevice());
- final byte[] bytes = sr.getScanRecord().getBytes();
- final StringBuilder sb = new StringBuilder(TextUtils.emptyIfNull(mRenamePrefix));
- int startInclusive = mRenameBytesFrom;
- int endInclusive = mRenameBytesTo - 1;
- int initial = mRenameBytesReverseOrder ? endInclusive : startInclusive;
- int step = mRenameBytesReverseOrder ? -1 : 1;
- for (int i = initial; startInclusive <= i && i <= endInclusive; i+=step) {
- sb.append(Byte.toHexString(bytes[i], true));
- }
- return sb.append(TextUtils.emptyIfNull(mRenameSuffix)).toString();
+ @NonNull
+ public ScanFilter getScanFilter() {
+ return mScanFilter;
}
/** @hide */
@Override
- public boolean matches(ScanResult device) {
- return matches(device.getDevice())
- && BitUtils.maskedEquals(device.getScanRecord().getBytes(),
- mRawDataFilter, mRawDataFilterMask);
- }
-
- private boolean matches(BluetoothDevice device) {
+ public boolean matches(BluetoothDevice device) {
return BluetoothDeviceFilterUtils.matches(getScanFilter(), device)
&& BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device);
}
- /** @hide */
- @Override
- public int getMediumType() {
- return DeviceFilter.MEDIUM_TYPE_BLUETOOTH_LE;
- }
-
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(patternToString(getNamePattern()));
@@ -174,13 +102,7 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
= new Creator<BluetoothLEDeviceFilter>() {
@Override
public BluetoothLEDeviceFilter createFromParcel(Parcel in) {
- return new BluetoothLEDeviceFilter.Builder()
- .setNamePattern(patternFromString(in.readString()))
- .setScanFilter(in.readParcelable(null))
- .setRawDataFilter(in.readBlob(), in.readBlob())
- .setRename(in.readString(), in.readString(),
- in.readInt(), in.readInt(), in.readBoolean())
- .build();
+ return new BluetoothLEDeviceFilter(in);
}
@Override
@@ -189,28 +111,16 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
}
};
- public static int getRenamePrefixLengthLimit() {
- return RENAME_PREFIX_LENGTH_LIMIT;
- }
-
/**
* Builder for {@link BluetoothLEDeviceFilter}
*/
public static final class Builder extends OneTimeUseBuilder<BluetoothLEDeviceFilter> {
private ScanFilter mScanFilter;
private Pattern mNamePattern;
- private byte[] mRawDataFilter;
- private byte[] mRawDataFilterMask;
- private String mRenamePrefix;
- private String mRenameSuffix;
- private int mRenameBytesFrom = -1;
- private int mRenameBytesTo;
- private boolean mRenameBytesReverseOrder = false;
/**
* @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
* given regular expression will be shown
- * @return self for chaining
*/
public Builder setNamePattern(@Nullable Pattern regex) {
checkNotUsed();
@@ -221,7 +131,6 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
/**
* @param scanFilter a {@link ScanFilter} to filter devices by
*
- * @return self for chaining
* @see ScanFilter for specific details on its various fields
*/
@NonNull
@@ -231,66 +140,12 @@ public final class BluetoothLEDeviceFilter implements DeviceFilter<ScanResult> {
return this;
}
- /**
- * Filter devices by raw advertisement data, as obtained by {@link ScanRecord#getBytes}
- *
- * @param rawDataFilter bit values that have to match against advertized data
- * @param rawDataFilterMask bits that have to be matched
- * @return self for chaining
- */
- @NonNull
- public Builder setRawDataFilter(@NonNull byte[] rawDataFilter,
- @NonNull byte[] rawDataFilterMask) {
- checkNotUsed();
- checkArgument(rawDataFilter.length == rawDataFilterMask.length,
- "Mask and filter should be the same length");
- mRawDataFilter = Preconditions.checkNotNull(rawDataFilter);
- mRawDataFilterMask = Preconditions.checkNotNull(rawDataFilterMask);
- return this;
- }
-
- /**
- * Rename the devices shown in the list, using specific bytes from the raw advertisement
- * data ({@link ScanRecord#getBytes}) in hexadecimal format, as well as a custom
- * prefix/suffix around them
- *
- * Note that the prefix length is limited to {@link #getRenamePrefixLengthLimit} characters
- * to ensure that there's enough space to display the byte data
- *
- * The range of bytes to be displayed cannot be empty
- *
- * @param prefix to be displayed before the byte data
- * @param suffix to be displayed after the byte data
- * @param bytesFrom the start byte index to be displayed (inclusive)
- * @param bytesTo the end byte index to be displayed (exclusive)
- * @param bytesReverseOrder if true, the byte order of the provided range will be flipped
- * when displaying
- * @return self for chaining
- */
- @NonNull
- public Builder setRename(@NonNull String prefix, @NonNull String suffix,
- int bytesFrom, int bytesTo, boolean bytesReverseOrder) {
- checkNotUsed();
- checkArgument(TextUtils.length(prefix) >= getRenamePrefixLengthLimit(),
- "Prefix is too short");
- mRenamePrefix = prefix;
- mRenameSuffix = suffix;
- checkArgument(bytesFrom < bytesTo, "Byte range must be non-empty");
- mRenameBytesFrom = bytesFrom;
- mRenameBytesTo = bytesTo;
- mRenameBytesReverseOrder = bytesReverseOrder;
- return this;
- }
-
/** @inheritDoc */
@Override
@NonNull
public BluetoothLEDeviceFilter build() {
markUsed();
- return new BluetoothLEDeviceFilter(mNamePattern, mScanFilter,
- mRawDataFilter, mRawDataFilterMask,
- mRenamePrefix, mRenameSuffix,
- mRenameBytesFrom, mRenameBytesTo, mRenameBytesReverseOrder);
+ return new BluetoothLEDeviceFilter(mNamePattern, mScanFilter);
}
}
}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 5710ad1318d7..6fa32b4b6944 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -117,7 +117,7 @@ public final class CompanionDeviceManager {
* @see AssociationRequest
*/
public void associate(
- @NonNull AssociationRequest request,
+ @NonNull AssociationRequest<?> request,
@NonNull Callback callback,
@Nullable Handler handler) {
final Handler finalHandler = handler != null
diff --git a/core/java/android/companion/DeviceFilter.java b/core/java/android/companion/DeviceFilter.java
index 9b4fdfdf5108..8362b2dab8fd 100644
--- a/core/java/android/companion/DeviceFilter.java
+++ b/core/java/android/companion/DeviceFilter.java
@@ -17,28 +17,17 @@
package android.companion;
-import android.annotation.IntDef;
import android.annotation.Nullable;
import android.os.Parcelable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
/**
* A filter for companion devices of type {@code D}
*
* @param <D> Type of devices, filtered by this filter,
- * e.g. {@link android.bluetooth.BluetoothDevice}, {@link android.net.wifi.ScanResult}
+ * e.g. {@link android.bluetooth.BluetoothDevice}, {@link android.net.wifi.WifiInfo}
*/
public interface DeviceFilter<D extends Parcelable> extends Parcelable {
- /** @hide */
- int MEDIUM_TYPE_BLUETOOTH = 0;
- /** @hide */
- int MEDIUM_TYPE_BLUETOOTH_LE = 1;
- /** @hide */
- int MEDIUM_TYPE_WIFI = 2;
-
/**
* @return whether the given device matches this filter
*
@@ -46,12 +35,6 @@ public interface DeviceFilter<D extends Parcelable> extends Parcelable {
*/
boolean matches(D device);
- /** @hide */
- String getDeviceDisplayName(D device);
-
- /** @hide */
- @MediumType int getMediumType();
-
/**
* A nullsafe {@link #matches(Parcelable)}, returning true if the filter is null
*
@@ -60,9 +43,4 @@ public interface DeviceFilter<D extends Parcelable> extends Parcelable {
static <D extends Parcelable> boolean matches(@Nullable DeviceFilter<D> filter, D device) {
return filter == null || filter.matches(device);
}
-
- /** @hide */
- @IntDef({MEDIUM_TYPE_BLUETOOTH, MEDIUM_TYPE_BLUETOOTH_LE, MEDIUM_TYPE_WIFI})
- @Retention(RetentionPolicy.SOURCE)
- @interface MediumType {}
}
diff --git a/core/java/android/companion/WifiDeviceFilter.java b/core/java/android/companion/WifiDeviceFilter.java
deleted file mode 100644
index 1ab9ce11cb0f..000000000000
--- a/core/java/android/companion/WifiDeviceFilter.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2017 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 static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
-import static android.companion.BluetoothDeviceFilterUtils.patternFromString;
-import static android.companion.BluetoothDeviceFilterUtils.patternToString;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SuppressLint;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.le.ScanFilter;
-import android.net.wifi.ScanResult;
-import android.os.Parcel;
-import android.provider.OneTimeUseBuilder;
-
-import java.util.regex.Pattern;
-
-/**
- * A filter for Wifi devices
- *
- * @see ScanFilter
- */
-public final class WifiDeviceFilter implements DeviceFilter<ScanResult> {
-
- private final Pattern mNamePattern;
-
- private WifiDeviceFilter(Pattern namePattern) {
- mNamePattern = namePattern;
- }
-
- @SuppressLint("ParcelClassLoader")
- private WifiDeviceFilter(Parcel in) {
- this(patternFromString(in.readString()));
- }
-
- /** @hide */
- @Nullable
- public Pattern getNamePattern() {
- return mNamePattern;
- }
-
-
- /** @hide */
- @Override
- public boolean matches(ScanResult device) {
- return BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device);
- }
-
- /** @hide */
- @Override
- public String getDeviceDisplayName(ScanResult device) {
- return getDeviceDisplayNameInternal(device);
- }
-
- /** @hide */
- @Override
- public int getMediumType() {
- return MEDIUM_TYPE_WIFI;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(patternToString(getNamePattern()));
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public static final Creator<WifiDeviceFilter> CREATOR
- = new Creator<WifiDeviceFilter>() {
- @Override
- public WifiDeviceFilter createFromParcel(Parcel in) {
- return new WifiDeviceFilter(in);
- }
-
- @Override
- public WifiDeviceFilter[] newArray(int size) {
- return new WifiDeviceFilter[size];
- }
- };
-
- /**
- * Builder for {@link WifiDeviceFilter}
- */
- public static final class Builder extends OneTimeUseBuilder<WifiDeviceFilter> {
- private Pattern mNamePattern;
-
- /**
- * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
- * given regular expression will be shown
- * @return self for chaining
- */
- public Builder setNamePattern(@Nullable Pattern regex) {
- checkNotUsed();
- mNamePattern = regex;
- return this;
- }
-
- /** @inheritDoc */
- @Override
- @NonNull
- public WifiDeviceFilter build() {
- markUsed();
- return new WifiDeviceFilter(mNamePattern);
- }
- }
-}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 7a39d239f84b..f94e89a2785d 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -601,11 +601,6 @@ public final class Parcel {
nativeWriteString(mNativePtr, val);
}
- /** @hide */
- public final void writeBoolean(boolean val) {
- writeInt(val ? 1 : 0);
- }
-
/**
* Write a CharSequence value into the parcel at the current dataPosition(),
* growing dataCapacity() if needed.
@@ -1969,11 +1964,6 @@ public final class Parcel {
return nativeReadString(mNativePtr);
}
- /** @hide */
- public final boolean readBoolean() {
- return readInt() != 0;
- }
-
/**
* Read a CharSequence value from the parcel at the current dataPosition().
* @hide
@@ -2500,11 +2490,11 @@ public final class Parcel {
* @see #writeParcelableList(List, int)
* @hide
*/
- public final <T extends Parcelable> List<T> readParcelableList(List<T> list, ClassLoader cl) {
+ public final <T extends Parcelable> void readParcelableList(List<T> list, ClassLoader cl) {
final int N = readInt();
if (N == -1) {
list.clear();
- return list;
+ return;
}
final int M = list.size();
@@ -2518,7 +2508,6 @@ public final class Parcel {
for (; i<M; i++) {
list.remove(N);
}
- return list;
}
/**
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index ee2b38e4f390..ac9c0d782c53 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -474,11 +474,6 @@ public class TextUtils {
return !isEmpty(a) ? a : Preconditions.checkStringNotEmpty(b);
}
- /** {@hide} */
- public static int length(@Nullable String s) {
- return isEmpty(s) ? 0 : s.length();
- }
-
/**
* Returns the length that the specified CharSequence would have if
* spaces and ASCII control characters were trimmed from the start and end,
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index d0fbe7c8a666..be69d9f808e2 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -237,35 +237,6 @@ public class ArrayUtils {
return false;
}
- @NonNull
- public static <T> List<T> filter(@Nullable List<?> list, Class<T> c) {
- if (isEmpty(list)) return Collections.emptyList();
- ArrayList<T> result = null;
- for (int i = 0; i < list.size(); i++) {
- final Object item = list.get(i);
- if (c.isInstance(item)) {
- result = add(result, (T) item);
- }
- }
- return emptyIfNull(result);
- }
-
- public static <T> boolean any(@Nullable List<T> items,
- java.util.function.Predicate<T> predicate) {
- return find(items, predicate) != null;
- }
-
- @Nullable
- public static <T> T find(@Nullable List<T> items,
- java.util.function.Predicate<T> predicate) {
- if (isEmpty(items)) return null;
- for (int i = 0; i < items.size(); i++) {
- final T item = items.get(i);
- if (predicate.test(item)) return item;
- }
- return null;
- }
-
public static long total(@Nullable long[] array) {
long total = 0;
if (array != null) {
diff --git a/core/java/com/android/internal/util/BitUtils.java b/core/java/com/android/internal/util/BitUtils.java
deleted file mode 100644
index a208ccb8f35f..000000000000
--- a/core/java/com/android/internal/util/BitUtils.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2017 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 com.android.internal.util;
-
-import android.annotation.Nullable;
-
-import libcore.util.Objects;
-
-import java.util.Arrays;
-import java.util.UUID;
-
-public class BitUtils {
- private BitUtils() {}
-
- public static boolean maskedEquals(long a, long b, long mask) {
- return (a & mask) == (b & mask);
- }
-
- public static boolean maskedEquals(byte a, byte b, byte mask) {
- return (a & mask) == (b & mask);
- }
-
- public static boolean maskedEquals(byte[] a, byte[] b, @Nullable byte[] mask) {
- if (a == null || b == null) return a == b;
- Preconditions.checkArgument(a.length == b.length, "Inputs must be of same size");
- if (mask == null) return Arrays.equals(a, b);
- Preconditions.checkArgument(a.length == mask.length, "Mask must be of same size as inputs");
- for (int i = 0; i < mask.length; i++) {
- if (!maskedEquals(a[i], b[i], mask[i])) return false;
- }
- return true;
- }
-
- public static boolean maskedEquals(UUID a, UUID b, @Nullable UUID mask) {
- if (mask == null) {
- return Objects.equal(a, b);
- }
- return maskedEquals(a.getLeastSignificantBits(), b.getLeastSignificantBits(),
- mask.getLeastSignificantBits())
- && maskedEquals(a.getMostSignificantBits(), b.getMostSignificantBits(),
- mask.getMostSignificantBits());
- }
-}
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index 34bc4ebcd0aa..65cac09a09b3 100644
--- a/packages/CompanionDeviceManager/AndroidManifest.xml
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -26,8 +26,6 @@
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<application
android:allowClearUserData="true"
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
index 14b9de59bf5a..12bab18c88c9 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -16,9 +16,10 @@
package com.android.companiondevicemanager;
-import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayName;
import android.app.Activity;
+import android.bluetooth.BluetoothDevice;
import android.companion.CompanionDeviceManager;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -33,8 +34,6 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import com.android.companiondevicemanager.DeviceDiscoveryService.DeviceFilterPair;
-
public class DeviceChooserActivity extends Activity {
private static final boolean DEBUG = false;
@@ -56,11 +55,11 @@ public class DeviceChooserActivity extends Activity {
if (getService().mRequest.isSingleDevice()) {
setContentView(R.layout.device_confirmation);
- final DeviceFilterPair selectedDevice = getService().mDevicesFound.get(0);
+ final BluetoothDevice selectedDevice = getService().mDevicesFound.get(0);
setTitle(Html.fromHtml(getString(
R.string.confirmation_title,
getCallingAppName(),
- selectedDevice.getDisplayName()), 0));
+ getDeviceDisplayName(selectedDevice)), 0));
getService().mSelectedDevice = selectedDevice;
} else {
setContentView(R.layout.device_chooser);
@@ -128,11 +127,10 @@ public class DeviceChooserActivity extends Activity {
return DeviceDiscoveryService.sInstance;
}
- protected void onPairTapped(DeviceFilterPair selectedDevice) {
- getService().onDeviceSelected(
- getCallingPackage(), getDeviceMacAddress(selectedDevice.device));
+ protected void onPairTapped(BluetoothDevice selectedDevice) {
+ getService().onDeviceSelected(getCallingPackage(), selectedDevice.getAddress());
setResult(RESULT_OK,
- new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice.device));
+ new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice));
finish();
}
} \ No newline at end of file
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index e1e60bb99374..f0f910848943 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -16,10 +16,8 @@
package com.android.companiondevicemanager;
-import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayNameInternal;
-import static android.companion.BluetoothDeviceFilterUtils.getDeviceMacAddress;
-
-import static com.android.internal.util.ArrayUtils.isEmpty;
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayName;
+import static android.companion.BluetoothLEDeviceFilter.nullsafe;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -34,38 +32,28 @@ import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.companion.AssociationRequest;
-import android.companion.BluetoothDeviceFilter;
-import android.companion.BluetoothDeviceFilterUtils;
import android.companion.BluetoothLEDeviceFilter;
import android.companion.CompanionDeviceManager;
-import android.companion.DeviceFilter;
import android.companion.ICompanionDeviceDiscoveryService;
import android.companion.ICompanionDeviceDiscoveryServiceCallback;
import android.companion.IFindDeviceCallback;
-import android.companion.WifiDeviceFilter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
-import android.net.wifi.WifiManager;
import android.os.IBinder;
-import android.os.Parcelable;
import android.os.RemoteException;
-import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.Preconditions;
-
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
-import java.util.Objects;
public class DeviceDiscoveryService extends Service {
@@ -75,16 +63,12 @@ public class DeviceDiscoveryService extends Service {
static DeviceDiscoveryService sInstance;
private BluetoothAdapter mBluetoothAdapter;
- private WifiManager mWifiManager;
+ private BluetoothLEDeviceFilter mFilter;
+ private ScanFilter mScanFilter;
private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
- private List<DeviceFilter<?>> mFilters;
- private List<BluetoothLEDeviceFilter> mBLEFilters;
- private List<BluetoothDeviceFilter> mBluetoothFilters;
- private List<WifiDeviceFilter> mWifiFilters;
- private List<ScanFilter> mBLEScanFilters;
- AssociationRequest mRequest;
- List<DeviceFilterPair> mDevicesFound;
- DeviceFilterPair mSelectedDevice;
+ AssociationRequest<?> mRequest;
+ List<BluetoothDevice> mDevicesFound;
+ BluetoothDevice mSelectedDevice;
DevicesAdapter mDevicesAdapter;
IFindDeviceCallback mFindCallback;
ICompanionDeviceDiscoveryServiceCallback mServiceCallback;
@@ -111,13 +95,11 @@ public class DeviceDiscoveryService extends Service {
private final ScanCallback mBLEScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
- final DeviceFilterPair<ScanResult> deviceFilterPair
- = DeviceFilterPair.findMatch(result, mBLEFilters);
- if (deviceFilterPair == null) return;
+ final BluetoothDevice device = result.getDevice();
if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) {
- onDeviceLost(deviceFilterPair);
+ onDeviceLost(device);
} else {
- onDeviceFound(deviceFilterPair);
+ onDeviceFound(device);
}
}
};
@@ -127,35 +109,15 @@ public class DeviceDiscoveryService extends Service {
private BroadcastReceiver mBluetoothDeviceFoundBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- final DeviceFilterPair<BluetoothDevice> deviceFilterPair
- = DeviceFilterPair.findMatch(device, mBluetoothFilters);
- if (deviceFilterPair == null) return;
+ final BluetoothDevice device = intent.getParcelableExtra(
+ BluetoothDevice.EXTRA_DEVICE);
+ if (!mFilter.matches(device)) return; // ignore device
+
if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
- onDeviceFound(deviceFilterPair);
+ onDeviceFound(device);
} else {
- onDeviceLost(deviceFilterPair);
- }
- }
- };
-
- private BroadcastReceiver mWifiDeviceFoundBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
- List<android.net.wifi.ScanResult> scanResults = mWifiManager.getScanResults();
-
- if (DEBUG) {
- Log.i(LOG_TAG, "Wifi scan results: " + TextUtils.join("\n", scanResults));
- }
-
- for (int i = 0; i < scanResults.size(); i++) {
- DeviceFilterPair<android.net.wifi.ScanResult> deviceFilterPair =
- DeviceFilterPair.findMatch(scanResults.get(i), mWifiFilters);
- if (deviceFilterPair != null) onDeviceFound(deviceFilterPair);
- }
+ onDeviceLost(device);
}
-
}
};
@@ -173,7 +135,6 @@ public class DeviceDiscoveryService extends Service {
mBluetoothAdapter = getSystemService(BluetoothManager.class).getAdapter();
mBLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
- mWifiManager = getSystemService(WifiManager.class);
mDevicesFound = new ArrayList<>();
mDevicesAdapter = new DevicesAdapter();
@@ -181,39 +142,23 @@ public class DeviceDiscoveryService extends Service {
sInstance = this;
}
- private void startDiscovery(AssociationRequest request) {
+ private void startDiscovery(AssociationRequest<?> request) {
+ //TODO support other protocols as well
mRequest = request;
-
- mFilters = request.getDeviceFilters();
- mWifiFilters = ArrayUtils.filter(mFilters, WifiDeviceFilter.class);
- mBluetoothFilters = ArrayUtils.filter(mFilters, BluetoothDeviceFilter.class);
- mBLEFilters = ArrayUtils.filter(mFilters, BluetoothLEDeviceFilter.class);
- mBLEScanFilters = ArrayUtils.map(mBLEFilters, BluetoothLEDeviceFilter::getScanFilter);
+ mFilter = nullsafe((BluetoothLEDeviceFilter) request.getDeviceFilter());
+ mScanFilter = mFilter.getScanFilter();
reset();
- if (shouldScan(mBluetoothFilters)) {
- final IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
- intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
+ intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
- registerReceiver(mBluetoothDeviceFoundBroadcastReceiver, intentFilter);
- mBluetoothAdapter.startDiscovery();
- }
+ registerReceiver(mBluetoothDeviceFoundBroadcastReceiver, intentFilter);
+ mBluetoothAdapter.startDiscovery();
- if (shouldScan(mBLEFilters)) {
- mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback);
- }
-
- if (shouldScan(mWifiFilters)) {
- registerReceiver(mWifiDeviceFoundBroadcastReceiver,
- new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
- mWifiManager.startScan();
- }
- }
-
- private boolean shouldScan(List<? extends DeviceFilter> mediumSpecificFilters) {
- return !isEmpty(mediumSpecificFilters) || isEmpty(mFilters);
+ mBLEScanner.startScan(
+ Collections.singletonList(mScanFilter), mDefaultScanSettings, mBLEScanCallback);
}
private void reset() {
@@ -233,18 +178,25 @@ public class DeviceDiscoveryService extends Service {
mBluetoothAdapter.cancelDiscovery();
mBLEScanner.stopScan(mBLEScanCallback);
unregisterReceiver(mBluetoothDeviceFoundBroadcastReceiver);
- unregisterReceiver(mWifiDeviceFoundBroadcastReceiver);
stopSelf();
}
- private void onDeviceFound(@Nullable DeviceFilterPair device) {
+ private void onDeviceFound(BluetoothDevice device) {
if (mDevicesFound.contains(device)) {
return;
}
- if (DEBUG) Log.i(LOG_TAG, "Found device " + device.getDisplayName() + " "
- + getDeviceMacAddress(device.device));
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Considering device " + getDeviceDisplayName(device));
+ }
+ if (!mFilter.matches(device)) {
+ return;
+ }
+
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Found device " + getDeviceDisplayName(device));
+ }
if (mDevicesFound.isEmpty()) {
onReadyToShowUI();
}
@@ -265,10 +217,12 @@ public class DeviceDiscoveryService extends Service {
}
}
- private void onDeviceLost(@Nullable DeviceFilterPair device) {
+ private void onDeviceLost(BluetoothDevice device) {
mDevicesFound.remove(device);
mDevicesAdapter.notifyDataSetChanged();
- if (DEBUG) Log.i(LOG_TAG, "Lost device " + device.getDisplayName());
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Lost device " + getDeviceDisplayName(device));
+ }
}
void onDeviceSelected(String callingPackage, String deviceAddress) {
@@ -282,8 +236,7 @@ public class DeviceDiscoveryService extends Service {
}
}
- class DevicesAdapter extends ArrayAdapter<DeviceFilterPair> {
- //TODO wifi icon
+ class DevicesAdapter extends ArrayAdapter<BluetoothDevice> {
private Drawable BLUETOOTH_ICON = icon(android.R.drawable.stat_sys_data_bluetooth);
private Drawable icon(int drawableRes) {
@@ -308,8 +261,8 @@ public class DeviceDiscoveryService extends Service {
return view;
}
- private void bind(TextView textView, DeviceFilterPair device) {
- textView.setText(device.getDisplayName());
+ private void bind(TextView textView, BluetoothDevice device) {
+ textView.setText(getDeviceDisplayName(device));
textView.setBackgroundColor(
device.equals(mSelectedDevice)
? Color.GRAY
@@ -332,62 +285,4 @@ public class DeviceDiscoveryService extends Service {
return textView;
}
}
-
- /**
- * A pair of device and a filter that matched this device if any.
- *
- * @param <T> device type
- */
- static class DeviceFilterPair<T extends Parcelable> {
- public final T device;
- @Nullable
- public final DeviceFilter<T> filter;
-
- private DeviceFilterPair(T device, @Nullable DeviceFilter<T> filter) {
- this.device = device;
- this.filter = filter;
- }
-
- /**
- * {@code (device, null)} if the filters list is empty or null
- * {@code null} if none of the provided filters match the device
- * {@code (device, filter)} where filter is among the list of filters and matches the device
- */
- @Nullable
- public static <T extends Parcelable> DeviceFilterPair<T> findMatch(
- T dev, @Nullable List<? extends DeviceFilter<T>> filters) {
- if (isEmpty(filters)) return new DeviceFilterPair<>(dev, null);
- final DeviceFilter<T> matchingFilter = ArrayUtils.find(filters, (f) -> f.matches(dev));
- return matchingFilter != null ? new DeviceFilterPair<>(dev, matchingFilter) : null;
- }
-
- public String getDisplayName() {
- if (filter == null) {
- Preconditions.checkNotNull(device);
- if (device instanceof BluetoothDevice) {
- return getDeviceDisplayNameInternal((BluetoothDevice) device);
- } else if (device instanceof android.net.wifi.ScanResult) {
- return getDeviceDisplayNameInternal((android.net.wifi.ScanResult) device);
- } else if (device instanceof ScanResult) {
- return getDeviceDisplayNameInternal(((ScanResult) device).getDevice());
- } else {
- throw new IllegalArgumentException("Unknown device type: " + device.getClass());
- }
- }
- return filter.getDeviceDisplayName(device);
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- DeviceFilterPair<?> that = (DeviceFilterPair<?>) o;
- return Objects.equals(getDeviceMacAddress(device), getDeviceMacAddress(that.device));
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getDeviceMacAddress(device));
- }
- }
}
diff --git a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
index e6e2cb3d99c9..ad64e4e6e64d 100644
--- a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
+++ b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
@@ -141,7 +141,7 @@ public class CompanionDeviceManagerService extends SystemService {
}
private ServiceConnection getServiceConnection(
- final AssociationRequest request,
+ final AssociationRequest<?> request,
final IFindDeviceCallback findDeviceCallback,
final String callingPackage) {
return new ServiceConnection() {