Merge "AWARE: Abstract structure of match filters" am: f358a69cba am: 7f12aa5470

am: 61eb0bf8fc

Change-Id: Ieac0ca72361be082f99f6ab3be89d7f1662b0e6b
This commit is contained in:
Etan Cohen
2016-12-01 22:03:29 +00:00
committed by android-build-merger
11 changed files with 202 additions and 417 deletions

View File

@@ -22,7 +22,7 @@ import android.os.Parcelable;
/** /**
* Defines a request object to configure a Wi-Fi Aware network. Built using * Defines a request object to configure a Wi-Fi Aware network. Built using
* {@link ConfigRequest.Builder}. Configuration is requested using * {@link ConfigRequest.Builder}. Configuration is requested using
* {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}. * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)}.
* Note that the actual achieved configuration may be different from the * Note that the actual achieved configuration may be different from the
* requested configuration - since different applications may request different * requested configuration - since different applications may request different
* configurations. * configurations.

View File

@@ -1,340 +0,0 @@
/*
* Copyright (C) 2016 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.net.wifi.aware;
import android.annotation.Nullable;
import libcore.io.Memory;
import java.nio.ByteOrder;
import java.util.Iterator;
/**
* Utility class to construct and parse byte arrays using the LV format -
* Length/Value format. The utilities accept a configuration of the size of
* the Length field.
*
* @hide PROPOSED_AWARE_API
*/
public class LvBufferUtils {
private LvBufferUtils() {
// no reason to ever create this class
}
/**
* Utility class to construct byte arrays using the LV format - Length/Value.
* <p>
* A constructor is created specifying the size of the Length (L) field.
* <p>
* The byte array is either provided (using
* {@link LvBufferUtils.LvConstructor#wrap(byte[])}) or allocated (using
* {@link LvBufferUtils.LvConstructor#allocate(int)}).
* <p>
* Values are added to the structure using the {@code LvConstructor.put*()}
* methods.
* <p>
* The final byte array is obtained using {@link LvBufferUtils.LvConstructor#getArray()}.
*/
public static class LvConstructor {
private TlvBufferUtils.TlvConstructor mTlvImpl;
/**
* Define a LV constructor with the specified size of the Length (L) field.
*
* @param lengthSize Number of bytes used for the Length (L) field.
* Values of 1 or 2 bytes are allowed.
*/
public LvConstructor(int lengthSize) {
mTlvImpl = new TlvBufferUtils.TlvConstructor(0, lengthSize);
}
/**
* Set the byte array to be used to construct the LV.
*
* @param array Byte array to be formatted.
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor wrap(@Nullable byte[] array) {
mTlvImpl.wrap(array);
return this;
}
/**
* Allocates a new byte array to be used ot construct a LV.
*
* @param capacity The size of the byte array to be allocated.
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor allocate(int capacity) {
mTlvImpl.allocate(capacity);
return this;
}
/**
* Copies a byte into the LV array.
*
* @param b The byte to be inserted into the structure.
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor putByte(byte b) {
mTlvImpl.putByte(0, b);
return this;
}
/**
* Copies a byte array into the LV.
*
* @param array The array to be copied into the LV structure.
* @param offset Start copying from the array at the specified offset.
* @param length Copy the specified number (length) of bytes from the
* array.
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor putByteArray(@Nullable byte[] array, int offset,
int length) {
mTlvImpl.putByteArray(0, array, offset, length);
return this;
}
/**
* Copies a byte array into the LV.
*
* @param array The array to be copied (in full) into the LV structure.
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor putByteArray(int type, @Nullable byte[] array) {
return putByteArray(array, 0, (array == null) ? 0 : array.length);
}
/**
* Places a zero length element (i.e. Length field = 0) into the LV.
*
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor putZeroLengthElement() {
mTlvImpl.putZeroLengthElement(0);
return this;
}
/**
* Copies short into the LV.
*
* @param data The short to be inserted into the structure.
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor putShort(short data) {
mTlvImpl.putShort(0, data);
return this;
}
/**
* Copies integer into the LV.
*
* @param data The integer to be inserted into the structure.
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor putInt(int data) {
mTlvImpl.putInt(0, data);
return this;
}
/**
* Copies a String's byte representation into the LV.
*
* @param data The string whose bytes are to be inserted into the
* structure.
* @return The constructor to facilitate chaining
* {@code ctr.putXXX(..).putXXX(..)}.
*/
public LvBufferUtils.LvConstructor putString(@Nullable String data) {
mTlvImpl.putString(0, data);
return this;
}
/**
* Returns the constructed LV formatted byte-array. This array is a copy of the wrapped
* or allocated array - truncated to just the significant bytes - i.e. those written into
* the LV.
*
* @return The byte array containing the LV formatted structure.
*/
public byte[] getArray() {
return mTlvImpl.getArray();
}
}
/**
* Utility class used when iterating over an LV formatted byte-array. Use
* {@link LvBufferUtils.LvIterable} to iterate over array. A {@link LvBufferUtils.LvElement}
* represents each entry in a LV formatted byte-array.
*/
public static class LvElement {
/**
* The Length (L) field of the current LV element.
*/
public int length;
/**
* The Value (V) field - a raw byte array representing the current LV
* element where the entry starts at {@link LvBufferUtils.LvElement#offset}.
*/
public byte[] refArray;
/**
* The offset to be used into {@link LvBufferUtils.LvElement#refArray} to access the
* raw data representing the current LV element.
*/
public int offset;
private LvElement(int length, @Nullable byte[] refArray, int offset) {
this.length = length;
this.refArray = refArray;
this.offset = offset;
}
/**
* Utility function to return a byte representation of a LV element of
* length 1. Note: an attempt to call this function on a LV item whose
* {@link LvBufferUtils.LvElement#length} is != 1 will result in an exception.
*
* @return byte representation of current LV element.
*/
public byte getByte() {
if (length != 1) {
throw new IllegalArgumentException(
"Accesing a byte from a LV element of length " + length);
}
return refArray[offset];
}
/**
* Utility function to return a short representation of a LV element of
* length 2. Note: an attempt to call this function on a LV item whose
* {@link LvBufferUtils.LvElement#length} is != 2 will result in an exception.
*
* @return short representation of current LV element.
*/
public short getShort() {
if (length != 2) {
throw new IllegalArgumentException(
"Accesing a short from a LV element of length " + length);
}
return Memory.peekShort(refArray, offset, ByteOrder.BIG_ENDIAN);
}
/**
* Utility function to return an integer representation of a LV element
* of length 4. Note: an attempt to call this function on a LV item
* whose {@link LvBufferUtils.LvElement#length} is != 4 will result in an exception.
*
* @return integer representation of current LV element.
*/
public int getInt() {
if (length != 4) {
throw new IllegalArgumentException(
"Accesing an int from a LV element of length " + length);
}
return Memory.peekInt(refArray, offset, ByteOrder.BIG_ENDIAN);
}
/**
* Utility function to return a String representation of a LV element.
*
* @return String representation of the current LV element.
*/
public String getString() {
return new String(refArray, offset, length);
}
}
/**
* Utility class to iterate over a LV formatted byte-array.
*/
public static class LvIterable implements Iterable<LvBufferUtils.LvElement> {
private final TlvBufferUtils.TlvIterable mTlvIterable;
/**
* Constructs an LvIterable object - specifying the format of the LV
* (the size of the Length field), and the byte array whose data is to be parsed.
*
* @param lengthSize Number of bytes sued for the Length (L) field.
* Values values are 1 or 2 bytes.
* @param array The LV formatted byte-array to parse.
*/
public LvIterable(int lengthSize, @Nullable byte[] array) {
mTlvIterable = new TlvBufferUtils.TlvIterable(0, lengthSize, array);
}
/**
* Prints out a parsed representation of the LV-formatted byte array.
* Whenever possible bytes, shorts, and integer are printed out (for
* fields whose length is 1, 2, or 4 respectively).
*/
@Override
public String toString() {
return mTlvIterable.toString();
}
/**
* Returns an iterator to step through a LV formatted byte-array. The
* individual elements returned by the iterator are {@link LvBufferUtils.LvElement}.
*/
@Override
public Iterator<LvBufferUtils.LvElement> iterator() {
return new Iterator<LvBufferUtils.LvElement>() {
private Iterator<TlvBufferUtils.TlvElement> mTlvIterator = mTlvIterable.iterator();
@Override
public boolean hasNext() {
return mTlvIterator.hasNext();
}
@Override
public LvBufferUtils.LvElement next() {
TlvBufferUtils.TlvElement tlvE = mTlvIterator.next();
return new LvElement(tlvE.length, tlvE.refArray, tlvE.offset);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
/**
* Validates that a LV array is constructed correctly. I.e. that its specified Length
* fields correctly fill the specified length (and do not overshoot).
*
* @param array The LV array to verify.
* @param lengthSize The size (in bytes) of the length field. Valid values are 1 or 2.
* @return A boolean indicating whether the array is valid (true) or invalid (false).
*/
public static boolean isValid(@Nullable byte[] array, int lengthSize) {
return TlvBufferUtils.isValid(array, 0, lengthSize);
}
}

View File

@@ -28,6 +28,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
/** /**
* Defines the configuration of a Aware publish session. Built using * Defines the configuration of a Aware publish session. Built using
@@ -84,7 +85,8 @@ public final class PublishConfig implements Parcelable {
/** @hide */ /** @hide */
public final boolean mEnableTerminateNotification; public final boolean mEnableTerminateNotification;
private PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter, /** @hide */
public PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
int publishType, int publichCount, int ttlSec, boolean enableTerminateNotification) { int publishType, int publichCount, int ttlSec, boolean enableTerminateNotification) {
mServiceName = serviceName; mServiceName = serviceName;
mServiceSpecificInfo = serviceSpecificInfo; mServiceSpecificInfo = serviceSpecificInfo;
@@ -99,9 +101,9 @@ public final class PublishConfig implements Parcelable {
public String toString() { public String toString() {
return "PublishConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + ( return "PublishConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
(mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo)) (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
+ ", mTxFilter=" + (new LvBufferUtils.LvIterable(1, mMatchFilter)).toString() + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
+ ", mPublishType=" + mPublishType + ", mPublishCount=" + mPublishCount mMatchFilter)).toString() + ", mPublishType=" + mPublishType + ", mPublishCount="
+ ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification=" + mPublishCount + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
+ mEnableTerminateNotification + "]"; + mEnableTerminateNotification + "]";
} }
@@ -186,7 +188,7 @@ public final class PublishConfig implements Parcelable {
throws IllegalArgumentException { throws IllegalArgumentException {
WifiAwareUtils.validateServiceName(mServiceName); WifiAwareUtils.validateServiceName(mServiceName);
if (!LvBufferUtils.isValid(mMatchFilter, 1)) { if (!TlvBufferUtils.isValid(mMatchFilter, 0, 1)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Invalid txFilter configuration - LV fields do not match up to length"); "Invalid txFilter configuration - LV fields do not match up to length");
} }
@@ -281,18 +283,17 @@ public final class PublishConfig implements Parcelable {
* The match filter for a publish session. Used to determine whether a service * The match filter for a publish session. Used to determine whether a service
* discovery occurred - in addition to relying on the service name. * discovery occurred - in addition to relying on the service name.
* <p> * <p>
* Format is an LV byte array: a single byte Length field followed by L bytes (the value of
* the Length field) of a value blob.
* <p>
* Optional. Empty by default. * Optional. Empty by default.
* *
* @param matchFilter The byte-array containing the LV formatted match filter. * @param matchFilter A list of match filter entries (each of which is an arbitrary byte
* array).
* *
* @return The builder to facilitate chaining * @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}. * {@code builder.setXXX(..).setXXX(..)}.
*/ */
public Builder setMatchFilter(@Nullable byte[] matchFilter) { public Builder setMatchFilter(@Nullable List<byte[]> matchFilter) {
mMatchFilter = matchFilter; mMatchFilter = new TlvBufferUtils.TlvConstructor(0, 1).allocateAndPut(
matchFilter).getArray();
return this; return this;
} }

View File

@@ -28,6 +28,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
/** /**
* Defines the configuration of a Aware subscribe session. Built using * Defines the configuration of a Aware subscribe session. Built using
@@ -106,7 +107,8 @@ public final class SubscribeConfig implements Parcelable {
/** @hide */ /** @hide */
public final boolean mEnableTerminateNotification; public final boolean mEnableTerminateNotification;
private SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter, /** @hide */
public SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
int subscribeType, int publichCount, int ttlSec, int matchStyle, int subscribeType, int publichCount, int ttlSec, int matchStyle,
boolean enableTerminateNotification) { boolean enableTerminateNotification) {
mServiceName = serviceName; mServiceName = serviceName;
@@ -123,10 +125,11 @@ public final class SubscribeConfig implements Parcelable {
public String toString() { public String toString() {
return "SubscribeConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + ( return "SubscribeConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
(mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo)) (mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
+ ", mMatchFilter=" + (new LvBufferUtils.LvIterable(1, mMatchFilter)).toString() + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
+ ", mSubscribeType=" + mSubscribeType + ", mSubscribeCount=" + mSubscribeCount mMatchFilter)).toString() + ", mSubscribeType=" + mSubscribeType
+ ", mTtlSec=" + mTtlSec + ", mMatchType=" + mMatchStyle + ", mSubscribeCount=" + mSubscribeCount + ", mTtlSec=" + mTtlSec + ", mMatchType="
+ ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]"; + mMatchStyle + ", mEnableTerminateNotification=" + mEnableTerminateNotification
+ "]";
} }
@Override @Override
@@ -213,7 +216,7 @@ public final class SubscribeConfig implements Parcelable {
throws IllegalArgumentException { throws IllegalArgumentException {
WifiAwareUtils.validateServiceName(mServiceName); WifiAwareUtils.validateServiceName(mServiceName);
if (!LvBufferUtils.isValid(mMatchFilter, 1)) { if (!TlvBufferUtils.isValid(mMatchFilter, 0, 1)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Invalid matchFilter configuration - LV fields do not match up to length"); "Invalid matchFilter configuration - LV fields do not match up to length");
} }
@@ -313,18 +316,17 @@ public final class SubscribeConfig implements Parcelable {
* The match filter for a subscribe session. Used to determine whether a service * The match filter for a subscribe session. Used to determine whether a service
* discovery occurred - in addition to relying on the service name. * discovery occurred - in addition to relying on the service name.
* <p> * <p>
* Format is an LV byte array: a single byte Length field followed by L bytes (the value of
* the Length field) of a value blob.
* <p>
* Optional. Empty by default. * Optional. Empty by default.
* *
* @param matchFilter The byte-array containing the LV formatted match filter. * @param matchFilter A list of match filter entries (each of which is an arbitrary byte
* array).
* *
* @return The builder to facilitate chaining * @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}. * {@code builder.setXXX(..).setXXX(..)}.
*/ */
public Builder setMatchFilter(@Nullable byte[] matchFilter) { public Builder setMatchFilter(@Nullable List<byte[]> matchFilter) {
mMatchFilter = matchFilter; mMatchFilter = new TlvBufferUtils.TlvConstructor(0, 1).allocateAndPut(
matchFilter).getArray();
return this; return this;
} }

View File

@@ -22,8 +22,10 @@ import libcore.io.Memory;
import java.nio.BufferOverflowException; import java.nio.BufferOverflowException;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
/** /**
@@ -32,7 +34,7 @@ import java.util.NoSuchElementException;
* the Type field and the Length field. A Type field size of 0 is allowed - * the Type field and the Length field. A Type field size of 0 is allowed -
* allowing usage for LV (no T) array formats. * allowing usage for LV (no T) array formats.
* *
* @hide PROPOSED_AWARE_API * @hide
*/ */
public class TlvBufferUtils { public class TlvBufferUtils {
private TlvBufferUtils() { private TlvBufferUtils() {
@@ -110,6 +112,31 @@ public class TlvBufferUtils {
return this; return this;
} }
/**
* Creates a TLV array (of the previously specified Type and Length sizes) from the input
* list. Allocates an array matching the contents (and required Type and Length
* fields), copies the contents, and set the Length fields. The Type field is set to 0.
*
* @param list A list of fields to be added to the TLV buffer.
* @return The constructor of the TLV.
*/
public TlvConstructor allocateAndPut(@Nullable List<byte[]> list) {
if (list != null) {
int size = 0;
for (byte[] field : list) {
size += mTypeSize + mLengthSize;
if (field != null) {
size += field.length;
}
}
allocate(size);
for (byte[] field : list) {
putByteArray(0, field);
}
}
return this;
}
/** /**
* Copies a byte into the TLV with the indicated type. For an LV * Copies a byte into the TLV with the indicated type. For an LV
* formatted structure (i.e. typeLength=0 in {@link TlvConstructor * formatted structure (i.e. typeLength=0 in {@link TlvConstructor
@@ -319,6 +346,10 @@ public class TlvBufferUtils {
this.length = length; this.length = length;
this.refArray = refArray; this.refArray = refArray;
this.offset = offset; this.offset = offset;
if (offset + length > refArray.length) {
throw new BufferOverflowException();
}
} }
/** /**
@@ -393,7 +424,7 @@ public class TlvBufferUtils {
* @param typeSize Number of bytes used for the Type (T) field. Valid * @param typeSize Number of bytes used for the Type (T) field. Valid
* values are 0 (i.e. indicating the format is LV rather than * values are 0 (i.e. indicating the format is LV rather than
* TLV), 1, and 2 bytes. * TLV), 1, and 2 bytes.
* @param lengthSize Number of bytes sued for the Length (L) field. * @param lengthSize Number of bytes used for the Length (L) field.
* Values values are 1 or 2 bytes. * Values values are 1 or 2 bytes.
* @param array The TLV formatted byte-array to parse. * @param array The TLV formatted byte-array to parse.
*/ */
@@ -449,6 +480,18 @@ public class TlvBufferUtils {
return builder.toString(); return builder.toString();
} }
/**
* Returns a List with the raw contents (no types) of the iterator.
*/
public List<byte[]> toList() {
List<byte[]> list = new ArrayList<>();
for (TlvElement tlv : this) {
list.add(Arrays.copyOfRange(tlv.refArray, tlv.offset, tlv.offset + tlv.length));
}
return list;
}
/** /**
* Returns an iterator to step through a TLV formatted byte-array. The * Returns an iterator to step through a TLV formatted byte-array. The
* individual elements returned by the iterator are {@link TlvElement}. * individual elements returned by the iterator are {@link TlvElement}.

View File

@@ -69,8 +69,9 @@ public class WifiAwareCharacteristics implements Parcelable {
/** /**
* Returns the maximum length of byte array that can be used to specify a Aware match filter. * Returns the maximum length of byte array that can be used to specify a Aware match filter.
* Restricts the parameters of the {@link PublishConfig.Builder#setMatchFilter(byte[])} and * Restricts the parameters of the
* {@link SubscribeConfig.Builder#setMatchFilter(byte[])}. * {@link PublishConfig.Builder#setMatchFilter(java.util.List<byte[]>)} and
* {@link SubscribeConfig.Builder#setMatchFilter(java.util.List<byte[]>)}.
* *
* @return A positive integer, maximum legngth of byte array for Aware discovery match filter. * @return A positive integer, maximum legngth of byte array for Aware discovery match filter.
*/ */

View File

@@ -140,7 +140,7 @@ public class WifiAwareDiscoveryBaseSession {
* Sends a message to the specified destination. Aware messages are transmitted in the context * Sends a message to the specified destination. Aware messages are transmitted in the context
* of a discovery session - executed subsequent to a publish/subscribe * of a discovery session - executed subsequent to a publish/subscribe
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
* byte[], byte[])} event. * byte[], java.util.List<byte[]>)} event.
* <p> * <p>
* Aware messages are not guaranteed delivery. Callbacks on * Aware messages are not guaranteed delivery. Callbacks on
* {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully, * {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
@@ -154,7 +154,7 @@ public class WifiAwareDiscoveryBaseSession {
* *
* @param peerHandle The peer's handle for the message. Must be a result of an * @param peerHandle The peer's handle for the message. Must be a result of an
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
* byte[], byte[])} or * byte[], java.util.List<byte[]>)} or
* {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
* byte[])} events. * byte[])} events.
* @param messageId An arbitrary integer used by the caller to identify the message. The same * @param messageId An arbitrary integer used by the caller to identify the message. The same
@@ -187,7 +187,7 @@ public class WifiAwareDiscoveryBaseSession {
* Sends a message to the specified destination. Aware messages are transmitted in the context * Sends a message to the specified destination. Aware messages are transmitted in the context
* of a discovery session - executed subsequent to a publish/subscribe * of a discovery session - executed subsequent to a publish/subscribe
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
* byte[], byte[])} event. * byte[], java.util.List<byte[]>)} event.
* <p> * <p>
* Aware messages are not guaranteed delivery. Callbacks on * Aware messages are not guaranteed delivery. Callbacks on
* {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully, * {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
@@ -203,7 +203,7 @@ public class WifiAwareDiscoveryBaseSession {
* *
* @param peerHandle The peer's handle for the message. Must be a result of an * @param peerHandle The peer's handle for the message. Must be a result of an
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
* byte[], byte[])} or * byte[], java.util.List<byte[]>)} or
* {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
* byte[])} events. * byte[])} events.
* @param messageId An arbitrary integer used by the caller to identify the message. The same * @param messageId An arbitrary integer used by the caller to identify the message. The same
@@ -220,7 +220,7 @@ public class WifiAwareDiscoveryBaseSession {
/** /**
* Start a ranging operation with the specified peers. The peer IDs are obtained from an * Start a ranging operation with the specified peers. The peer IDs are obtained from an
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
* byte[], byte[])} or * byte[], java.util.List<byte[]>)} or
* {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
* byte[])} operation - can * byte[])} operation - can
* only range devices which are part of an ongoing discovery session. * only range devices which are part of an ongoing discovery session.
@@ -266,7 +266,7 @@ public class WifiAwareDiscoveryBaseSession {
* *
* @param peerHandle The peer's handle obtained through * @param peerHandle The peer's handle obtained through
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
* byte[], byte[])} or * byte[], java.util.List<byte[]>)} or
* {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle, * {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
* byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
* from only that peer. A RESPONDER may specified a null - indicating that * from only that peer. A RESPONDER may specified a null - indicating that

View File

@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.List;
/** /**
* Base class for Aware session events callbacks. Should be extended by * Base class for Aware session events callbacks. Should be extended by
@@ -130,11 +131,10 @@ public class WifiAwareDiscoverySessionCallback {
* @param serviceSpecificInfo The service specific information (arbitrary * @param serviceSpecificInfo The service specific information (arbitrary
* byte array) provided by the peer as part of its discovery * byte array) provided by the peer as part of its discovery
* configuration. * configuration.
* @param matchFilter The filter (Tx on advertiser and Rx on listener) which * @param matchFilter The filter which resulted in this service discovery.
* resulted in this service discovery.
*/ */
public void onServiceDiscovered(WifiAwareManager.PeerHandle peerHandle, public void onServiceDiscovered(WifiAwareManager.PeerHandle peerHandle,
byte[] serviceSpecificInfo, byte[] matchFilter) { byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
/* empty */ /* empty */
} }

View File

@@ -45,7 +45,9 @@ import org.json.JSONObject;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.nio.BufferOverflowException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
/** /**
* This class provides the primary API for managing Wi-Fi Aware operations: * This class provides the primary API for managing Wi-Fi Aware operations:
@@ -874,12 +876,22 @@ public class WifiAwareManager {
case CALLBACK_SESSION_TERMINATED: case CALLBACK_SESSION_TERMINATED:
onProxySessionTerminated(msg.arg1); onProxySessionTerminated(msg.arg1);
break; break;
case CALLBACK_MATCH: case CALLBACK_MATCH: {
mOriginalCallback.onServiceDiscovered( List<byte[]> matchFilter = null;
new PeerHandle(msg.arg1), byte[] arg = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2);
try {
matchFilter = new TlvBufferUtils.TlvIterable(0, 1, arg).toList();
} catch (BufferOverflowException e) {
matchFilter = null;
Log.e(TAG, "onServiceDiscovered: invalid match filter byte array '"
+ new String(HexEncoding.encode(arg))
+ "' - cannot be parsed: e=" + e);
}
mOriginalCallback.onServiceDiscovered(new PeerHandle(msg.arg1),
msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2)); matchFilter);
break; break;
}
case CALLBACK_MESSAGE_SEND_SUCCESS: case CALLBACK_MESSAGE_SEND_SUCCESS:
mOriginalCallback.onMessageSendSucceeded(msg.arg1); mOriginalCallback.onMessageSendSucceeded(msg.arg1);
break; break;
@@ -966,7 +978,7 @@ public class WifiAwareManager {
@Override @Override
public void onMessageReceived(int peerId, byte[] message) { public void onMessageReceived(int peerId, byte[] message) {
if (VDBG) { if (VDBG) {
Log.v(TAG, "onMessageReceived: peerId='" + peerId); Log.v(TAG, "onMessageReceived: peerId=" + peerId);
} }
Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_RECEIVED); Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_RECEIVED);

View File

@@ -24,6 +24,10 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ErrorCollector; import org.junit.rules.ErrorCollector;
import java.nio.BufferOverflowException;
import java.util.ArrayList;
import java.util.List;
/** /**
* Unit test harness for TlvBufferUtils class. * Unit test harness for TlvBufferUtils class.
*/ */
@@ -47,9 +51,9 @@ public class TlvBufferUtilsTest {
collector.checkThat("tlv11-correct-construction", collector.checkThat("tlv11-correct-construction",
tlv11.getArray(), equalTo(new byte[]{0, 1, 2, 2, 3, 0, 1, 2})); tlv11.getArray(), equalTo(new byte[]{0, 1, 2, 2, 3, 0, 1, 2}));
LvBufferUtils.LvConstructor tlv01 = new LvBufferUtils.LvConstructor(1); TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
tlv01.allocate(15); tlv01.allocate(15);
tlv01.putByte((byte) 2); tlv01.putByte(0, (byte) 2);
tlv01.putByteArray(2, new byte[] { tlv01.putByteArray(2, new byte[] {
0, 1, 2 }); 0, 1, 2 });
@@ -60,10 +64,63 @@ public class TlvBufferUtilsTest {
TlvBufferUtils.isValid(tlv11.getArray(), 1, 1), TlvBufferUtils.isValid(tlv11.getArray(), 1, 1),
equalTo(true)); equalTo(true));
collector.checkThat("tlv01-valid", collector.checkThat("tlv01-valid",
LvBufferUtils.isValid(tlv01.getArray(), 1), TlvBufferUtils.isValid(tlv01.getArray(), 0, 1),
equalTo(true)); equalTo(true));
} }
/**
* Verify that can build a valid TLV from a List of byte[].
*/
@Test
public void testTlvListOperations() {
byte[] entry1 = { 1, 2, 3 };
byte[] entry2 = { 4, 5 };
byte[] entry3 = new byte[0];
List<byte[]> data = new ArrayList<>();
data.add(entry1);
data.add(entry2);
data.add(entry3);
data.add(null); // zero-length should work
TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
tlv01.allocateAndPut(data);
byte[] tlvData = tlv01.getArray();
List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, tlvData).toList();
collector.checkThat("tlvData-correct-length", tlvData.length,
equalTo(entry1.length + 1 + entry2.length + 1 + entry3.length + 1 + 1));
collector.checkThat("parsedList-correct-length", parsedList.size(), equalTo(4));
collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(entry1));
collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(entry2));
collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(entry3));
collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0]));
}
/**
* Verify that can parse a (correctly formatted) byte array to a list.
*/
@Test
public void testTlvParseToList() {
byte[] validTlv01 = { 0, 1, 55, 2, 33, 66, 0 };
List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, validTlv01).toList();
collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(new byte[0]));
collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(new byte[] { 55 }));
collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(new byte[] { 33, 66 }));
collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0]));
}
/**
* Verify that an exception is thrown when trying to parse an invalid array.
*/
@Test(expected = BufferOverflowException.class)
public void testTlvParseToListError() {
byte[] invalidTlv01 = { 0, 1, 55, 2, 55, 66, 3 }; // bad data
List<byte[]> data = new TlvBufferUtils.TlvIterable(0, 1, invalidTlv01).toList();
}
@Test @Test
public void testTlvIterate() { public void testTlvIterate() {
final String ascii = "ABC"; final String ascii = "ABC";
@@ -137,7 +194,7 @@ public class TlvBufferUtilsTest {
TlvBufferUtils.isValid(tlv22.getArray(), 2, 2), TlvBufferUtils.isValid(tlv22.getArray(), 2, 2),
equalTo(true)); equalTo(true));
collector.checkThat("tlv02-valid", collector.checkThat("tlv02-valid",
LvBufferUtils.isValid(tlv02.getArray(), 2), TlvBufferUtils.isValid(tlv02.getArray(), 0, 2),
equalTo(true)); equalTo(true));
} }
@@ -211,15 +268,15 @@ public class TlvBufferUtilsTest {
*/ */
@Test @Test
public void testTlvInvalidByteArray() { public void testTlvInvalidByteArray() {
LvBufferUtils.LvConstructor tlv01 = new LvBufferUtils.LvConstructor(1); TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
tlv01.allocate(15); tlv01.allocate(15);
tlv01.putByte((byte) 2); tlv01.putByte(0, (byte) 2);
tlv01.putByteArray(2, new byte[]{0, 1, 2}); tlv01.putByteArray(2, new byte[]{0, 1, 2});
byte[] array = tlv01.getArray(); byte[] array = tlv01.getArray();
array[0] = 10; array[0] = 10;
collector.checkThat("tlv01-invalid", collector.checkThat("tlv01-invalid",
LvBufferUtils.isValid(array, 1), equalTo(false)); TlvBufferUtils.isValid(array, 0, 1), equalTo(false));
} }
} }

