Improvements of Presence APIs.
- use int instead of String for DataElement key
- add a version to the BroadcastRequest
- use DataElement and PublicCredential for PresenceScanFilter
- add CTS tests for scan APIs.
Bug: 217283281
Test: atest CtsNearbyFastPairTests
Change-Id: Ida965f9fece2c655048acedba1a210db69f5d991
diff --git a/nearby/framework/java/android/nearby/BroadcastRequest.java b/nearby/framework/java/android/nearby/BroadcastRequest.java
index 5fe07d5..1f408d4 100644
--- a/nearby/framework/java/android/nearby/BroadcastRequest.java
+++ b/nearby/framework/java/android/nearby/BroadcastRequest.java
@@ -38,15 +38,31 @@
/** Broadcast type for advertising using nearby presence protocol. */
public static final int BROADCAST_TYPE_NEARBY_PRESENCE = 3;
+ /** @hide **/
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({BROADCAST_TYPE_NEARBY_PRESENCE})
+ public @interface BroadcastType {
+ }
+
/**
* Tx Power when the value is not set in the broadcast.
*/
public static final int UNKNOWN_TX_POWER = -100;
+ /**
+ * V0 of Nearby Presence Protocol.
+ */
+ public static final int PRESENCE_VERSION_V0 = 0;
+
+ /**
+ * V1 of Nearby Presence Protocol.
+ */
+ public static final int PRESENCE_VERSION_V1 = 1;
+
/** @hide **/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({BROADCAST_TYPE_NEARBY_PRESENCE})
- public @interface BroadcastType {
+ @IntDef({PRESENCE_VERSION_V0, PRESENCE_VERSION_V1})
+ public @interface BroadcastVersion {
}
public static final @NonNull Creator<BroadcastRequest> CREATOR =
@@ -70,17 +86,21 @@
};
private final @BroadcastType int mType;
+ private final @BroadcastVersion int mVersion;
private final int mTxPower;
private final List<Integer> mMediums;
- BroadcastRequest(@BroadcastType int type, int txPower, List<Integer> mediums) {
+ BroadcastRequest(@BroadcastType int type, @BroadcastVersion int version, int txPower,
+ List<Integer> mediums) {
this.mType = type;
+ this.mVersion = version;
this.mTxPower = txPower;
this.mMediums = mediums;
}
BroadcastRequest(@BroadcastType int type, Parcel in) {
mType = type;
+ mVersion = in.readInt();
mTxPower = in.readInt();
mMediums = new ArrayList<>();
in.readList(mMediums, Integer.class.getClassLoader(), Integer.class);
@@ -94,6 +114,13 @@
}
/**
+ * Returns the version fo the broadcast.
+ */
+ public @BroadcastVersion int getVersion() {
+ return mVersion;
+ }
+
+ /**
* Returns the calibrated TX power when this request is broadcast.
*/
public int getTxPower() {
@@ -111,6 +138,7 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mType);
+ dest.writeInt(mVersion);
dest.writeInt(mTxPower);
dest.writeList(mMediums);
}
diff --git a/nearby/framework/java/android/nearby/CredentialElement.java b/nearby/framework/java/android/nearby/CredentialElement.java
index a8b9ba9..5f31c17 100644
--- a/nearby/framework/java/android/nearby/CredentialElement.java
+++ b/nearby/framework/java/android/nearby/CredentialElement.java
@@ -27,7 +27,7 @@
*
* @hide
*/
-public class CredentialElement implements Parcelable {
+public final class CredentialElement implements Parcelable {
private final String mKey;
private final byte[] mValue;
@@ -84,7 +84,7 @@
/**
* Builder for {@link CredentialElement}.
*/
- public static class Builder {
+ public static final class Builder {
private String mKey;
private byte[] mValue;
@@ -92,6 +92,7 @@
* Set the key and value for this credential element.
*/
@NonNull
+ @SuppressWarnings("MissingGetterMatchingBuilder")
public CredentialElement.Builder setElement(@NonNull String key, @NonNull byte[] value) {
mKey = key;
mValue = value;
diff --git a/nearby/framework/java/android/nearby/DataElement.java b/nearby/framework/java/android/nearby/DataElement.java
index 68818e1..f037612 100644
--- a/nearby/framework/java/android/nearby/DataElement.java
+++ b/nearby/framework/java/android/nearby/DataElement.java
@@ -28,12 +28,12 @@
*
* @hide
*/
-public class DataElement implements Parcelable {
+public final class DataElement implements Parcelable {
- private final String mKey;
+ private final int mKey;
private final byte[] mValue;
- private DataElement(String key, byte[] value) {
+ private DataElement(int key, byte[] value) {
mKey = key;
mValue = value;
}
@@ -42,7 +42,7 @@
public static final Creator<DataElement> CREATOR = new Creator<DataElement>() {
@Override
public DataElement createFromParcel(Parcel in) {
- String key = in.readString();
+ int key = in.readInt();
byte[] value = new byte[in.readInt()];
in.readByteArray(value);
return new Builder().setElement(key, value).build();
@@ -61,7 +61,7 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeString(mKey);
+ dest.writeInt(mKey);
dest.writeInt(mValue.length);
dest.writeByteArray(mValue);
}
@@ -69,8 +69,7 @@
/**
* Returns the key of the data element.
*/
- @NonNull
- public String getKey() {
+ public int getKey() {
return mKey;
}
@@ -85,15 +84,16 @@
/**
* Builder for {@link DataElement}.
*/
- public static class Builder {
- private String mKey;
+ public static final class Builder {
+ private int mKey;
private byte[] mValue;
/**
* Set the key and value for this data element.
*/
@NonNull
- public Builder setElement(@NonNull String key, @NonNull byte[] value) {
+ @SuppressWarnings("MissingGetterMatchingBuilder")
+ public Builder setElement(int key, @NonNull byte[] value) {
mKey = key;
mValue = value;
return this;
@@ -104,8 +104,8 @@
*/
@NonNull
public DataElement build() {
- Preconditions.checkState(mKey != null && mValue != null,
- "neither key or value can be null");
+ Preconditions.checkState(mValue != null,
+ "value can be null");
return new DataElement(mKey, mValue);
}
}
diff --git a/nearby/framework/java/android/nearby/PresenceBroadcastRequest.java b/nearby/framework/java/android/nearby/PresenceBroadcastRequest.java
index 223322a..7e387b5 100644
--- a/nearby/framework/java/android/nearby/PresenceBroadcastRequest.java
+++ b/nearby/framework/java/android/nearby/PresenceBroadcastRequest.java
@@ -36,10 +36,10 @@
private final PrivateCredential mCredential;
private final List<DataElement> mExtendedProperties;
- private PresenceBroadcastRequest(int txPower, List<Integer> mediums, byte[] salt,
- List<Integer> actions,
+ private PresenceBroadcastRequest(@BroadcastVersion int version, int txPower,
+ List<Integer> mediums, byte[] salt, List<Integer> actions,
PrivateCredential credential, List<DataElement> extendedProperties) {
- super(BROADCAST_TYPE_NEARBY_PRESENCE, txPower, mediums);
+ super(BROADCAST_TYPE_NEARBY_PRESENCE, version, txPower, mediums);
mSalt = salt;
mActions = actions;
mCredential = credential;
@@ -82,6 +82,7 @@
/**
* Returns the salt associated with this broadcast request.
*/
+ @NonNull
public byte[] getSalt() {
return mSalt;
}
@@ -135,11 +136,13 @@
private final List<Integer> mActions;
private final List<DataElement> mExtendedProperties;
+ private int mVersion;
private int mTxPower;
private byte[] mSalt;
private PrivateCredential mCredential;
public Builder() {
+ mVersion = PRESENCE_VERSION_V0;
mTxPower = UNKNOWN_TX_POWER;
mMediums = new ArrayList<>();
mActions = new ArrayList<>();
@@ -147,6 +150,15 @@
}
/**
+ * Sets the version for this request.
+ */
+ @NonNull
+ public Builder setVersion(@BroadcastVersion int version) {
+ mVersion = version;
+ return this;
+ }
+
+ /**
* Sets the calibrated tx power level for this request.
*/
@NonNull
@@ -207,7 +219,7 @@
public PresenceBroadcastRequest build() {
Preconditions.checkState(!mMediums.isEmpty(), "mediums cannot be empty");
Preconditions.checkState(mSalt != null && mSalt.length > 0, "salt cannot be empty");
- return new PresenceBroadcastRequest(mTxPower, mMediums, mSalt, mActions,
+ return new PresenceBroadcastRequest(mVersion, mTxPower, mMediums, mSalt, mActions,
mCredential, mExtendedProperties);
}
}
diff --git a/nearby/framework/java/android/nearby/PresenceCredential.java b/nearby/framework/java/android/nearby/PresenceCredential.java
index 5f0c201..14b17ae 100644
--- a/nearby/framework/java/android/nearby/PresenceCredential.java
+++ b/nearby/framework/java/android/nearby/PresenceCredential.java
@@ -81,7 +81,7 @@
private final @CredentialType int mType;
private final @IdentityType int mIdentityType;
- private final byte[] mSecreteId;
+ private final byte[] mSecretId;
private final byte[] mAuthenticityKey;
private final List<CredentialElement> mCredentialElements;
@@ -89,7 +89,7 @@
byte[] secreteId, byte[] authenticityKey, List<CredentialElement> credentialElements) {
mType = type;
mIdentityType = identityType;
- mSecreteId = secreteId;
+ mSecretId = secreteId;
mAuthenticityKey = authenticityKey;
mCredentialElements = credentialElements;
}
@@ -97,8 +97,8 @@
PresenceCredential(@CredentialType int type, Parcel in) {
mType = type;
mIdentityType = in.readInt();
- mSecreteId = new byte[in.readInt()];
- in.readByteArray(mSecreteId);
+ mSecretId = new byte[in.readInt()];
+ in.readByteArray(mSecretId);
mAuthenticityKey = new byte[in.readInt()];
in.readByteArray(mAuthenticityKey);
mCredentialElements = new ArrayList<>();
@@ -144,11 +144,11 @@
}
/**
- * Returns the secrete id of the credential.
+ * Returns the secret id of the credential.
*/
@NonNull
- public byte[] getSecreteId() {
- return mSecreteId;
+ public byte[] getSecretId() {
+ return mSecretId;
}
/**
@@ -176,8 +176,8 @@
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeInt(mIdentityType);
- dest.writeInt(mSecreteId.length);
- dest.writeByteArray(mSecreteId);
+ dest.writeInt(mSecretId.length);
+ dest.writeByteArray(mSecretId);
dest.writeInt(mAuthenticityKey.length);
dest.writeByteArray(mAuthenticityKey);
dest.writeList(mCredentialElements);
diff --git a/nearby/framework/java/android/nearby/PresenceDevice.java b/nearby/framework/java/android/nearby/PresenceDevice.java
index 61326c6..0b3782c 100644
--- a/nearby/framework/java/android/nearby/PresenceDevice.java
+++ b/nearby/framework/java/android/nearby/PresenceDevice.java
@@ -63,6 +63,9 @@
}
private final String mDeviceId;
+ private final byte[] mSalt;
+ private final byte[] mSecretId;
+ private final byte[] mEncryptedIdentity;
private final int mDeviceType;
private final String mDeviceImageUrl;
private final long mDiscoveryTimestampMillis;
@@ -89,6 +92,30 @@
return mDeviceId;
}
+ /**
+ * Returns the salt used when presence device is discovered.
+ */
+ @NonNull
+ public byte[] getSalt() {
+ return mSalt;
+ }
+
+ /**
+ * Returns the secret used when presence device is discovered.
+ */
+ @NonNull
+ public byte[] getSecretId() {
+ return mSecretId;
+ }
+
+ /**
+ * Returns the encrypted identity used when presence device is discovered.
+ */
+ @NonNull
+ public byte[] getEncryptedIdentity() {
+ return mEncryptedIdentity;
+ }
+
/** The type of the device. */
@DeviceType
public int getDeviceType() {
@@ -115,12 +142,15 @@
}
private PresenceDevice(String deviceName, int mMedium, int rssi, String deviceId,
- int deviceType,
+ byte[] salt, byte[] secretId, byte[] encryptedIdentity, int deviceType,
String deviceImageUrl, long discoveryTimestampMillis,
Bundle extendedProperties) {
// TODO (b/217462253): change medium to a set in NearbyDevice.
super(deviceName, mMedium, rssi);
mDeviceId = deviceId;
+ mSalt = salt;
+ mSecretId = secretId;
+ mEncryptedIdentity = encryptedIdentity;
mDeviceType = deviceType;
mDeviceImageUrl = deviceImageUrl;
mDiscoveryTimestampMillis = discoveryTimestampMillis;
@@ -192,6 +222,9 @@
private int mRssi;
private int mMedium;
private String mDeviceId;
+ private byte[] mSalt;
+ private byte[] mSecretId;
+ private byte[] mEncryptedIdentity;
private int mDeviceType;
private String mDeviceImageUrl;
private long mDiscoveryTimestampMillis;
@@ -245,6 +278,32 @@
return this;
}
+ /**
+ * Sets the identifier on the discovered Presence device.
+ */
+ @NonNull
+ public Builder setSalt(@NonNull byte[] salt) {
+ mSalt = salt;
+ return this;
+ }
+
+ /**
+ * Sets the secret Id of the discovered Presence device.
+ */
+ @NonNull
+ public Builder setSecretId(@NonNull byte[] secretId) {
+ mSecretId = secretId;
+ return this;
+ }
+
+ /**
+ * Sets the encrypted identity of the discovered Presence device.
+ */
+ @NonNull
+ public Builder setEncryptedIdentity(@NonNull byte[] encryptedIdentity) {
+ mEncryptedIdentity = encryptedIdentity;
+ return this;
+ }
/**
* Sets the type of discovered Presence device.
@@ -299,7 +358,9 @@
*/
@NonNull
public PresenceDevice build() {
- return new PresenceDevice(mName, mMedium, mRssi, mDeviceId, mDeviceType,
+ return new PresenceDevice(mName, mMedium, mRssi, mDeviceId,
+ mSalt, mSecretId, mEncryptedIdentity,
+ mDeviceType,
mDeviceImageUrl,
mDiscoveryTimestampMillis, mExtendedProperties);
}
diff --git a/nearby/framework/java/android/nearby/PresenceScanFilter.java b/nearby/framework/java/android/nearby/PresenceScanFilter.java
index 61e5049..e9b5faa 100644
--- a/nearby/framework/java/android/nearby/PresenceScanFilter.java
+++ b/nearby/framework/java/android/nearby/PresenceScanFilter.java
@@ -17,8 +17,6 @@
package android.nearby;
import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
@@ -36,25 +34,16 @@
*/
public final class PresenceScanFilter extends ScanFilter implements Parcelable {
- private final List<byte[]> mCertificates;
- private final List<Integer> mPresenceIdentities;
+ private final List<PublicCredential> mCredentials;
private final List<Integer> mPresenceActions;
- private final Bundle mExtendedProperties;
+ private final List<DataElement> mExtendedProperties;
/**
- * A list of certificates to filter on.
+ * A list of credentials to filter on.
*/
@NonNull
- public List<byte[]> getCertificates() {
- return mCertificates;
- }
-
- /**
- * A list of presence identities for matching.
- */
- @NonNull
- public List<Integer> getPresenceIdentities() {
- return mPresenceIdentities;
+ public List<PublicCredential> getCredentials() {
+ return mCredentials;
}
/**
@@ -69,42 +58,33 @@
* A bundle of extended properties for matching.
*/
@NonNull
- public Bundle getExtendedProperties() {
+ public List<DataElement> getExtendedProperties() {
return mExtendedProperties;
}
- private PresenceScanFilter(int rssiThreshold, List<byte[]> certificates,
- List<Integer> presenceIdentities, List<Integer> presenceActions,
- Bundle extendedProperties) {
+ private PresenceScanFilter(int rssiThreshold, List<PublicCredential> credentials,
+ List<Integer> presenceActions, List<DataElement> extendedProperties) {
super(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE, rssiThreshold);
- mCertificates = new ArrayList<>(certificates);
- mPresenceIdentities = new ArrayList<>(presenceIdentities);
+ mCredentials = new ArrayList<>(credentials);
mPresenceActions = new ArrayList<>(presenceActions);
mExtendedProperties = extendedProperties;
}
private PresenceScanFilter(Parcel in) {
super(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE, in);
- mCertificates = new ArrayList<>();
- int size = in.readInt();
- for (int i = 0; i < size; i++) {
- int len = in.readInt();
- byte[] certificate = new byte[len];
- in.readByteArray(certificate);
- mCertificates.add(certificate);
- }
- mPresenceIdentities = new ArrayList<>();
+ mCredentials = new ArrayList<>();
if (in.readInt() != 0) {
- in.readList(mPresenceIdentities, Integer.class.getClassLoader(), Integer.class);
+ in.readParcelableList(mCredentials, PublicCredential.class.getClassLoader(),
+ PublicCredential.class);
}
mPresenceActions = new ArrayList<>();
if (in.readInt() != 0) {
in.readList(mPresenceActions, Integer.class.getClassLoader(), Integer.class);
}
- mExtendedProperties = new Bundle();
- Bundle bundle = in.readBundle(getClass().getClassLoader());
- for (String key : bundle.keySet()) {
- mExtendedProperties.putString(key, bundle.getString(key));
+ mExtendedProperties = new ArrayList<>();
+ if (in.readInt() != 0) {
+ in.readParcelableList(mExtendedProperties, DataElement.class.getClassLoader(),
+ DataElement.class);
}
}
@@ -138,20 +118,18 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
- dest.writeInt(mCertificates.size());
- for (byte[] certificate : mCertificates) {
- dest.writeInt(certificate.length);
- dest.writeByteArray(certificate);
- }
- dest.writeInt(mPresenceIdentities.size());
- if (!mPresenceIdentities.isEmpty()) {
- dest.writeList(mPresenceIdentities);
+ dest.writeInt(mCredentials.size());
+ if (!mCredentials.isEmpty()) {
+ dest.writeParcelableList(mCredentials, 0);
}
dest.writeInt(mPresenceActions.size());
if (!mPresenceActions.isEmpty()) {
dest.writeList(mPresenceActions);
}
- dest.writeBundle(mExtendedProperties);
+ dest.writeInt(mExtendedProperties.size());
+ if (!mExtendedProperties.isEmpty()) {
+ dest.writeList(mExtendedProperties);
+ }
}
/**
@@ -161,17 +139,17 @@
*/
public static final class Builder {
private int mRssiThreshold;
- private final Set<byte[]> mCertificates;
+ private final Set<PublicCredential> mCredentials;
private final Set<Integer> mPresenceIdentities;
private final Set<Integer> mPresenceActions;
- private final Bundle mExtendedProperties;
+ private final List<DataElement> mExtendedProperties;
public Builder() {
mRssiThreshold = -100;
- mCertificates = new ArraySet<>();
+ mCredentials = new ArraySet<>();
mPresenceIdentities = new ArraySet<>();
mPresenceActions = new ArraySet<>();
- mExtendedProperties = new Bundle();
+ mExtendedProperties = new ArrayList<>();
}
/**
@@ -184,21 +162,12 @@
}
/**
- * Adds a list of certificates the scan filter is expected to match.
+ * Adds a list of credentials the scan filter is expected to match.
*/
@NonNull
- public Builder addCertificate(@NonNull byte[] certificate) {
- mCertificates.add(certificate);
- return this;
- }
-
- /**
- * Adds a presence identity for filtering.
- */
- @NonNull
- public Builder addPresenceIdentity(int identity) {
- mPresenceIdentities.add(identity);
+ public Builder addCredential(@NonNull PublicCredential credential) {
+ mCredentials.add(credential);
return this;
}
@@ -215,8 +184,8 @@
* Add an extended property for scan filtering.
*/
@NonNull
- public Builder addExtendedProperty(@NonNull String key, @Nullable String value) {
- mExtendedProperties.putCharSequence(key, value);
+ public Builder addExtendedProperty(@NonNull DataElement dataElement) {
+ mExtendedProperties.add(dataElement);
return this;
}
@@ -225,9 +194,9 @@
*/
@NonNull
public PresenceScanFilter build() {
- Preconditions.checkState(!mCertificates.isEmpty(), "certificates cannot be empty");
- return new PresenceScanFilter(mRssiThreshold, new ArrayList<>(mCertificates),
- new ArrayList<>(mPresenceIdentities),
+ Preconditions.checkState(!mCredentials.isEmpty(), "credentials cannot be empty");
+ return new PresenceScanFilter(mRssiThreshold,
+ new ArrayList<>(mCredentials),
new ArrayList<>(mPresenceActions),
mExtendedProperties);
}
diff --git a/nearby/framework/java/android/nearby/PrivateCredential.java b/nearby/framework/java/android/nearby/PrivateCredential.java
index e05efa0..2860fdb 100644
--- a/nearby/framework/java/android/nearby/PrivateCredential.java
+++ b/nearby/framework/java/android/nearby/PrivateCredential.java
@@ -30,7 +30,7 @@
*
* @hide
*/
-public class PrivateCredential extends PresenceCredential implements Parcelable {
+public final class PrivateCredential extends PresenceCredential implements Parcelable {
@NonNull
public static final Creator<PrivateCredential> CREATOR = new Creator<PrivateCredential>() {
@@ -56,7 +56,7 @@
mDeviceName = in.readString();
}
- public PrivateCredential(int identityType, byte[] secreteId,
+ private PrivateCredential(int identityType, byte[] secreteId,
String deviceName, byte[] authenticityKey, List<CredentialElement> credentialElements,
byte[] metaDataEncryptionKey) {
super(CREDENTIAL_TYPE_PRIVATE, identityType, secreteId, authenticityKey,
@@ -82,15 +82,22 @@
dest.writeString(mDeviceName);
}
+ /**
+ * Returns the metadata encryption key associated with this credential.
+ */
+ @NonNull
public byte[] getMetaDataEncryptionKey() {
return mMetaDataEncryptionKey;
}
+ /**
+ * Returns the device name associated with this credential.
+ */
+ @NonNull
public String getDeviceName() {
return mDeviceName;
}
-
/**
* Builder class for {@link PresenceCredential}.
*
@@ -140,7 +147,7 @@
* Sets the metadata encryption key to the credential.
*/
@NonNull
- public Builder setMetaDataEncryptionKey(byte[] metaDataEncryptionKey) {
+ public Builder setMetaDataEncryptionKey(@NonNull byte[] metaDataEncryptionKey) {
mMetaDataEncryptionKey = metaDataEncryptionKey;
return this;
}
@@ -149,7 +156,7 @@
* Sets the device name of the credential.
*/
@NonNull
- public Builder setDeviceName(String deviceName) {
+ public Builder setDeviceName(@NonNull String deviceName) {
mDeviceName = deviceName;
return this;
}
@@ -158,7 +165,7 @@
* Adds an element to the credential.
*/
@NonNull
- public Builder addCredentialElement(CredentialElement credentialElement) {
+ public Builder addCredentialElement(@NonNull CredentialElement credentialElement) {
mCredentialElements.add(credentialElement);
return this;
}
diff --git a/nearby/framework/java/android/nearby/PublicCredential.java b/nearby/framework/java/android/nearby/PublicCredential.java
index 560e7f0..78f6205 100644
--- a/nearby/framework/java/android/nearby/PublicCredential.java
+++ b/nearby/framework/java/android/nearby/PublicCredential.java
@@ -30,7 +30,7 @@
*
* @hide
*/
-public class PublicCredential extends PresenceCredential implements Parcelable {
+public final class PublicCredential extends PresenceCredential implements Parcelable {
@NonNull
public static final Creator<PublicCredential> CREATOR = new Creator<PublicCredential>() {
@Override
@@ -58,7 +58,7 @@
mMetaDataEncryptionKeyTag = metaDataEncryptionKeyTag;
}
- public PublicCredential(Parcel in) {
+ private PublicCredential(Parcel in) {
super(CREDENTIAL_TYPE_PUBLIC, in);
mPublicKey = new byte[in.readInt()];
in.readByteArray(mPublicKey);
@@ -72,14 +72,26 @@
return new PublicCredential(in);
}
+ /**
+ * Returns the public key associated with this credential.
+ */
+ @NonNull
public byte[] getPublicKey() {
return mPublicKey;
}
+ /**
+ * Returns the encrypted metadata associated with this credential.
+ */
+ @NonNull
public byte[] getEncryptedMetadata() {
return mEncryptedMetadata;
}
+ /**
+ * Returns the metadata encryption key tag associated with this credential.
+ */
+ @NonNull
public byte[] getMetaDataEncryptionKeyTag() {
return mMetaDataEncryptionKeyTag;
}
@@ -150,7 +162,7 @@
* Adds an element to the credential.
*/
@NonNull
- public Builder addCredentialElement(CredentialElement credentialElement) {
+ public Builder addCredentialElement(@NonNull CredentialElement credentialElement) {
mCredentialElements.add(credentialElement);
return this;
}
@@ -159,7 +171,7 @@
* Sets the public key for the credential.
*/
@NonNull
- public Builder setPublicKey(byte[] publicKey) {
+ public Builder setPublicKey(@NonNull byte[] publicKey) {
mPublicKey = publicKey;
return this;
}
@@ -168,7 +180,7 @@
* Sets the encrypted metadata.
*/
@NonNull
- public Builder setEncryptedMetadata(byte[] encryptedMetadata) {
+ public Builder setEncryptedMetadata(@NonNull byte[] encryptedMetadata) {
mEncryptedMetadata = encryptedMetadata;
return this;
}
@@ -177,7 +189,7 @@
* Sets the metadata encryption key tag.
*/
@NonNull
- public Builder setMetaDataEncryptionKeyTag(byte[] metaDataEncryptionKeyTag) {
+ public Builder setMetaDataEncryptionKeyTag(@NonNull byte[] metaDataEncryptionKeyTag) {
mMetaDataEncryptionKeyTag = metaDataEncryptionKeyTag;
return this;
}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
index 95d64c3..d096ed1 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
@@ -35,7 +35,7 @@
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
public class DataElementTest {
- private static final String KEY = "SUPPORT_MEDIA";
+ private static final int KEY = 1234;
private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
@Test
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
index a974008..a27d525 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
@@ -44,12 +44,13 @@
private static final int TX_POWER = 1;
private static final byte[] SALT = new byte[]{1, 2};
private static final int ACTION_ID = 123;
- private static final String SUPPORT_MEDIA_KEY = "SupportMedia";
- private static final byte[] SUPPORT_MEDIA_VALUE = new byte[]{1, 2, 34};
private static final int BLE_MEDIUM = 1;
private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
private static final byte[] METADATA_ENCRYPTION_KEY = new byte[]{1, 1, 3, 4, 5};
+ private static final int KEY = 1234;
+ private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
+
private PresenceBroadcastRequest.Builder mBuilder;
@@ -61,14 +62,14 @@
.setAuthenticityKey(AUTHENTICITY_KEY)
.setMetaDataEncryptionKey(METADATA_ENCRYPTION_KEY)
.build();
+ DataElement element = new DataElement.Builder().setElement(KEY, VALUE).build();
mBuilder = new PresenceBroadcastRequest.Builder()
.setSalt(SALT)
.setTxPower(TX_POWER)
.setCredential(credential)
.addAction(ACTION_ID)
.addMediums(BLE_MEDIUM)
- .addExtendedProperty(new DataElement.Builder().setElement(SUPPORT_MEDIA_KEY,
- SUPPORT_MEDIA_VALUE).build());
+ .addExtendedProperty(element);
}
@Test
@@ -78,7 +79,7 @@
assertThat(broadcastRequest.getTxPower()).isEqualTo(TX_POWER);
assertThat(broadcastRequest.getActions()).containsExactly(ACTION_ID);
assertThat(broadcastRequest.getExtendedProperties().get(0).getKey()).isEqualTo(
- SUPPORT_MEDIA_KEY);
+ KEY);
assertThat(broadcastRequest.getMediums()).containsExactly(BLE_MEDIUM);
assertThat(broadcastRequest.getCredential().getIdentityType()).isEqualTo(
IDENTITY_TYPE_PRIVATE);
@@ -99,7 +100,7 @@
assertThat(parcelRequest.getTxPower()).isEqualTo(TX_POWER);
assertThat(parcelRequest.getActions()).containsExactly(ACTION_ID);
assertThat(parcelRequest.getExtendedProperties().get(0).getKey()).isEqualTo(
- SUPPORT_MEDIA_KEY);
+ KEY);
assertThat(parcelRequest.getMediums()).containsExactly(BLE_MEDIUM);
assertThat(parcelRequest.getCredential().getIdentityType()).isEqualTo(
IDENTITY_TYPE_PRIVATE);
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
new file mode 100644
index 0000000..c704022
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.nearby.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.NearbyDevice;
+import android.nearby.PresenceDevice;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test for {@link PresenceDevice}.
+ */
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class PresenceDeviceTest {
+ private static final int DEVICE_TYPE = PresenceDevice.DeviceType.PHONE;
+ private static final String DEVICE_ID = "123";
+ private static final String IMAGE_URL = "http://example.com/imageUrl";
+ private static final String SUPPORT_MEDIA = "SupportMedia";
+ private static final String SUPPORT_MEDIA_VALUE = "true";
+ private static final int RSSI = -40;
+ private static final int MEDIUM = NearbyDevice.Medium.BLE;
+ private static final String DEVICE_NAME = "testDevice";
+
+ @Test
+ public void testBuilder() {
+ PresenceDevice device = new PresenceDevice.Builder()
+ .setDeviceType(DEVICE_TYPE)
+ .setDeviceId(DEVICE_ID)
+ .setDeviceImageUrl(IMAGE_URL)
+ .addExtendedProperty(SUPPORT_MEDIA, SUPPORT_MEDIA_VALUE)
+ .setRssi(RSSI)
+ .setMedium(MEDIUM)
+ .setName(DEVICE_NAME)
+ .build();
+
+ assertThat(device.getDeviceType()).isEqualTo(DEVICE_TYPE);
+ assertThat(device.getDeviceId()).isEqualTo(DEVICE_ID);
+ assertThat(device.getDeviceImageUrl()).isEqualTo(IMAGE_URL);
+ assertThat(device.getExtendedProperties().get(SUPPORT_MEDIA)).isEqualTo(
+ SUPPORT_MEDIA_VALUE);
+ assertThat(device.getRssi()).isEqualTo(RSSI);
+ assertThat(device.getMedium()).isEqualTo(MEDIUM);
+ assertThat(device.getName()).isEqualTo(DEVICE_NAME);
+ }
+
+ @Test
+ public void testWriteParcel() {
+ PresenceDevice device = new PresenceDevice.Builder()
+ .setDeviceId(DEVICE_ID)
+ .addExtendedProperty(SUPPORT_MEDIA, SUPPORT_MEDIA_VALUE)
+ .setRssi(RSSI)
+ .setMedium(MEDIUM)
+ .setName(DEVICE_NAME)
+ .build();
+
+ Parcel parcel = Parcel.obtain();
+ device.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ PresenceDevice parcelDevice = PresenceDevice.CREATOR.createFromParcel(parcel);
+ parcel.recycle();
+
+ assertThat(parcelDevice.getDeviceId()).isEqualTo(DEVICE_ID);
+ assertThat(parcelDevice.getExtendedProperties().get(SUPPORT_MEDIA)).isEqualTo(
+ SUPPORT_MEDIA_VALUE);
+ assertThat(parcelDevice.getRssi()).isEqualTo(RSSI);
+ assertThat(parcelDevice.getMedium()).isEqualTo(MEDIUM);
+ assertThat(parcelDevice.getName()).isEqualTo(DEVICE_NAME);
+ }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
new file mode 100644
index 0000000..017677f
--- /dev/null
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.nearby.cts;
+
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.nearby.DataElement;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
+import android.nearby.ScanRequest;
+import android.os.Build;
+import android.os.Parcel;
+
+import androidx.annotation.RequiresApi;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link android.nearby.PresenceScanFilter}.
+ */
+@RunWith(AndroidJUnit4.class)
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class PresenceScanFilterTest {
+
+ private static final int RSSI = -40;
+ private static final int ACTION = 123;
+ private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
+ private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
+ private static final byte[] PUBLIC_KEY = new byte[]{1, 1, 2, 2};
+ private static final byte[] ENCRYPTED_METADATA = new byte[]{1, 2, 3, 4, 5};
+ private static final byte[] METADATA_ENCRYPTION_KEY_TAG = new byte[]{1, 1, 3, 4, 5};
+ private static final int KEY = 1234;
+ private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
+
+
+ private PublicCredential mPublicCredential =
+ new PublicCredential.Builder()
+ .setIdentityType(IDENTITY_TYPE_PRIVATE)
+ .setSecretId(SECRETE_ID).setAuthenticityKey(AUTHENTICITY_KEY)
+ .setPublicKey(PUBLIC_KEY).setEncryptedMetadata(ENCRYPTED_METADATA)
+ .setMetaDataEncryptionKeyTag(METADATA_ENCRYPTION_KEY_TAG).build();
+ private PresenceScanFilter.Builder mBuilder = new PresenceScanFilter.Builder()
+ .setRssiThreshold(RSSI)
+ .addCredential(mPublicCredential)
+ .addPresenceAction(ACTION)
+ .addExtendedProperty(new DataElement.Builder().setElement(KEY, VALUE).build());
+
+ @Test
+ public void testBuilder() {
+ PresenceScanFilter filter = mBuilder.build();
+
+ assertThat(filter.getRssiThreshold()).isEqualTo(RSSI);
+ assertThat(filter.getCredentials().get(0).getIdentityType()).isEqualTo(
+ IDENTITY_TYPE_PRIVATE);
+ assertThat(filter.getPresenceActions()).containsExactly(ACTION);
+ }
+
+ @Test
+ public void testWriteParcel() {
+ PresenceScanFilter filter = mBuilder.build();
+
+ Parcel parcel = Parcel.obtain();
+ filter.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ PresenceScanFilter parcelFilter = PresenceScanFilter.CREATOR.createFromParcel(parcel);
+ parcel.recycle();
+
+ assertThat(parcelFilter.getType()).isEqualTo(ScanRequest.SCAN_TYPE_NEARBY_PRESENCE);
+ assertThat(parcelFilter.getRssiThreshold()).isEqualTo(RSSI);
+ assertThat(parcelFilter.getPresenceActions()).containsExactly(ACTION);
+ }
+}
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
index 1174400..054bb1a 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PrivateCredentialTest.java
@@ -65,7 +65,7 @@
assertThat(credential.getType()).isEqualTo(CREDENTIAL_TYPE_PRIVATE);
assertThat(credential.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
- assertThat(Arrays.equals(credential.getSecreteId(), SECRETE_ID)).isTrue();
+ assertThat(Arrays.equals(credential.getSecretId(), SECRETE_ID)).isTrue();
assertThat(Arrays.equals(credential.getAuthenticityKey(), AUTHENTICITY_KEY)).isTrue();
assertThat(Arrays.equals(credential.getMetaDataEncryptionKey(),
METADATA_ENCRYPTION_KEY)).isTrue();
@@ -87,7 +87,7 @@
assertThat(credentialFromParcel.getType()).isEqualTo(CREDENTIAL_TYPE_PRIVATE);
assertThat(credentialFromParcel.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
- assertThat(Arrays.equals(credentialFromParcel.getSecreteId(), SECRETE_ID)).isTrue();
+ assertThat(Arrays.equals(credentialFromParcel.getSecretId(), SECRETE_ID)).isTrue();
assertThat(Arrays.equals(credentialFromParcel.getAuthenticityKey(),
AUTHENTICITY_KEY)).isTrue();
assertThat(Arrays.equals(credentialFromParcel.getMetaDataEncryptionKey(),
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
index 2c28768..4359ba5 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PublicCredentialTest.java
@@ -65,7 +65,7 @@
assertThat(credential.getType()).isEqualTo(CREDENTIAL_TYPE_PUBLIC);
assertThat(credential.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
- assertThat(Arrays.equals(credential.getSecreteId(), SECRETE_ID)).isTrue();
+ assertThat(Arrays.equals(credential.getSecretId(), SECRETE_ID)).isTrue();
assertThat(Arrays.equals(credential.getAuthenticityKey(), AUTHENTICITY_KEY)).isTrue();
assertThat(Arrays.equals(credential.getPublicKey(), PUBLIC_KEY)).isTrue();
assertThat(Arrays.equals(credential.getEncryptedMetadata(), ENCRYPTED_METADATA)).isTrue();
@@ -86,7 +86,7 @@
assertThat(credentialFromParcel.getType()).isEqualTo(CREDENTIAL_TYPE_PUBLIC);
assertThat(credentialFromParcel.getIdentityType()).isEqualTo(IDENTITY_TYPE_PRIVATE);
- assertThat(Arrays.equals(credentialFromParcel.getSecreteId(), SECRETE_ID)).isTrue();
+ assertThat(Arrays.equals(credentialFromParcel.getSecretId(), SECRETE_ID)).isTrue();
assertThat(Arrays.equals(credentialFromParcel.getAuthenticityKey(),
AUTHENTICITY_KEY)).isTrue();
assertThat(Arrays.equals(credentialFromParcel.getPublicKey(), PUBLIC_KEY)).isTrue();
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java
index 3bb348b..25aa926 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/ScanRequestTest.java
@@ -16,6 +16,7 @@
package android.nearby.cts;
+import static android.nearby.PresenceCredential.IDENTITY_TYPE_PRIVATE;
import static android.nearby.ScanRequest.SCAN_MODE_BALANCED;
import static android.nearby.ScanRequest.SCAN_MODE_LOW_LATENCY;
import static android.nearby.ScanRequest.SCAN_MODE_LOW_POWER;
@@ -27,6 +28,8 @@
import static com.google.common.truth.Truth.assertThat;
+import android.nearby.PresenceScanFilter;
+import android.nearby.PublicCredential;
import android.nearby.ScanRequest;
import android.os.Build;
import android.os.WorkSource;
@@ -62,7 +65,7 @@
assertThat(request.getScanMode()).isEqualTo(SCAN_MODE_LOW_POWER);
}
- /** Verify setting work source with null value in the scan request is allowed*/
+ /** Verify setting work source with null value in the scan request is allowed */
@Test
@SdkSuppress(minSdkVersion = 32, codeName = "T")
public void testSetWorkSource_nullValue() {
@@ -151,6 +154,38 @@
assertThat(ScanRequest.scanModeToString(-2)).isEqualTo("SCAN_MODE_INVALID");
}
+ @Test
+ @SdkSuppress(minSdkVersion = 32, codeName = "T")
+ public void testScanFilter() {
+ final byte[] secreteId = new byte[]{1, 2, 3, 4};
+ final byte[] authenticityKey = new byte[]{0, 1, 1, 1};
+ final byte[] publicKey = new byte[]{1, 1, 2, 2};
+ final byte[] encryptedMetadata = new byte[]{1, 2, 3, 4, 5};
+ final byte[] metadataEncryptionKeyTag = new byte[]{1, 1, 3, 4, 5};
+
+ PublicCredential credential = new PublicCredential.Builder()
+ .setIdentityType(IDENTITY_TYPE_PRIVATE)
+ .setSecretId(secreteId)
+ .setAuthenticityKey(authenticityKey)
+ .setEncryptedMetadata(encryptedMetadata)
+ .setPublicKey(publicKey)
+ .setMetaDataEncryptionKeyTag(metadataEncryptionKeyTag).build();
+
+ final int rssi = -40;
+ final int action = 123;
+ PresenceScanFilter filter = new PresenceScanFilter.Builder()
+ .addCredential(credential)
+ .setRssiThreshold(rssi)
+ .addPresenceAction(action)
+ .build();
+
+ ScanRequest request = new ScanRequest.Builder().setScanType(
+ SCAN_TYPE_FAST_PAIR).addScanFilter(filter).build();
+
+ assertThat(request.getScanFilters()).isNotEmpty();
+ assertThat(request.getScanFilters().get(0).getRssiThreshold()).isEqualTo(rssi);
+ }
+
private static WorkSource getWorkSource() {
return new WorkSource(UID, APP_NAME);
}