View File

@@ -49,6 +49,8 @@ import org.mockito.InOrder;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.util.List;
/** /**
* Unit test harness for WifiAwareManager class. * Unit test harness for WifiAwareManager class.
*/ */
@@ -276,7 +278,7 @@ public class WifiAwareManagerTest {
final PublishConfig publishConfig = new PublishConfig.Builder().build(); final PublishConfig publishConfig = new PublishConfig.Builder().build();
final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(873); final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(873);
final String string1 = "hey from here..."; final String string1 = "hey from here...";
final String string2 = "some other arbitrary string..."; final byte[] matchFilter = { 1, 12, 2, 31, 32 };
final int messageId = 2123; final int messageId = 2123;
final int reason = AWARE_STATUS_ERROR; final int reason = AWARE_STATUS_ERROR;
@@ -292,6 +294,8 @@ public class WifiAwareManagerTest {
.forClass(WifiAwarePublishDiscoverySession.class); .forClass(WifiAwarePublishDiscoverySession.class);
ArgumentCaptor<WifiAwareManager.PeerHandle> peerIdCaptor = ArgumentCaptor.forClass( ArgumentCaptor<WifiAwareManager.PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(
WifiAwareManager.PeerHandle.class); WifiAwareManager.PeerHandle.class);
ArgumentCaptor<List<byte[]>> matchFilterCaptor = ArgumentCaptor.forClass(
(Class) List.class);
// (0) connect + success // (0) connect + success
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null); mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
@@ -314,8 +318,7 @@ public class WifiAwareManagerTest {
// (3) ... // (3) ...
publishSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes()); publishSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
string2.getBytes());
sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes()); sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
sessionProxyCallback.getValue().onMessageSendFail(messageId, reason); sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
sessionProxyCallback.getValue().onMessageSendSuccess(messageId); sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
@@ -324,13 +327,22 @@ public class WifiAwareManagerTest {
inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId), inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0)); eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(), inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
eq(string1.getBytes()), eq(string2.getBytes())); eq(string1.getBytes()),
assertEquals(((WifiAwareManager.PeerHandle) peerIdCaptor.getValue()).peerId, matchFilterCaptor.capture());
peerHandle.peerId);
// note: need to capture/compare elements since the Mockito eq() is a shallow comparator
List<byte[]> parsedMatchFilter = new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList();
collector.checkThat("match-filter-size", parsedMatchFilter.size(),
equalTo(matchFilterCaptor.getValue().size()));
collector.checkThat("match-filter-entry0", parsedMatchFilter.get(0),
equalTo(matchFilterCaptor.getValue().get(0)));
collector.checkThat("match-filter-entry1", parsedMatchFilter.get(1),
equalTo(matchFilterCaptor.getValue().get(1)));
assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(), inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
eq(string1.getBytes())); eq(string1.getBytes()));
assertEquals(((WifiAwareManager.PeerHandle) peerIdCaptor.getValue()).peerId, assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
peerHandle.peerId);
inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId)); inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId)); inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
@@ -418,7 +430,7 @@ public class WifiAwareManagerTest {
final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(873); final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(873);
final String string1 = "hey from here..."; final String string1 = "hey from here...";
final String string2 = "some other arbitrary string..."; final byte[] matchFilter = { 1, 12, 3, 31, 32 }; // bad data!
final int messageId = 2123; final int messageId = 2123;
final int reason = AWARE_STATUS_ERROR; final int reason = AWARE_STATUS_ERROR;
@@ -456,8 +468,7 @@ public class WifiAwareManagerTest {
// (3) ... // (3) ...
subscribeSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes()); subscribeSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
string2.getBytes());
sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes()); sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
sessionProxyCallback.getValue().onMessageSendFail(messageId, reason); sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
sessionProxyCallback.getValue().onMessageSendSuccess(messageId); sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
@@ -466,13 +477,11 @@ public class WifiAwareManagerTest {
inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId), inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0)); eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(), inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
eq(string1.getBytes()), eq(string2.getBytes())); eq(string1.getBytes()), (List<byte[]>) isNull());
assertEquals(((WifiAwareManager.PeerHandle) peerIdCaptor.getValue()).peerId, assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
peerHandle.peerId);
inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(), inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
eq(string1.getBytes())); eq(string1.getBytes()));
assertEquals(((WifiAwareManager.PeerHandle) peerIdCaptor.getValue()).peerId, assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
peerHandle.peerId);
inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId)); inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId)); inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
@@ -676,8 +685,7 @@ public class WifiAwareManagerTest {
public void testSubscribeConfigBuilder() { public void testSubscribeConfigBuilder() {
final String serviceName = "some_service_or_other"; final String serviceName = "some_service_or_other";
final String serviceSpecificInfo = "long arbitrary string with some info"; final String serviceSpecificInfo = "long arbitrary string with some info";
final byte[] matchFilter = { final byte[] matchFilter = { 1, 16, 1, 22 };
0, 1, 16, 1, 22 };
final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE; final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
final int subscribeCount = 10; final int subscribeCount = 10;
final int subscribeTtl = 15; final int subscribeTtl = 15;
@@ -685,7 +693,8 @@ public class WifiAwareManagerTest {
final boolean enableTerminateNotification = false; final boolean enableTerminateNotification = false;
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName) SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
.setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(matchFilter) .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setSubscribeType(subscribeType) .setSubscribeType(subscribeType)
.setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle) .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
.setTerminateNotificationEnabled(enableTerminateNotification).build(); .setTerminateNotificationEnabled(enableTerminateNotification).build();
@@ -709,8 +718,7 @@ public class WifiAwareManagerTest {
public void testSubscribeConfigParcel() { public void testSubscribeConfigParcel() {
final String serviceName = "some_service_or_other"; final String serviceName = "some_service_or_other";
final String serviceSpecificInfo = "long arbitrary string with some info"; final String serviceSpecificInfo = "long arbitrary string with some info";
final byte[] matchFilter = { final byte[] matchFilter = { 1, 16, 1, 22 };
0, 1, 16, 1, 22 };
final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE; final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
final int subscribeCount = 10; final int subscribeCount = 10;
final int subscribeTtl = 15; final int subscribeTtl = 15;
@@ -718,7 +726,8 @@ public class WifiAwareManagerTest {
final boolean enableTerminateNotification = true; final boolean enableTerminateNotification = true;
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName) SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
.setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(matchFilter) .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setSubscribeType(subscribeType) .setSubscribeType(subscribeType)
.setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle) .setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
.setTerminateNotificationEnabled(enableTerminateNotification).build(); .setTerminateNotificationEnabled(enableTerminateNotification).build();
@@ -780,15 +789,15 @@ public class WifiAwareManagerTest {
public void testPublishConfigBuilder() { public void testPublishConfigBuilder() {
final String serviceName = "some_service_or_other"; final String serviceName = "some_service_or_other";
final String serviceSpecificInfo = "long arbitrary string with some info"; final String serviceSpecificInfo = "long arbitrary string with some info";
final byte[] matchFilter = { final byte[] matchFilter = { 1, 16, 1, 22 };
0, 1, 16, 1, 22 };
final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED; final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
final int publishCount = 10; final int publishCount = 10;
final int publishTtl = 15; final int publishTtl = 15;
final boolean enableTerminateNotification = false; final boolean enableTerminateNotification = false;
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName) PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
.setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(matchFilter) .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setPublishType(publishType) .setPublishType(publishType)
.setPublishCount(publishCount).setTtlSec(publishTtl) .setPublishCount(publishCount).setTtlSec(publishTtl)
.setTerminateNotificationEnabled(enableTerminateNotification).build(); .setTerminateNotificationEnabled(enableTerminateNotification).build();
@@ -809,15 +818,15 @@ public class WifiAwareManagerTest {
public void testPublishConfigParcel() { public void testPublishConfigParcel() {
final String serviceName = "some_service_or_other"; final String serviceName = "some_service_or_other";
final String serviceSpecificInfo = "long arbitrary string with some info"; final String serviceSpecificInfo = "long arbitrary string with some info";
final byte[] matchFilter = { final byte[] matchFilter = { 1, 16, 1, 22 };
0, 1, 16, 1, 22 };
final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED; final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
final int publishCount = 10; final int publishCount = 10;
final int publishTtl = 15; final int publishTtl = 15;
final boolean enableTerminateNotification = false; final boolean enableTerminateNotification = false;
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName) PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
.setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(matchFilter) .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setPublishType(publishType) .setPublishType(publishType)
.setPublishCount(publishCount).setTtlSec(publishTtl) .setPublishCount(publishCount).setTtlSec(publishTtl)
.setTerminateNotificationEnabled(enableTerminateNotification).build(); .setTerminateNotificationEnabled(enableTerminateNotification).build();