summaryrefslogtreecommitdiff
path: root/wifi
diff options
context:
space:
mode:
Diffstat (limited to 'wifi')
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl6
-rw-r--r--wifi/java/android/net/wifi/RttManager.aidl5
-rw-r--r--wifi/java/android/net/wifi/RttManager.java73
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java38
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java37
-rw-r--r--wifi/java/android/net/wifi/nan/ConfigRequest.java129
-rw-r--r--wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl (renamed from wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl)12
-rw-r--r--wifi/java/android/net/wifi/nan/IWifiNanManager.aidl40
-rw-r--r--wifi/java/android/net/wifi/nan/IWifiNanSessionCallback.aidl (renamed from wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl)11
-rw-r--r--wifi/java/android/net/wifi/nan/PublishConfig.aidl (renamed from wifi/java/android/net/wifi/nan/SubscribeData.aidl)2
-rw-r--r--wifi/java/android/net/wifi/nan/PublishConfig.java (renamed from wifi/java/android/net/wifi/nan/PublishData.java)250
-rw-r--r--wifi/java/android/net/wifi/nan/PublishSettings.aidl19
-rw-r--r--wifi/java/android/net/wifi/nan/PublishSettings.java204
-rw-r--r--wifi/java/android/net/wifi/nan/SubscribeConfig.aidl (renamed from wifi/java/android/net/wifi/nan/PublishData.aidl)2
-rw-r--r--wifi/java/android/net/wifi/nan/SubscribeConfig.java584
-rw-r--r--wifi/java/android/net/wifi/nan/SubscribeData.java329
-rw-r--r--wifi/java/android/net/wifi/nan/SubscribeSettings.aidl19
-rw-r--r--wifi/java/android/net/wifi/nan/SubscribeSettings.java205
-rw-r--r--wifi/java/android/net/wifi/nan/WifiNanEventCallback.java92
-rw-r--r--wifi/java/android/net/wifi/nan/WifiNanEventListener.java205
-rw-r--r--wifi/java/android/net/wifi/nan/WifiNanManager.java851
-rw-r--r--wifi/java/android/net/wifi/nan/WifiNanPublishSession.java33
-rw-r--r--wifi/java/android/net/wifi/nan/WifiNanSession.java149
-rw-r--r--wifi/java/android/net/wifi/nan/WifiNanSessionCallback.java213
-rw-r--r--wifi/java/android/net/wifi/nan/WifiNanSessionListener.java439
-rw-r--r--wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java33
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pDevice.java14
27 files changed, 2251 insertions, 1743 deletions
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 9268a2b7cbe2..3674f0f4baa7 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -169,5 +169,11 @@ interface IWifiManager
void factoryReset();
Network getCurrentNetwork();
+
+ byte[] retrieveBackupData();
+
+ void restoreBackupData(in byte[] data);
+
+ void restoreSupplicantBackupData(in byte[] supplicantData, in byte[] ipConfigData);
}
diff --git a/wifi/java/android/net/wifi/RttManager.aidl b/wifi/java/android/net/wifi/RttManager.aidl
index 5c6d44710ea5..9479cf0b936e 100644
--- a/wifi/java/android/net/wifi/RttManager.aidl
+++ b/wifi/java/android/net/wifi/RttManager.aidl
@@ -15,4 +15,7 @@
*/
package android.net.wifi;
-parcelable RttManager.RttCapabilities; \ No newline at end of file
+
+parcelable RttManager.RttCapabilities;
+parcelable RttManager.ParcelableRttResults;
+parcelable RttManager.ParcelableRttParams;
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index 590ff1b1bfaa..ff632a5cdc7c 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -472,6 +472,34 @@ public class RttManager {
preamble = PREAMBLE_HT;
bandwidth = RTT_BW_20_SUPPORT;
}
+
+ /**
+ * {@hide}
+ */
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("deviceType=" + deviceType);
+ sb.append(", requestType=" + requestType);
+ sb.append(", secure=" + secure);
+ sb.append(", bssid=" + bssid);
+ sb.append(", frequency=" + frequency);
+ sb.append(", channelWidth=" + channelWidth);
+ sb.append(", centerFreq0=" + centerFreq0);
+ sb.append(", centerFreq1=" + centerFreq1);
+ sb.append(", num_samples=" + num_samples);
+ sb.append(", num_retries=" + num_retries);
+ sb.append(", numberBurst=" + numberBurst);
+ sb.append(", interval=" + interval);
+ sb.append(", numSamplesPerBurst=" + numSamplesPerBurst);
+ sb.append(", numRetriesPerMeasurementFrame=" + numRetriesPerMeasurementFrame);
+ sb.append(", numRetriesPerFTMR=" + numRetriesPerFTMR);
+ sb.append(", LCIRequest=" + LCIRequest);
+ sb.append(", LCRRequest=" + LCRRequest);
+ sb.append(", burstTimeout=" + burstTimeout);
+ sb.append(", preamble=" + preamble);
+ sb.append(", bandwidth=" + bandwidth);
+ return sb.toString();
+ }
}
/** pseudo-private class used to parcel arguments */
@@ -727,6 +755,51 @@ public class RttManager {
mResults = results;
}
+ /**
+ * {@hide}
+ */
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < mResults.length; ++i) {
+ sb.append("[" + i + "]: ");
+ sb.append("bssid=" + mResults[i].bssid);
+ sb.append(", burstNumber=" + mResults[i].burstNumber);
+ sb.append(", measurementFrameNumber=" + mResults[i].measurementFrameNumber);
+ sb.append(", successMeasurementFrameNumber="
+ + mResults[i].successMeasurementFrameNumber);
+ sb.append(", frameNumberPerBurstPeer=" + mResults[i].frameNumberPerBurstPeer);
+ sb.append(", status=" + mResults[i].status);
+ sb.append(", requestType=" + mResults[i].requestType);
+ sb.append(", measurementType=" + mResults[i].measurementType);
+ sb.append(", retryAfterDuration=" + mResults[i].retryAfterDuration);
+ sb.append(", ts=" + mResults[i].ts);
+ sb.append(", rssi=" + mResults[i].rssi);
+ sb.append(", rssi_spread=" + mResults[i].rssi_spread);
+ sb.append(", rssiSpread=" + mResults[i].rssiSpread);
+ sb.append(", tx_rate=" + mResults[i].tx_rate);
+ sb.append(", txRate=" + mResults[i].txRate);
+ sb.append(", rxRate=" + mResults[i].rxRate);
+ sb.append(", rtt_ns=" + mResults[i].rtt_ns);
+ sb.append(", rtt=" + mResults[i].rtt);
+ sb.append(", rtt_sd_ns=" + mResults[i].rtt_sd_ns);
+ sb.append(", rttStandardDeviation=" + mResults[i].rttStandardDeviation);
+ sb.append(", rtt_spread_ns=" + mResults[i].rtt_spread_ns);
+ sb.append(", rttSpread=" + mResults[i].rttSpread);
+ sb.append(", distance_cm=" + mResults[i].distance_cm);
+ sb.append(", distance=" + mResults[i].distance);
+ sb.append(", distance_sd_cm=" + mResults[i].distance_sd_cm);
+ sb.append(", distanceStandardDeviation=" + mResults[i].distanceStandardDeviation);
+ sb.append(", distance_spread_cm=" + mResults[i].distance_spread_cm);
+ sb.append(", distanceSpread=" + mResults[i].distanceSpread);
+ sb.append(", burstDuration=" + mResults[i].burstDuration);
+ sb.append(", negotiatedBurstNum=" + mResults[i].negotiatedBurstNum);
+ sb.append(", LCI=" + mResults[i].LCI);
+ sb.append(", LCR=" + mResults[i].LCR);
+ sb.append(", secure=" + mResults[i].secure);
+ }
+ return sb.toString();
+ }
+
/** Implement the Parcelable interface {@hide} */
@Override
public int describeContents() {
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 9d0c20ce4c5d..3bf88b79b8a1 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -837,25 +837,33 @@ public class WifiConfiguration implements Parcelable {
*/
public static final int DISABLED_DNS_FAILURE = 5;
/**
+ * This network is disabled because we started WPS
+ */
+ public static final int DISABLED_WPS_START = 6;
+ /**
* This network is disabled because EAP-TLS failure
*/
- public static final int DISABLED_TLS_VERSION_MISMATCH = 6;
+ public static final int DISABLED_TLS_VERSION_MISMATCH = 7;
/**
- * This network is disabled due to WifiManager disable it explicitly
+ * This network is disabled due to absence of user credentials
*/
- public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 7;
+ public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 8;
/**
* This network is disabled because no Internet connected and user do not want
*/
- public static final int DISABLED_NO_INTERNET = 8;
+ public static final int DISABLED_NO_INTERNET = 9;
/**
* This network is disabled due to WifiManager disable it explicitly
*/
- public static final int DISABLED_BY_WIFI_MANAGER = 9;
+ public static final int DISABLED_BY_WIFI_MANAGER = 10;
+ /**
+ * This network is disabled due to user switching
+ */
+ public static final int DISABLED_DUE_TO_USER_SWITCH = 11;
/**
* This Maximum disable reason value
*/
- public static final int NETWORK_SELECTION_DISABLED_MAX = 10;
+ public static final int NETWORK_SELECTION_DISABLED_MAX = 12;
/**
* Quality network selection disable reason String (for debug purpose)
@@ -867,10 +875,13 @@ public class WifiConfiguration implements Parcelable {
"NETWORK_SELECTION_DISABLED_AUTHENTICATION_FAILURE",
"NETWORK_SELECTION_DISABLED_DHCP_FAILURE",
"NETWORK_SELECTION_DISABLED_DNS_FAILURE",
+ "NETWORK_SELECTION_DISABLED_WPS_START",
"NETWORK_SELECTION_DISABLED_TLS_VERSION",
"NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
"NETWORK_SELECTION_DISABLED_NO_INTERNET",
- "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER"};
+ "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER",
+ "NETWORK_SELECTION_DISABLED_BY_USER_SWITCH"
+ };
/**
* Invalid time stamp for network selection disable
@@ -1054,7 +1065,7 @@ public class WifiConfiguration implements Parcelable {
return mHasEverConnected;
}
- private NetworkSelectionStatus() {
+ public NetworkSelectionStatus() {
// previously stored configs will not have this parameter, so we default to false.
mHasEverConnected = false;
};
@@ -1302,7 +1313,7 @@ public class WifiConfiguration implements Parcelable {
* @hide
* network selection related member
*/
- private final NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus();
+ private NetworkSelectionStatus mNetworkSelectionStatus = new NetworkSelectionStatus();
/**
* @hide
@@ -1311,6 +1322,15 @@ public class WifiConfiguration implements Parcelable {
public NetworkSelectionStatus getNetworkSelectionStatus() {
return mNetworkSelectionStatus;
}
+
+ /**
+ * Set the network selection status
+ * @hide
+ */
+ public void setNetworkSelectionStatus(NetworkSelectionStatus status) {
+ mNetworkSelectionStatus = status;
+ }
+
/**
* @hide
* Linked Configurations: represent the set of Wificonfigurations that are equivalent
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index bbc3d2fd5927..6cf1921524b3 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2737,4 +2737,41 @@ public class WifiManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Retrieve the data to be backed to save the current state.
+ * @hide
+ */
+ public byte[] retrieveBackupData() {
+ try {
+ return mService.retrieveBackupData();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Restore state from the backed up data.
+ * @hide
+ */
+ public void restoreBackupData(byte[] data) {
+ try {
+ mService.restoreBackupData(data);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Restore state from the older version of back up data.
+ * The old backup data was essentially a backup of wpa_supplicant.conf & ipconfig.txt file.
+ * @hide
+ */
+ public void restoreSupplicantBackupData(byte[] supplicantData, byte[] ipConfigData) {
+ try {
+ mService.restoreSupplicantBackupData(supplicantData, ipConfigData);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/wifi/java/android/net/wifi/nan/ConfigRequest.java b/wifi/java/android/net/wifi/nan/ConfigRequest.java
index 23e37547b9f0..759098e9b0c2 100644
--- a/wifi/java/android/net/wifi/nan/ConfigRequest.java
+++ b/wifi/java/android/net/wifi/nan/ConfigRequest.java
@@ -22,9 +22,10 @@ import android.os.Parcelable;
/**
* Defines a request object to configure a Wi-Fi NAN network. Built using
* {@link ConfigRequest.Builder}. Configuration is requested using
- * {@link WifiNanManager#requestConfig(ConfigRequest)}. Note that the actual
- * achieved configuration may be different from the requested configuration -
- * since multiple applications may request different configurations.
+ * {@link WifiNanManager#connect(android.os.Looper, WifiNanEventCallback, ConfigRequest)}
+ * . Note that the actual achieved configuration may be different from the
+ * requested configuration - since multiple applications may request different
+ * configurations.
*
* @hide PROPOSED_NAN_API
*/
@@ -73,19 +74,28 @@ public class ConfigRequest implements Parcelable {
*/
public final int mClusterHigh;
+ /**
+ * Indicates whether we want to get callbacks when our identity is changed.
+ *
+ * @hide
+ */
+ public final boolean mEnableIdentityChangeCallback;
+
private ConfigRequest(boolean support5gBand, int masterPreference, int clusterLow,
- int clusterHigh) {
+ int clusterHigh, boolean enableIdentityChangeCallback) {
mSupport5gBand = support5gBand;
mMasterPreference = masterPreference;
mClusterLow = clusterLow;
mClusterHigh = clusterHigh;
+ mEnableIdentityChangeCallback = enableIdentityChangeCallback;
}
@Override
public String toString() {
return "ConfigRequest [mSupport5gBand=" + mSupport5gBand + ", mMasterPreference="
+ mMasterPreference + ", mClusterLow=" + mClusterLow + ", mClusterHigh="
- + mClusterHigh + "]";
+ + mClusterHigh + ", mEnableIdentityChangeCallback=" + mEnableIdentityChangeCallback
+ + "]";
}
@Override
@@ -99,6 +109,7 @@ public class ConfigRequest implements Parcelable {
dest.writeInt(mMasterPreference);
dest.writeInt(mClusterLow);
dest.writeInt(mClusterHigh);
+ dest.writeInt(mEnableIdentityChangeCallback ? 1 : 0);
}
public static final Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
@@ -113,7 +124,9 @@ public class ConfigRequest implements Parcelable {
int masterPreference = in.readInt();
int clusterLow = in.readInt();
int clusterHigh = in.readInt();
- return new ConfigRequest(support5gBand, masterPreference, clusterLow, clusterHigh);
+ boolean enableIdentityChangeCallback = in.readInt() != 0;
+ return new ConfigRequest(support5gBand, masterPreference, clusterLow, clusterHigh,
+ enableIdentityChangeCallback);
}
};
@@ -130,6 +143,31 @@ public class ConfigRequest implements Parcelable {
ConfigRequest lhs = (ConfigRequest) o;
return mSupport5gBand == lhs.mSupport5gBand && mMasterPreference == lhs.mMasterPreference
+ && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh
+ && mEnableIdentityChangeCallback == lhs.mEnableIdentityChangeCallback;
+ }
+
+ /**
+ * Checks for equality of two configuration - but only considering their
+ * on-the-air NAN configuration impact.
+ *
+ * @param o Object to compare to.
+ * @return true if configuration objects have the same on-the-air
+ * configuration, false otherwise.
+ * @hide
+ */
+ public boolean equalsOnTheAir(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof ConfigRequest)) {
+ return false;
+ }
+
+ ConfigRequest lhs = (ConfigRequest) o;
+
+ return mSupport5gBand == lhs.mSupport5gBand && mMasterPreference == lhs.mMasterPreference
&& mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh;
}
@@ -141,28 +179,53 @@ public class ConfigRequest implements Parcelable {
result = 31 * result + mMasterPreference;
result = 31 * result + mClusterLow;
result = 31 * result + mClusterHigh;
+ result = 31 * result + (mEnableIdentityChangeCallback ? 1 : 0);
return result;
}
/**
+ * Validates that the contents of the ConfigRequest are valid. Otherwise
+ * throws an IllegalArgumentException.
+ *
+ * @hide
+ */
+ public void validate() throws IllegalArgumentException {
+ if (mMasterPreference < 0) {
+ throw new IllegalArgumentException(
+ "Master Preference specification must be non-negative");
+ }
+ if (mMasterPreference == 1 || mMasterPreference == 255 || mMasterPreference > 255) {
+ throw new IllegalArgumentException("Master Preference specification must not "
+ + "exceed 255 or use 1 or 255 (reserved values)");
+ }
+ if (mClusterLow < CLUSTER_ID_MIN) {
+ throw new IllegalArgumentException("Cluster specification must be non-negative");
+ }
+ if (mClusterLow > CLUSTER_ID_MAX) {
+ throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
+ }
+ if (mClusterHigh < CLUSTER_ID_MIN) {
+ throw new IllegalArgumentException("Cluster specification must be non-negative");
+ }
+ if (mClusterHigh > CLUSTER_ID_MAX) {
+ throw new IllegalArgumentException("Cluster specification must not exceed 0xFFFF");
+ }
+ if (mClusterLow > mClusterHigh) {
+ throw new IllegalArgumentException(
+ "Invalid argument combination - must have Cluster Low <= Cluster High");
+ }
+ }
+
+ /**
* Builder used to build {@link ConfigRequest} objects.
*/
public static final class Builder {
- private boolean mSupport5gBand;
- private int mMasterPreference;
- private int mClusterLow;
- private int mClusterHigh;
-
- /**
- * Default constructor for the Builder.
- */
- public Builder() {
- mSupport5gBand = false;
- mMasterPreference = 0;
- mClusterLow = 0;
- mClusterHigh = CLUSTER_ID_MAX;
- }
+ private boolean mSupport5gBand = false;
+ private int mMasterPreference = 0;
+ private int mClusterLow = CLUSTER_ID_MIN;
+ private int mClusterHigh = CLUSTER_ID_MAX;
+ private boolean mEnableIdentityChangeCallback = false;
/**
* Specify whether 5G band support is required in this request.
@@ -170,6 +233,7 @@ public class ConfigRequest implements Parcelable {
* @param support5gBand Support for 5G band is required.
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
+ * @hide PROPOSED_NAN_SYSTEM_API
*/
public Builder setSupport5gBand(boolean support5gBand) {
mSupport5gBand = support5gBand;
@@ -183,6 +247,7 @@ public class ConfigRequest implements Parcelable {
* @param masterPreference The requested master preference
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
+ * @hide PROPOSED_NAN_SYSTEM_API
*/
public Builder setMasterPreference(int masterPreference) {
if (masterPreference < 0) {
@@ -209,6 +274,7 @@ public class ConfigRequest implements Parcelable {
* @param clusterLow The lower range of the generated cluster ID.
* @return The builder to facilitate chaining
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
+ * @hide PROPOSED_NAN_SYSTEM_API
*/
public Builder setClusterLow(int clusterLow) {
if (clusterLow < CLUSTER_ID_MIN) {
@@ -233,6 +299,7 @@ public class ConfigRequest implements Parcelable {
* @param clusterHigh The upper range of the generated cluster ID.
* @return The builder to facilitate chaining
* {@code builder.setClusterLow(..).setClusterHigh(..)}.
+ * @hide PROPOSED_NAN_SYSTEM_API
*/
public Builder setClusterHigh(int clusterHigh) {
if (clusterHigh < CLUSTER_ID_MIN) {
@@ -247,6 +314,25 @@ public class ConfigRequest implements Parcelable {
}
/**
+ * Indicate whether or not we want to enable the callback to the
+ * listener on the event when the NAN device identity is changed. A
+ * device identity is it's Discovery MAC address. Depending on use-case
+ * we may want to perform some activity (e.g. re-publish). In other
+ * use-cases (typically where we're silent) there's no reason to be
+ * woken up repeatedly. Note that the MAC address is randomized at
+ * regular intervals - so do not enable unless specifically required.
+ *
+ * @param enableIdentityChangeCallback Enable the callback informing
+ * listener when identity is changed.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setEnableIdentityChangeCallback(boolean enableIdentityChangeCallback) {
+ mEnableIdentityChangeCallback = enableIdentityChangeCallback;
+ return this;
+ }
+
+ /**
* Build {@link ConfigRequest} given the current requests made on the
* builder.
*/
@@ -256,7 +342,8 @@ public class ConfigRequest implements Parcelable {
"Invalid argument combination - must have Cluster Low <= Cluster High");
}
- return new ConfigRequest(mSupport5gBand, mMasterPreference, mClusterLow, mClusterHigh);
+ return new ConfigRequest(mSupport5gBand, mMasterPreference, mClusterLow, mClusterHigh,
+ mEnableIdentityChangeCallback);
}
}
}
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl b/wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl
index fa666afd1c27..b95140e88ae7 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanEventListener.aidl
+++ b/wifi/java/android/net/wifi/nan/IWifiNanEventCallback.aidl
@@ -17,16 +17,20 @@
package android.net.wifi.nan;
import android.net.wifi.nan.ConfigRequest;
+import android.net.wifi.RttManager;
/**
* Callback interface that WifiNanManager implements
*
* {@hide}
*/
-oneway interface IWifiNanEventListener
+oneway interface IWifiNanEventCallback
{
- void onConfigCompleted(in ConfigRequest completedConfig);
- void onConfigFailed(in ConfigRequest failedConfig, int reason);
- void onNanDown(int reason);
+ void onConnectSuccess();
+ void onConnectFail(int reason);
void onIdentityChanged();
+
+ void onRangingSuccess(int rangingId, in RttManager.ParcelableRttResults results);
+ void onRangingFailure(int rangingId, int reason, in String description);
+ void onRangingAborted(int rangingId);
}
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl b/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
index f382d97762d3..efa6211a8063 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
+++ b/wifi/java/android/net/wifi/nan/IWifiNanManager.aidl
@@ -19,12 +19,11 @@ package android.net.wifi.nan;
import android.app.PendingIntent;
import android.net.wifi.nan.ConfigRequest;
-import android.net.wifi.nan.IWifiNanEventListener;
-import android.net.wifi.nan.IWifiNanSessionListener;
-import android.net.wifi.nan.PublishData;
-import android.net.wifi.nan.PublishSettings;
-import android.net.wifi.nan.SubscribeData;
-import android.net.wifi.nan.SubscribeSettings;
+import android.net.wifi.nan.IWifiNanEventCallback;
+import android.net.wifi.nan.IWifiNanSessionCallback;
+import android.net.wifi.nan.PublishConfig;
+import android.net.wifi.nan.SubscribeConfig;
+import android.net.wifi.RttManager;
/**
* Interface that WifiNanService implements
@@ -33,18 +32,25 @@ import android.net.wifi.nan.SubscribeSettings;
*/
interface IWifiNanManager
{
+ // NAN API
+ void enableUsage();
+ void disableUsage();
+ boolean isUsageEnabled();
+
// client API
- void connect(in IBinder binder, in IWifiNanEventListener listener, int events);
- void disconnect(in IBinder binder);
- void requestConfig(in ConfigRequest configRequest);
+ int connect(in IBinder binder, in IWifiNanEventCallback callback,
+ in ConfigRequest configRequest);
+ void disconnect(int clientId, in IBinder binder);
+
+ void publish(int clientId, in PublishConfig publishConfig, in IWifiNanSessionCallback callback);
+ void subscribe(int clientId, in SubscribeConfig subscribeConfig,
+ in IWifiNanSessionCallback callback);
// session API
- int createSession(in IWifiNanSessionListener listener, int events);
- void publish(int sessionId, in PublishData publishData, in PublishSettings publishSettings);
- void subscribe(int sessionId, in SubscribeData subscribeData,
- in SubscribeSettings subscribeSettings);
- void sendMessage(int sessionId, int peerId, in byte[] message, int messageLength,
- int messageId);
- void stopSession(int sessionId);
- void destroySession(int sessionId);
+ void updatePublish(int clientId, int sessionId, in PublishConfig publishConfig);
+ void updateSubscribe(int clientId, int sessionId, in SubscribeConfig subscribeConfig);
+ void sendMessage(int clientId, int sessionId, int peerId, in byte[] message, int messageLength,
+ int messageId, int retryCount);
+ void terminateSession(int clientId, int sessionId);
+ int startRanging(int clientId, int sessionId, in RttManager.ParcelableRttParams parms);
}
diff --git a/wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl b/wifi/java/android/net/wifi/nan/IWifiNanSessionCallback.aidl
index d60d8caae70e..7162be72a3c5 100644
--- a/wifi/java/android/net/wifi/nan/IWifiNanSessionListener.aidl
+++ b/wifi/java/android/net/wifi/nan/IWifiNanSessionCallback.aidl
@@ -21,13 +21,12 @@ package android.net.wifi.nan;
*
* {@hide}
*/
-oneway interface IWifiNanSessionListener
+oneway interface IWifiNanSessionCallback
{
- void onPublishFail(int reason);
- void onPublishTerminated(int reason);
-
- void onSubscribeFail(int reason);
- void onSubscribeTerminated(int reason);
+ void onSessionStarted(int sessionId);
+ void onSessionConfigSuccess();
+ void onSessionConfigFail(int reason);
+ void onSessionTerminated(int reason);
void onMatch(int peerId, in byte[] serviceSpecificInfo,
int serviceSpecificInfoLength, in byte[] matchFilter, int matchFilterLength);
diff --git a/wifi/java/android/net/wifi/nan/SubscribeData.aidl b/wifi/java/android/net/wifi/nan/PublishConfig.aidl
index 662fdb83f74c..5f66d168a1da 100644
--- a/wifi/java/android/net/wifi/nan/SubscribeData.aidl
+++ b/wifi/java/android/net/wifi/nan/PublishConfig.aidl
@@ -16,4 +16,4 @@
package android.net.wifi.nan;
-parcelable SubscribeData;
+parcelable PublishConfig;
diff --git a/wifi/java/android/net/wifi/nan/PublishData.java b/wifi/java/android/net/wifi/nan/PublishConfig.java
index 80119eb0f4fd..d7cba8fcdfb3 100644
--- a/wifi/java/android/net/wifi/nan/PublishData.java
+++ b/wifi/java/android/net/wifi/nan/PublishConfig.java
@@ -16,19 +16,45 @@
package android.net.wifi.nan;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
/**
- * Defines the data for a NAN publish session. Built using
- * {@link PublishData.Builder}. Publish is done using
- * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
- * or {@link WifiNanPublishSession#publish(PublishData, PublishSettings)}.
+ * Defines the configuration of a NAN publish session. Built using
+ * {@link PublishConfig.Builder}. Publish is done using
+ * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} or
+ * {@link WifiNanPublishSession#updatePublish(PublishConfig)}.
+ *
* @hide PROPOSED_NAN_API
*/
-public class PublishData implements Parcelable {
+public class PublishConfig implements Parcelable {
+ @IntDef({
+ PUBLISH_TYPE_UNSOLICITED, PUBLISH_TYPE_SOLICITED })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PublishTypes {
+ }
+
+ /**
+ * Defines an unsolicited publish session - i.e. a publish session where
+ * publish packets are transmitted over-the-air. Configuration is done using
+ * {@link PublishConfig.Builder#setPublishType(int)}.
+ */
+ public static final int PUBLISH_TYPE_UNSOLICITED = 0;
+
+ /**
+ * Defines a solicited publish session - i.e. a publish session where
+ * publish packets are not transmitted over-the-air and the device listens
+ * and matches to transmitted subscribe packets. Configuration is done using
+ * {@link PublishConfig.Builder#setPublishType(int)}.
+ */
+ public static final int PUBLISH_TYPE_SOLICITED = 1;
+
/**
* @hide
*/
@@ -64,9 +90,30 @@ public class PublishData implements Parcelable {
*/
public final byte[] mRxFilter;
- private PublishData(String serviceName, byte[] serviceSpecificInfo,
+ /**
+ * @hide
+ */
+ public final int mPublishType;
+
+ /**
+ * @hide
+ */
+ public final int mPublishCount;
+
+ /**
+ * @hide
+ */
+ public final int mTtlSec;
+
+ /**
+ * @hide
+ */
+ public final boolean mEnableTerminateNotification;
+
+ private PublishConfig(String serviceName, byte[] serviceSpecificInfo,
int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter,
- int rxFilterLength) {
+ int rxFilterLength, int publishType, int publichCount, int ttlSec,
+ boolean enableTerminateNotification) {
mServiceName = serviceName;
mServiceSpecificInfoLength = serviceSpecificInfoLength;
mServiceSpecificInfo = serviceSpecificInfo;
@@ -74,17 +121,23 @@ public class PublishData implements Parcelable {
mTxFilter = txFilter;
mRxFilterLength = rxFilterLength;
mRxFilter = rxFilter;
+ mPublishType = publishType;
+ mPublishCount = publichCount;
+ mTtlSec = ttlSec;
+ mEnableTerminateNotification = enableTerminateNotification;
}
@Override
public String toString() {
- return "PublishData [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
+ return "PublishConfig [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
+ (new String(mServiceSpecificInfo, 0, mServiceSpecificInfoLength))
+ "', mTxFilter="
+ (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter, mTxFilterLength)).toString()
+ ", mRxFilter="
+ (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter, mRxFilterLength)).toString()
- + "']";
+ + ", mPublishType=" + mPublishType + ", mPublishCount=" + mPublishCount
+ + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
+ + mEnableTerminateNotification + "]";
}
@Override
@@ -92,7 +145,6 @@ public class PublishData implements Parcelable {
return 0;
}
-
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mServiceName);
@@ -108,16 +160,20 @@ public class PublishData implements Parcelable {
if (mRxFilterLength != 0) {
dest.writeByteArray(mRxFilter, 0, mRxFilterLength);
}
+ dest.writeInt(mPublishType);
+ dest.writeInt(mPublishCount);
+ dest.writeInt(mTtlSec);
+ dest.writeInt(mEnableTerminateNotification ? 1 : 0);
}
- public static final Creator<PublishData> CREATOR = new Creator<PublishData>() {
+ public static final Creator<PublishConfig> CREATOR = new Creator<PublishConfig>() {
@Override
- public PublishData[] newArray(int size) {
- return new PublishData[size];
+ public PublishConfig[] newArray(int size) {
+ return new PublishConfig[size];
}
@Override
- public PublishData createFromParcel(Parcel in) {
+ public PublishConfig createFromParcel(Parcel in) {
String serviceName = in.readString();
int ssiLength = in.readInt();
byte[] ssi = new byte[ssiLength];
@@ -134,9 +190,14 @@ public class PublishData implements Parcelable {
if (rxFilterLength != 0) {
in.readByteArray(rxFilter);
}
-
- return new PublishData(serviceName, ssi, ssiLength, txFilter, txFilterLength, rxFilter,
- rxFilterLength);
+ int publishType = in.readInt();
+ int publishCount = in.readInt();
+ int ttlSec = in.readInt();
+ boolean enableTerminateNotification = in.readInt() != 0;
+
+ return new PublishConfig(serviceName, ssi, ssiLength, txFilter, txFilterLength,
+ rxFilter, rxFilterLength, publishType, publishCount, ttlSec,
+ enableTerminateNotification);
}
};
@@ -146,11 +207,11 @@ public class PublishData implements Parcelable {
return true;
}
- if (!(o instanceof PublishData)) {
+ if (!(o instanceof PublishConfig)) {
return false;
}
- PublishData lhs = (PublishData) o;
+ PublishConfig lhs = (PublishConfig) o;
if (!mServiceName.equals(lhs.mServiceName)
|| mServiceSpecificInfoLength != lhs.mServiceSpecificInfoLength
@@ -189,7 +250,9 @@ public class PublishData implements Parcelable {
return false; // invalid != invalid
}
- return true;
+ return mPublishType == lhs.mPublishType && mPublishCount == lhs.mPublishCount
+ && mTtlSec == lhs.mTtlSec
+ && mEnableTerminateNotification == lhs.mEnableTerminateNotification;
}
@Override
@@ -203,12 +266,55 @@ public class PublishData implements Parcelable {
result = 31 * result + Arrays.hashCode(mTxFilter);
result = 31 * result + mRxFilterLength;
result = 31 * result + Arrays.hashCode(mRxFilter);
+ result = 31 * result + mPublishType;
+ result = 31 * result + mPublishCount;
+ result = 31 * result + mTtlSec;
+ result = 31 * result + (mEnableTerminateNotification ? 1 : 0);
return result;
}
/**
- * Builder used to build {@link PublishData} objects.
+ * Validates that the contents of the PublishConfig are valid. Otherwise
+ * throws an IllegalArgumentException.
+ *
+ * @hide
+ */
+ public void validate() throws IllegalArgumentException {
+ if (mServiceSpecificInfoLength != 0 && (mServiceSpecificInfo == null
+ || mServiceSpecificInfo.length < mServiceSpecificInfoLength)) {
+ throw new IllegalArgumentException("Non-matching combination of "
+ + "serviceSpecificInfo and serviceSpecificInfoLength");
+ }
+ if (mTxFilterLength != 0 && (mTxFilter == null || mTxFilter.length < mTxFilterLength)) {
+ throw new IllegalArgumentException(
+ "Non-matching combination of txFilter and txFilterLength");
+ }
+ if (mRxFilterLength != 0 && (mRxFilter == null || mRxFilter.length < mRxFilterLength)) {
+ throw new IllegalArgumentException(
+ "Non-matching combination of rxFilter and rxFilterLength");
+ }
+ if (mPublishType < PUBLISH_TYPE_UNSOLICITED || mPublishType > PUBLISH_TYPE_SOLICITED) {
+ throw new IllegalArgumentException("Invalid publishType - " + mPublishType);
+ }
+ if (mPublishCount < 0) {
+ throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
+ }
+ if (mTtlSec < 0) {
+ throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
+ }
+ if (mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED && mRxFilterLength != 0) {
+ throw new IllegalArgumentException("Invalid publish config: UNSOLICITED "
+ + "publishes (active) can't have an Rx filter");
+ }
+ if (mPublishType == PublishConfig.PUBLISH_TYPE_SOLICITED && mTxFilterLength != 0) {
+ throw new IllegalArgumentException("Invalid publish config: SOLICITED "
+ + "publishes (passive) can't have a Tx filter");
+ }
+ }
+
+ /**
+ * Builder used to build {@link PublishConfig} objects.
*/
public static final class Builder {
private String mServiceName;
@@ -218,6 +324,10 @@ public class PublishData implements Parcelable {
private byte[] mTxFilter = new byte[0];
private int mRxFilterLength;
private byte[] mRxFilter = new byte[0];
+ private int mPublishType = PUBLISH_TYPE_UNSOLICITED;
+ private int mPublishCount = 0;
+ private int mTtlSec = 0;
+ private boolean mEnableTerminateNotification = true;
/**
* Specify the service name of the publish session. The actual on-air
@@ -227,7 +337,7 @@ public class PublishData implements Parcelable {
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public Builder setServiceName(String serviceName) {
+ public Builder setServiceName(@NonNull String serviceName) {
mServiceName = serviceName;
return this;
}
@@ -260,7 +370,7 @@ public class PublishData implements Parcelable {
/**
* Specify service specific information for the publish session - same
- * as {@link PublishData.Builder#setServiceSpecificInfo(byte[], int)}
+ * as {@link PublishConfig.Builder#setServiceSpecificInfo(byte[], int)}
* but obtaining the data from a String.
*
* @param serviceSpecificInfoStr The service specific information string
@@ -269,7 +379,7 @@ public class PublishData implements Parcelable {
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public Builder setServiceSpecificInfo(String serviceSpecificInfoStr) {
+ public Builder setServiceSpecificInfo(@NonNull String serviceSpecificInfoStr) {
mServiceSpecificInfoLength = serviceSpecificInfoStr.length();
mServiceSpecificInfo = serviceSpecificInfoStr.getBytes();
return this;
@@ -277,8 +387,8 @@ public class PublishData implements Parcelable {
/**
* The transmit filter for an active publish session
- * {@link PublishSettings.Builder#setPublishType(int)} and
- * {@link PublishSettings#PUBLISH_TYPE_UNSOLICITED}. Included in
+ * {@link PublishConfig.Builder#setPublishType(int)} and
+ * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED}. Included in
* transmitted publish packets and used by receivers (subscribers) to
* determine whether they match - in addition to just relying on the
* service name.
@@ -305,8 +415,8 @@ public class PublishData implements Parcelable {
/**
* The transmit filter for a passive publish session
- * {@link PublishSettings.Builder#setPublishType(int)} and
- * {@link PublishSettings#PUBLISH_TYPE_SOLICITED}. Used by the publisher
+ * {@link PublishConfig.Builder#setPublishType(int)} and
+ * {@link PublishConfig#PUBLISH_TYPE_SOLICITED}. Used by the publisher
* to determine whether they match transmitted subscriber packets
* (active subscribers) - in addition to just relying on the service
* name.
@@ -332,12 +442,88 @@ public class PublishData implements Parcelable {
}
/**
- * Build {@link PublishData} given the current requests made on the
+ * Sets the type of the publish session: solicited (aka active - publish
+ * packets are transmitted over-the-air), or unsolicited (aka passive -
+ * no publish packets are transmitted, a match is made against an active
+ * subscribe session whose packets are transmitted over-the-air).
+ *
+ * @param publishType Publish session type: solicited (
+ * {@link PublishConfig#PUBLISH_TYPE_SOLICITED}) or
+ * unsolicited (
+ * {@link PublishConfig#PUBLISH_TYPE_UNSOLICITED}).
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setPublishType(@PublishTypes int publishType) {
+ if (publishType < PUBLISH_TYPE_UNSOLICITED || publishType > PUBLISH_TYPE_SOLICITED) {
+ throw new IllegalArgumentException("Invalid publishType - " + publishType);
+ }
+ mPublishType = publishType;
+ return this;
+ }
+
+ /**
+ * Sets the number of times a solicited (
+ * {@link PublishConfig.Builder#setPublishType(int)}) publish session
+ * will transmit a packet. When the count is reached an event will be
+ * generated for {@link WifiNanSessionCallback#onSessionTerminated(int)}
+ * with reason={@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
+ *
+ * @param publishCount Number of publish packets to transmit.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setPublishCount(int publishCount) {
+ if (publishCount < 0) {
+ throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
+ }
+ mPublishCount = publishCount;
+ return this;
+ }
+
+ /**
+ * Sets the time interval (in seconds) a solicited (
+ * {@link PublishConfig.Builder#setPublishCount(int)}) publish session
+ * will be alive - i.e. transmitting a packet. When the TTL is reached
+ * an event will be generated for
+ * {@link WifiNanSessionCallback#onSessionTerminated(int)} with reason=
+ * {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
+ *
+ * @param ttlSec Lifetime of a publish session in seconds.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setTtlSec(int ttlSec) {
+ if (ttlSec < 0) {
+ throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
+ }
+ mTtlSec = ttlSec;
+ return this;
+ }
+
+ /**
+ * Configure whether a publish terminate notification
+ * {@link WifiNanSessionCallback#onSessionTerminated(int)} is reported
+ * back to the callback.
+ *
+ * @param enable If true the terminate callback will be called when the
+ * publish is terminated. Otherwise it will not be called.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setEnableTerminateNotification(boolean enable) {
+ mEnableTerminateNotification = enable;
+ return this;
+ }
+
+ /**
+ * Build {@link PublishConfig} given the current requests made on the
* builder.
*/
- public PublishData build() {
- return new PublishData(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
- mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength);
+ public PublishConfig build() {
+ return new PublishConfig(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
+ mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength, mPublishType,
+ mPublishCount, mTtlSec, mEnableTerminateNotification);
}
}
}
diff --git a/wifi/java/android/net/wifi/nan/PublishSettings.aidl b/wifi/java/android/net/wifi/nan/PublishSettings.aidl
deleted file mode 100644
index ff692936bf06..000000000000
--- a/wifi/java/android/net/wifi/nan/PublishSettings.aidl
+++ /dev/null
@@ -1,19 +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.nan;
-
-parcelable PublishSettings;
diff --git a/wifi/java/android/net/wifi/nan/PublishSettings.java b/wifi/java/android/net/wifi/nan/PublishSettings.java
deleted file mode 100644
index bbc53408f2b5..000000000000
--- a/wifi/java/android/net/wifi/nan/PublishSettings.java
+++ /dev/null
@@ -1,204 +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.nan;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Defines the settings (configuration) for a NAN publish session. Built using
- * {@link PublishSettings.Builder}. Publish is done using
- * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
- * or {@link WifiNanPublishSession#publish(PublishData, PublishSettings)}.
- *
- * @hide PROPOSED_NAN_API
- */
-public class PublishSettings implements Parcelable {
-
- /**
- * Defines an unsolicited publish session - i.e. a publish session where
- * publish packets are transmitted over-the-air. Configuration is done using
- * {@link PublishSettings.Builder#setPublishType(int)}.
- */
- public static final int PUBLISH_TYPE_UNSOLICITED = 0;
-
- /**
- * Defines a solicited publish session - i.e. a publish session where
- * publish packets are not transmitted over-the-air and the device listens
- * and matches to transmitted subscribe packets. Configuration is done using
- * {@link PublishSettings.Builder#setPublishType(int)}.
- */
- public static final int PUBLISH_TYPE_SOLICITED = 1;
-
- /**
- * @hide
- */
- public final int mPublishType;
-
- /**
- * @hide
- */
- public final int mPublishCount;
-
- /**
- * @hide
- */
- public final int mTtlSec;
-
- private PublishSettings(int publishType, int publichCount, int ttlSec) {
- mPublishType = publishType;
- mPublishCount = publichCount;
- mTtlSec = ttlSec;
- }
-
- @Override
- public String toString() {
- return "PublishSettings [mPublishType=" + mPublishType + ", mPublishCount=" + mPublishCount
- + ", mTtlSec=" + mTtlSec + "]";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mPublishType);
- dest.writeInt(mPublishCount);
- dest.writeInt(mTtlSec);
- }
-
- public static final Creator<PublishSettings> CREATOR = new Creator<PublishSettings>() {
- @Override
- public PublishSettings[] newArray(int size) {
- return new PublishSettings[size];
- }
-
- @Override
- public PublishSettings createFromParcel(Parcel in) {
- int publishType = in.readInt();
- int publishCount = in.readInt();
- int ttlSec = in.readInt();
- return new PublishSettings(publishType, publishCount, ttlSec);
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof PublishSettings)) {
- return false;
- }
-
- PublishSettings lhs = (PublishSettings) o;
-
- return mPublishType == lhs.mPublishType && mPublishCount == lhs.mPublishCount
- && mTtlSec == lhs.mTtlSec;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
-
- result = 31 * result + mPublishType;
- result = 31 * result + mPublishCount;
- result = 31 * result + mTtlSec;
-
- return result;
- }
-
- /**
- * Builder used to build {@link PublishSettings} objects.
- */
- public static final class Builder {
- int mPublishType;
- int mPublishCount;
- int mTtlSec;
-
- /**
- * Sets the type of the publish session: solicited (aka active - publish
- * packets are transmitted over-the-air), or unsolicited (aka passive -
- * no publish packets are transmitted, a match is made against an active
- * subscribe session whose packets are transmitted over-the-air).
- *
- * @param publishType Publish session type: solicited (
- * {@link PublishSettings#PUBLISH_TYPE_SOLICITED}) or
- * unsolicited (
- * {@link PublishSettings#PUBLISH_TYPE_UNSOLICITED}).
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setPublishType(int publishType) {
- if (publishType < PUBLISH_TYPE_UNSOLICITED || publishType > PUBLISH_TYPE_SOLICITED) {
- throw new IllegalArgumentException("Invalid publishType - " + publishType);
- }
- mPublishType = publishType;
- return this;
- }
-
- /**
- * Sets the number of times a solicited (
- * {@link PublishSettings.Builder#setPublishType(int)}) publish session
- * will transmit a packet. When the count is reached an event will be
- * generated for {@link WifiNanSessionListener#onPublishTerminated(int)}
- * with reason={@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
- *
- * @param publishCount Number of publish packets to transmit.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setPublishCount(int publishCount) {
- if (publishCount < 0) {
- throw new IllegalArgumentException("Invalid publishCount - must be non-negative");
- }
- mPublishCount = publishCount;
- return this;
- }
-
- /**
- * Sets the time interval (in seconds) a solicited (
- * {@link PublishSettings.Builder#setPublishCount(int)}) publish session
- * will be alive - i.e. transmitting a packet. When the TTL is reached
- * an event will be generated for
- * {@link WifiNanSessionListener#onPublishTerminated(int)} with reason=
- * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
- *
- * @param ttlSec Lifetime of a publish session in seconds.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setTtlSec(int ttlSec) {
- if (ttlSec < 0) {
- throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
- }
- mTtlSec = ttlSec;
- return this;
- }
-
- /**
- * Build {@link PublishSettings} given the current requests made on the
- * builder.
- */
- public PublishSettings build() {
- return new PublishSettings(mPublishType, mPublishCount, mTtlSec);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/nan/PublishData.aidl b/wifi/java/android/net/wifi/nan/SubscribeConfig.aidl
index 15e4ddfd1c0b..92344a43daf2 100644
--- a/wifi/java/android/net/wifi/nan/PublishData.aidl
+++ b/wifi/java/android/net/wifi/nan/SubscribeConfig.aidl
@@ -16,4 +16,4 @@
package android.net.wifi.nan;
-parcelable PublishData;
+parcelable SubscribeConfig;
diff --git a/wifi/java/android/net/wifi/nan/SubscribeConfig.java b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
new file mode 100644
index 000000000000..847c8d002abb
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/SubscribeConfig.java
@@ -0,0 +1,584 @@
+/*
+ * 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.nan;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+
+/**
+ * Defines the configuration of a NAN subscribe session. Built using
+ * {@link SubscribeConfig.Builder}. Subscribe is done using
+ * {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} or
+ * {@link WifiNanSubscribeSession#updateSubscribe(SubscribeConfig)}.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class SubscribeConfig implements Parcelable {
+ @IntDef({
+ SUBSCRIBE_TYPE_PASSIVE, SUBSCRIBE_TYPE_ACTIVE })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SubscribeTypes {
+ }
+
+ /**
+ * Defines a passive subscribe session - i.e. a subscribe session where
+ * subscribe packets are not transmitted over-the-air and the device listens
+ * and matches to transmitted publish packets. Configuration is done using
+ * {@link SubscribeConfig.Builder#setSubscribeType(int)}.
+ */
+ public static final int SUBSCRIBE_TYPE_PASSIVE = 0;
+
+ /**
+ * Defines an active subscribe session - i.e. a subscribe session where
+ * subscribe packets are transmitted over-the-air. Configuration is done
+ * using {@link SubscribeConfig.Builder#setSubscribeType(int)}.
+ */
+ public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
+
+ @IntDef({
+ MATCH_STYLE_FIRST_ONLY, MATCH_STYLE_ALL })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MatchStyles {
+ }
+
+ /**
+ * Specifies that only the first match of a set of identical matches (same
+ * publish) will be reported to the subscriber.
+ */
+ public static final int MATCH_STYLE_FIRST_ONLY = 0;
+
+ /**
+ * Specifies that all matches of a set of identical matches (same publish)
+ * will be reported to the subscriber.
+ */
+ public static final int MATCH_STYLE_ALL = 1;
+
+ /**
+ * @hide
+ */
+ public final String mServiceName;
+
+ /**
+ * @hide
+ */
+ public final int mServiceSpecificInfoLength;
+
+ /**
+ * @hide
+ */
+ public final byte[] mServiceSpecificInfo;
+
+ /**
+ * @hide
+ */
+ public final int mTxFilterLength;
+
+ /**
+ * @hide
+ */
+ public final byte[] mTxFilter;
+
+ /**
+ * @hide
+ */
+ public final int mRxFilterLength;
+
+ /**
+ * @hide
+ */
+ public final byte[] mRxFilter;
+
+ /**
+ * @hide
+ */
+ public final int mSubscribeType;
+
+ /**
+ * @hide
+ */
+ public final int mSubscribeCount;
+
+ /**
+ * @hide
+ */
+ public final int mTtlSec;
+
+ /**
+ * @hide
+ */
+ public final int mMatchStyle;
+
+ /**
+ * @hide
+ */
+ public final boolean mEnableTerminateNotification;
+
+ private SubscribeConfig(String serviceName, byte[] serviceSpecificInfo,
+ int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter,
+ int rxFilterLength, int subscribeType, int publichCount, int ttlSec, int matchStyle,
+ boolean enableTerminateNotification) {
+ mServiceName = serviceName;
+ mServiceSpecificInfoLength = serviceSpecificInfoLength;
+ mServiceSpecificInfo = serviceSpecificInfo;
+ mTxFilterLength = txFilterLength;
+ mTxFilter = txFilter;
+ mRxFilterLength = rxFilterLength;
+ mRxFilter = rxFilter;
+ mSubscribeType = subscribeType;
+ mSubscribeCount = publichCount;
+ mTtlSec = ttlSec;
+ mMatchStyle = matchStyle;
+ mEnableTerminateNotification = enableTerminateNotification;
+ }
+
+ @Override
+ public String toString() {
+ return "SubscribeConfig [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
+ + (new String(mServiceSpecificInfo, 0, mServiceSpecificInfoLength))
+ + "', mTxFilter="
+ + (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter, mTxFilterLength)).toString()
+ + ", mRxFilter="
+ + (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter, mRxFilterLength)).toString()
+ + ", mSubscribeType=" + mSubscribeType + ", mSubscribeCount=" + mSubscribeCount
+ + ", mTtlSec=" + mTtlSec + ", mMatchType=" + mMatchStyle
+ + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mServiceName);
+ dest.writeInt(mServiceSpecificInfoLength);
+ if (mServiceSpecificInfoLength != 0) {
+ dest.writeByteArray(mServiceSpecificInfo, 0, mServiceSpecificInfoLength);
+ }
+ dest.writeInt(mTxFilterLength);
+ if (mTxFilterLength != 0) {
+ dest.writeByteArray(mTxFilter, 0, mTxFilterLength);
+ }
+ dest.writeInt(mRxFilterLength);
+ if (mRxFilterLength != 0) {
+ dest.writeByteArray(mRxFilter, 0, mRxFilterLength);
+ }
+ dest.writeInt(mSubscribeType);
+ dest.writeInt(mSubscribeCount);
+ dest.writeInt(mTtlSec);
+ dest.writeInt(mMatchStyle);
+ dest.writeInt(mEnableTerminateNotification ? 1 : 0);
+ }
+
+ public static final Creator<SubscribeConfig> CREATOR = new Creator<SubscribeConfig>() {
+ @Override
+ public SubscribeConfig[] newArray(int size) {
+ return new SubscribeConfig[size];
+ }
+
+ @Override
+ public SubscribeConfig createFromParcel(Parcel in) {
+ String serviceName = in.readString();
+ int ssiLength = in.readInt();
+ byte[] ssi = new byte[ssiLength];
+ if (ssiLength != 0) {
+ in.readByteArray(ssi);
+ }
+ int txFilterLength = in.readInt();
+ byte[] txFilter = new byte[txFilterLength];
+ if (txFilterLength != 0) {
+ in.readByteArray(txFilter);
+ }
+ int rxFilterLength = in.readInt();
+ byte[] rxFilter = new byte[rxFilterLength];
+ if (rxFilterLength != 0) {
+ in.readByteArray(rxFilter);
+ }
+ int subscribeType = in.readInt();
+ int subscribeCount = in.readInt();
+ int ttlSec = in.readInt();
+ int matchStyle = in.readInt();
+ boolean enableTerminateNotification = in.readInt() != 0;
+
+ return new SubscribeConfig(serviceName, ssi, ssiLength, txFilter, txFilterLength,
+ rxFilter, rxFilterLength, subscribeType, subscribeCount, ttlSec, matchStyle,
+ enableTerminateNotification);
+ }
+ };
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof SubscribeConfig)) {
+ return false;
+ }
+
+ SubscribeConfig lhs = (SubscribeConfig) o;
+
+ if (!mServiceName.equals(lhs.mServiceName)
+ || mServiceSpecificInfoLength != lhs.mServiceSpecificInfoLength
+ || mTxFilterLength != lhs.mTxFilterLength
+ || mRxFilterLength != lhs.mRxFilterLength) {
+ return false;
+ }
+
+ if (mServiceSpecificInfo != null && lhs.mServiceSpecificInfo != null) {
+ for (int i = 0; i < mServiceSpecificInfoLength; ++i) {
+ if (mServiceSpecificInfo[i] != lhs.mServiceSpecificInfo[i]) {
+ return false;
+ }
+ }
+ } else if (mServiceSpecificInfoLength != 0) {
+ return false; // invalid != invalid
+ }
+
+ if (mTxFilter != null && lhs.mTxFilter != null) {
+ for (int i = 0; i < mTxFilterLength; ++i) {
+ if (mTxFilter[i] != lhs.mTxFilter[i]) {
+ return false;
+ }
+ }
+ } else if (mTxFilterLength != 0) {
+ return false; // invalid != invalid
+ }
+
+ if (mRxFilter != null && lhs.mRxFilter != null) {
+ for (int i = 0; i < mRxFilterLength; ++i) {
+ if (mRxFilter[i] != lhs.mRxFilter[i]) {
+ return false;
+ }
+ }
+ } else if (mRxFilterLength != 0) {
+ return false; // invalid != invalid
+ }
+
+ return mSubscribeType == lhs.mSubscribeType && mSubscribeCount == lhs.mSubscribeCount
+ && mTtlSec == lhs.mTtlSec && mMatchStyle == lhs.mMatchStyle
+ && mEnableTerminateNotification == lhs.mEnableTerminateNotification;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+
+ result = 31 * result + mServiceName.hashCode();
+ result = 31 * result + mServiceSpecificInfoLength;
+ result = 31 * result + Arrays.hashCode(mServiceSpecificInfo);
+ result = 31 * result + mTxFilterLength;
+ result = 31 * result + Arrays.hashCode(mTxFilter);
+ result = 31 * result + mRxFilterLength;
+ result = 31 * result + Arrays.hashCode(mRxFilter);
+ result = 31 * result + mSubscribeType;
+ result = 31 * result + mSubscribeCount;
+ result = 31 * result + mTtlSec;
+ result = 31 * result + mMatchStyle;
+ result = 31 * result + (mEnableTerminateNotification ? 1 : 0);
+
+ return result;
+ }
+
+ /**
+ * Validates that the contents of the SubscribeConfig are valid. Otherwise
+ * throws an IllegalArgumentException.
+ *
+ * @hide
+ */
+ public void validate() throws IllegalArgumentException {
+ if (mServiceSpecificInfoLength != 0 && (mServiceSpecificInfo == null
+ || mServiceSpecificInfo.length < mServiceSpecificInfoLength)) {
+ throw new IllegalArgumentException("Non-matching combination of "
+ + "serviceSpecificInfo and serviceSpecificInfoLength");
+ }
+ if (mTxFilterLength != 0 && (mTxFilter == null || mTxFilter.length < mTxFilterLength)) {
+ throw new IllegalArgumentException(
+ "Non-matching combination of txFilter and txFilterLength");
+ }
+ if (mRxFilterLength != 0 && (mRxFilter == null || mRxFilter.length < mRxFilterLength)) {
+ throw new IllegalArgumentException(
+ "Non-matching combination of rxFilter and rxFilterLength");
+ }
+ if (mSubscribeType < SUBSCRIBE_TYPE_PASSIVE || mSubscribeType > SUBSCRIBE_TYPE_ACTIVE) {
+ throw new IllegalArgumentException("Invalid subscribeType - " + mSubscribeType);
+ }
+ if (mSubscribeCount < 0) {
+ throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
+ }
+ if (mTtlSec < 0) {
+ throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
+ }
+ if (mMatchStyle != MATCH_STYLE_FIRST_ONLY && mMatchStyle != MATCH_STYLE_ALL) {
+ throw new IllegalArgumentException(
+ "Invalid matchType - must be MATCH_FIRST_ONLY or MATCH_ALL");
+ }
+ if (mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE && mRxFilterLength != 0) {
+ throw new IllegalArgumentException(
+ "Invalid subscribe config: ACTIVE subscribes can't have an Rx filter");
+ }
+ if (mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE && mTxFilterLength != 0) {
+ throw new IllegalArgumentException(
+ "Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
+ }
+ }
+
+ /**
+ * Builder used to build {@link SubscribeConfig} objects.
+ */
+ public static final class Builder {
+ private String mServiceName;
+ private int mServiceSpecificInfoLength;
+ private byte[] mServiceSpecificInfo = new byte[0];
+ private int mTxFilterLength;
+ private byte[] mTxFilter = new byte[0];
+ private int mRxFilterLength;
+ private byte[] mRxFilter = new byte[0];
+ private int mSubscribeType = SUBSCRIBE_TYPE_PASSIVE;
+ private int mSubscribeCount = 0;
+ private int mTtlSec = 0;
+ private int mMatchStyle = MATCH_STYLE_ALL;
+ private boolean mEnableTerminateNotification = true;
+
+ /**
+ * Specify the service name of the subscribe session. The actual on-air
+ * value is a 6 byte hashed representation of this string.
+ *
+ * @param serviceName The service name for the subscribe session.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setServiceName(@NonNull String serviceName) {
+ mServiceName = serviceName;
+ return this;
+ }
+
+ /**
+ * Specify service specific information for the subscribe session. This
+ * is a free-form byte array available to the application to send
+ * additional information as part of the discovery operation - i.e. it
+ * will not be used to determine whether a publish/subscribe match
+ * occurs.
+ *
+ * @param serviceSpecificInfo A byte-array for the service-specific
+ * information field.
+ * @param serviceSpecificInfoLength The length of the byte-array to be
+ * used.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setServiceSpecificInfo(byte[] serviceSpecificInfo,
+ int serviceSpecificInfoLength) {
+ if (serviceSpecificInfoLength != 0 && (serviceSpecificInfo == null
+ || serviceSpecificInfo.length < serviceSpecificInfoLength)) {
+ throw new IllegalArgumentException("Non-matching combination of "
+ + "serviceSpecificInfo and serviceSpecificInfoLength");
+ }
+ mServiceSpecificInfoLength = serviceSpecificInfoLength;
+ mServiceSpecificInfo = serviceSpecificInfo;
+ return this;
+ }
+
+ /**
+ * Specify service specific information for the subscribe session - same
+ * as
+ * {@link SubscribeConfig.Builder#setServiceSpecificInfo(byte[], int)}
+ * but obtaining the data from a String.
+ *
+ * @param serviceSpecificInfoStr The service specific information string
+ * to be included (as a byte array) in the subscribe
+ * information.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setServiceSpecificInfo(@NonNull String serviceSpecificInfoStr) {
+ mServiceSpecificInfoLength = serviceSpecificInfoStr.length();
+ mServiceSpecificInfo = serviceSpecificInfoStr.getBytes();
+ return this;
+ }
+
+ /**
+ * The transmit filter for an active subscribe session
+ * {@link SubscribeConfig.Builder#setSubscribeType(int)} and
+ * {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE}. Included in
+ * transmitted subscribe packets and used by receivers (passive
+ * publishers) to determine whether they match - in addition to just
+ * relying on the service name.
+ * <p>
+ * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+ * is available to form and parse.
+ *
+ * @param txFilter The byte-array containing the LV formatted transmit
+ * filter.
+ * @param txFilterLength The number of bytes in the transmit filter
+ * argument.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setTxFilter(byte[] txFilter, int txFilterLength) {
+ if (txFilterLength != 0 && (txFilter == null || txFilter.length < txFilterLength)) {
+ throw new IllegalArgumentException(
+ "Non-matching combination of txFilter and txFilterLength");
+ }
+ mTxFilter = txFilter;
+ mTxFilterLength = txFilterLength;
+ return this;
+ }
+
+ /**
+ * The transmit filter for a passive subsribe session
+ * {@link SubscribeConfig.Builder#setSubscribeType(int)} and
+ * {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE}. Used by the
+ * subscriber to determine whether they match transmitted publish
+ * packets - in addition to just relying on the service name.
+ * <p>
+ * Format is an LV byte array - the {@link TlvBufferUtils} utility class
+ * is available to form and parse.
+ *
+ * @param rxFilter The byte-array containing the LV formatted receive
+ * filter.
+ * @param rxFilterLength The number of bytes in the receive filter
+ * argument.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setRxFilter(byte[] rxFilter, int rxFilterLength) {
+ if (rxFilterLength != 0 && (rxFilter == null || rxFilter.length < rxFilterLength)) {
+ throw new IllegalArgumentException(
+ "Non-matching combination of rxFilter and rxFilterLength");
+ }
+ mRxFilter = rxFilter;
+ mRxFilterLength = rxFilterLength;
+ return this;
+ }
+
+ /**
+ * Sets the type of the subscribe session: active (subscribe packets are
+ * transmitted over-the-air), or passive (no subscribe packets are
+ * transmitted, a match is made against a solicited/active publish
+ * session whose packets are transmitted over-the-air).
+ *
+ * @param subscribeType Subscribe session type: active (
+ * {@link SubscribeConfig#SUBSCRIBE_TYPE_ACTIVE}) or passive
+ * ( {@link SubscribeConfig#SUBSCRIBE_TYPE_PASSIVE} ).
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setSubscribeType(@SubscribeTypes int subscribeType) {
+ if (subscribeType < SUBSCRIBE_TYPE_PASSIVE || subscribeType > SUBSCRIBE_TYPE_ACTIVE) {
+ throw new IllegalArgumentException("Invalid subscribeType - " + subscribeType);
+ }
+ mSubscribeType = subscribeType;
+ return this;
+ }
+
+ /**
+ * Sets the number of times an active (
+ * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
+ * session will transmit a packet. When the count is reached an event
+ * will be generated for
+ * {@link WifiNanSessionCallback#onSessionTerminated(int)} with reason=
+ * {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
+ *
+ * @param subscribeCount Number of subscribe packets to transmit.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setSubscribeCount(int subscribeCount) {
+ if (subscribeCount < 0) {
+ throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
+ }
+ mSubscribeCount = subscribeCount;
+ return this;
+ }
+
+ /**
+ * Sets the time interval (in seconds) an active (
+ * {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
+ * session will be alive - i.e. transmitting a packet. When the TTL is
+ * reached an event will be generated for
+ * {@link WifiNanSessionCallback#onSessionTerminated(int)} with reason=
+ * {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
+ *
+ * @param ttlSec Lifetime of a subscribe session in seconds.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setTtlSec(int ttlSec) {
+ if (ttlSec < 0) {
+ throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
+ }
+ mTtlSec = ttlSec;
+ return this;
+ }
+
+ /**
+ * Sets the match style of the subscription - how are matches from a
+ * single match session (corresponding to the same publish action on the
+ * peer) reported to the host (using the
+ * {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)}
+ * ). The options are: only report the first match and ignore the rest
+ * {@link SubscribeConfig#MATCH_STYLE_FIRST_ONLY} or report every single
+ * match {@link SubscribeConfig#MATCH_STYLE_ALL}.
+ *
+ * @param matchStyle The reporting style for the discovery match.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setMatchStyle(@MatchStyles int matchStyle) {
+ if (matchStyle != MATCH_STYLE_FIRST_ONLY && matchStyle != MATCH_STYLE_ALL) {
+ throw new IllegalArgumentException(
+ "Invalid matchType - must be MATCH_FIRST_ONLY or MATCH_ALL");
+ }
+ mMatchStyle = matchStyle;
+ return this;
+ }
+
+ /**
+ * Configure whether a subscribe terminate notification
+ * {@link WifiNanSessionCallback#onSessionTerminated(int)} is reported
+ * back to the callback.
+ *
+ * @param enable If true the terminate callback will be called when the
+ * subscribe is terminated. Otherwise it will not be called.
+ * @return The builder to facilitate chaining
+ * {@code builder.setXXX(..).setXXX(..)}.
+ */
+ public Builder setEnableTerminateNotification(boolean enable) {
+ mEnableTerminateNotification = enable;
+ return this;
+ }
+
+ /**
+ * Build {@link SubscribeConfig} given the current requests made on the
+ * builder.
+ */
+ public SubscribeConfig build() {
+ return new SubscribeConfig(mServiceName, mServiceSpecificInfo,
+ mServiceSpecificInfoLength, mTxFilter, mTxFilterLength, mRxFilter,
+ mRxFilterLength, mSubscribeType, mSubscribeCount, mTtlSec, mMatchStyle,
+ mEnableTerminateNotification);
+ }
+ }
+}
diff --git a/wifi/java/android/net/wifi/nan/SubscribeData.java b/wifi/java/android/net/wifi/nan/SubscribeData.java
deleted file mode 100644
index cd6e91882834..000000000000
--- a/wifi/java/android/net/wifi/nan/SubscribeData.java
+++ /dev/null
@@ -1,329 +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.nan;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/**
- * Defines the data for a NAN subscribe session. Built using
- * {@link SubscribeData.Builder}. Subscribe is done using
- * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
- * or
- * {@link WifiNanSubscribeSession#subscribe(SubscribeData, SubscribeSettings)}.
- * @hide PROPOSED_NAN_API
- */
-public class SubscribeData implements Parcelable {
- /**
- * @hide
- */
- public final String mServiceName;
-
- /**
- * @hide
- */
- public final int mServiceSpecificInfoLength;
-
- /**
- * @hide
- */
- public final byte[] mServiceSpecificInfo;
-
- /**
- * @hide
- */
- public final int mTxFilterLength;
-
- /**
- * @hide
- */
- public final byte[] mTxFilter;
-
- /**
- * @hide
- */
- public final int mRxFilterLength;
-
- /**
- * @hide
- */
- public final byte[] mRxFilter;
-
- private SubscribeData(String serviceName, byte[] serviceSpecificInfo,
- int serviceSpecificInfoLength, byte[] txFilter, int txFilterLength, byte[] rxFilter,
- int rxFilterLength) {
- mServiceName = serviceName;
- mServiceSpecificInfoLength = serviceSpecificInfoLength;
- mServiceSpecificInfo = serviceSpecificInfo;
- mTxFilterLength = txFilterLength;
- mTxFilter = txFilter;
- mRxFilterLength = rxFilterLength;
- mRxFilter = rxFilter;
- }
-
- @Override
- public String toString() {
- return "SubscribeData [mServiceName='" + mServiceName + "', mServiceSpecificInfo='"
- + (new String(mServiceSpecificInfo, 0, mServiceSpecificInfoLength))
- + "', mTxFilter="
- + (new TlvBufferUtils.TlvIterable(0, 1, mTxFilter, mTxFilterLength)).toString()
- + ", mRxFilter="
- + (new TlvBufferUtils.TlvIterable(0, 1, mRxFilter, mRxFilterLength)).toString()
- + "']";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mServiceName);
- dest.writeInt(mServiceSpecificInfoLength);
- if (mServiceSpecificInfoLength != 0) {
- dest.writeByteArray(mServiceSpecificInfo, 0, mServiceSpecificInfoLength);
- }
- dest.writeInt(mTxFilterLength);
- if (mTxFilterLength != 0) {
- dest.writeByteArray(mTxFilter, 0, mTxFilterLength);
- }
- dest.writeInt(mRxFilterLength);
- if (mRxFilterLength != 0) {
- dest.writeByteArray(mRxFilter, 0, mRxFilterLength);
- }
- }
-
- public static final Creator<SubscribeData> CREATOR = new Creator<SubscribeData>() {
- @Override
- public SubscribeData[] newArray(int size) {
- return new SubscribeData[size];
- }
-
- @Override
- public SubscribeData createFromParcel(Parcel in) {
- String serviceName = in.readString();
- int ssiLength = in.readInt();
- byte[] ssi = new byte[ssiLength];
- if (ssiLength != 0) {
- in.readByteArray(ssi);
- }
- int txFilterLength = in.readInt();
- byte[] txFilter = new byte[txFilterLength];
- if (txFilterLength != 0) {
- in.readByteArray(txFilter);
- }
- int rxFilterLength = in.readInt();
- byte[] rxFilter = new byte[rxFilterLength];
- if (rxFilterLength != 0) {
- in.readByteArray(rxFilter);
- }
-
- return new SubscribeData(serviceName, ssi, ssiLength, txFilter, txFilterLength,
- rxFilter, rxFilterLength);
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof SubscribeData)) {
- return false;
- }
-
- SubscribeData lhs = (SubscribeData) o;
-
- if (!mServiceName.equals(lhs.mServiceName)
- || mServiceSpecificInfoLength != lhs.mServiceSpecificInfoLength
- || mTxFilterLength != lhs.mTxFilterLength
- || mRxFilterLength != lhs.mRxFilterLength) {
- return false;
- }
-
- if (mServiceSpecificInfo != null && lhs.mServiceSpecificInfo != null) {
- for (int i = 0; i < mServiceSpecificInfoLength; ++i) {
- if (mServiceSpecificInfo[i] != lhs.mServiceSpecificInfo[i]) {
- return false;
- }
- }
- } else if (mServiceSpecificInfoLength != 0) {
- return false; // invalid != invalid
- }
-
- if (mTxFilter != null && lhs.mTxFilter != null) {
- for (int i = 0; i < mTxFilterLength; ++i) {
- if (mTxFilter[i] != lhs.mTxFilter[i]) {
- return false;
- }
- }
- } else if (mTxFilterLength != 0) {
- return false; // invalid != invalid
- }
-
- if (mRxFilter != null && lhs.mRxFilter != null) {
- for (int i = 0; i < mRxFilterLength; ++i) {
- if (mRxFilter[i] != lhs.mRxFilter[i]) {
- return false;
- }
- }
- } else if (mRxFilterLength != 0) {
- return false; // invalid != invalid
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
-
- result = 31 * result + mServiceName.hashCode();
- result = 31 * result + mServiceSpecificInfoLength;
- result = 31 * result + Arrays.hashCode(mServiceSpecificInfo);
- result = 31 * result + mTxFilterLength;
- result = 31 * result + Arrays.hashCode(mTxFilter);
- result = 31 * result + mRxFilterLength;
- result = 31 * result + Arrays.hashCode(mRxFilter);
-
- return result;
- }
-
- /**
- * Builder used to build {@link SubscribeData} objects.
- */
- public static final class Builder {
- private String mServiceName;
- private int mServiceSpecificInfoLength;
- private byte[] mServiceSpecificInfo = new byte[0];
- private int mTxFilterLength;
- private byte[] mTxFilter = new byte[0];
- private int mRxFilterLength;
- private byte[] mRxFilter = new byte[0];
-
- /**
- * Specify the service name of the subscribe session. The actual on-air
- * value is a 6 byte hashed representation of this string.
- *
- * @param serviceName The service name for the subscribe session.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setServiceName(String serviceName) {
- mServiceName = serviceName;
- return this;
- }
-
- /**
- * Specify service specific information for the subscribe session. This
- * is a free-form byte array available to the application to send
- * additional information as part of the discovery operation - i.e. it
- * will not be used to determine whether a publish/subscribe match
- * occurs.
- *
- * @param serviceSpecificInfo A byte-array for the service-specific
- * information field.
- * @param serviceSpecificInfoLength The length of the byte-array to be
- * used.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setServiceSpecificInfo(byte[] serviceSpecificInfo,
- int serviceSpecificInfoLength) {
- mServiceSpecificInfoLength = serviceSpecificInfoLength;
- mServiceSpecificInfo = serviceSpecificInfo;
- return this;
- }
-
- /**
- * Specify service specific information for the subscribe session - same
- * as {@link SubscribeData.Builder#setServiceSpecificInfo(byte[], int)}
- * but obtaining the data from a String.
- *
- * @param serviceSpecificInfoStr The service specific information string
- * to be included (as a byte array) in the subscribe
- * information.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setServiceSpecificInfo(String serviceSpecificInfoStr) {
- mServiceSpecificInfoLength = serviceSpecificInfoStr.length();
- mServiceSpecificInfo = serviceSpecificInfoStr.getBytes();
- return this;
- }
-
- /**
- * The transmit filter for an active subscribe session
- * {@link SubscribeSettings.Builder#setSubscribeType(int)} and
- * {@link SubscribeSettings#SUBSCRIBE_TYPE_ACTIVE}. Included in
- * transmitted subscribe packets and used by receivers (passive
- * publishers) to determine whether they match - in addition to just
- * relying on the service name.
- * <p>
- * Format is an LV byte array - the {@link TlvBufferUtils} utility class
- * is available to form and parse.
- *
- * @param txFilter The byte-array containing the LV formatted transmit
- * filter.
- * @param txFilterLength The number of bytes in the transmit filter
- * argument.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setTxFilter(byte[] txFilter, int txFilterLength) {
- mTxFilter = txFilter;
- mTxFilterLength = txFilterLength;
- return this;
- }
-
- /**
- * The transmit filter for a passive subsribe session
- * {@link SubscribeSettings.Builder#setSubscribeType(int)} and
- * {@link SubscribeSettings#SUBSCRIBE_TYPE_PASSIVE}. Used by the
- * subscriber to determine whether they match transmitted publish
- * packets - in addition to just relying on the service name.
- * <p>
- * Format is an LV byte array - the {@link TlvBufferUtils} utility class
- * is available to form and parse.
- *
- * @param rxFilter The byte-array containing the LV formatted receive
- * filter.
- * @param rxFilterLength The number of bytes in the receive filter
- * argument.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setRxFilter(byte[] rxFilter, int rxFilterLength) {
- mRxFilter = rxFilter;
- mRxFilterLength = rxFilterLength;
- return this;
- }
-
- /**
- * Build {@link SubscribeData} given the current requests made on the
- * builder.
- */
- public SubscribeData build() {
- return new SubscribeData(mServiceName, mServiceSpecificInfo, mServiceSpecificInfoLength,
- mTxFilter, mTxFilterLength, mRxFilter, mRxFilterLength);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl b/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl
deleted file mode 100644
index 44849bc04a57..000000000000
--- a/wifi/java/android/net/wifi/nan/SubscribeSettings.aidl
+++ /dev/null
@@ -1,19 +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.nan;
-
-parcelable SubscribeSettings;
diff --git a/wifi/java/android/net/wifi/nan/SubscribeSettings.java b/wifi/java/android/net/wifi/nan/SubscribeSettings.java
deleted file mode 100644
index 5c4f8fb385fa..000000000000
--- a/wifi/java/android/net/wifi/nan/SubscribeSettings.java
+++ /dev/null
@@ -1,205 +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.nan;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Defines the settings (configuration) for a NAN subscribe session. Built using
- * {@link SubscribeSettings.Builder}. Subscribe is done using
- * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
- * or {@link WifiNanSubscribeSession#subscribe(SubscribeData, SubscribeSettings)}.
- *
- * @hide PROPOSED_NAN_API
- */
-public class SubscribeSettings implements Parcelable {
-
- /**
- * Defines a passive subscribe session - i.e. a subscribe session where
- * subscribe packets are not transmitted over-the-air and the device listens
- * and matches to transmitted publish packets. Configuration is done using
- * {@link SubscribeSettings.Builder#setSubscribeType(int)}.
- */
- public static final int SUBSCRIBE_TYPE_PASSIVE = 0;
-
- /**
- * Defines an active subscribe session - i.e. a subscribe session where
- * subscribe packets are transmitted over-the-air. Configuration is done
- * using {@link SubscribeSettings.Builder#setSubscribeType(int)}.
- */
- public static final int SUBSCRIBE_TYPE_ACTIVE = 1;
-
- /**
- * @hide
- */
- public final int mSubscribeType;
-
- /**
- * @hide
- */
- public final int mSubscribeCount;
-
- /**
- * @hide
- */
- public final int mTtlSec;
-
- private SubscribeSettings(int subscribeType, int publichCount, int ttlSec) {
- mSubscribeType = subscribeType;
- mSubscribeCount = publichCount;
- mTtlSec = ttlSec;
- }
-
- @Override
- public String toString() {
- return "SubscribeSettings [mSubscribeType=" + mSubscribeType + ", mSubscribeCount="
- + mSubscribeCount + ", mTtlSec=" + mTtlSec + "]";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mSubscribeType);
- dest.writeInt(mSubscribeCount);
- dest.writeInt(mTtlSec);
- }
-
- public static final Creator<SubscribeSettings> CREATOR = new Creator<SubscribeSettings>() {
- @Override
- public SubscribeSettings[] newArray(int size) {
- return new SubscribeSettings[size];
- }
-
- @Override
- public SubscribeSettings createFromParcel(Parcel in) {
- int subscribeType = in.readInt();
- int subscribeCount = in.readInt();
- int ttlSec = in.readInt();
- return new SubscribeSettings(subscribeType, subscribeCount, ttlSec);
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (!(o instanceof SubscribeSettings)) {
- return false;
- }
-
- SubscribeSettings lhs = (SubscribeSettings) o;
-
- return mSubscribeType == lhs.mSubscribeType && mSubscribeCount == lhs.mSubscribeCount
- && mTtlSec == lhs.mTtlSec;
- }
-
- @Override
- public int hashCode() {
- int result = 17;
-
- result = 31 * result + mSubscribeType;
- result = 31 * result + mSubscribeCount;
- result = 31 * result + mTtlSec;
-
- return result;
- }
-
- /**
- * Builder used to build {@link SubscribeSettings} objects.
- */
- public static final class Builder {
- int mSubscribeType;
- int mSubscribeCount;
- int mTtlSec;
-
- /**
- * Sets the type of the subscribe session: active (subscribe packets are
- * transmitted over-the-air), or passive (no subscribe packets are
- * transmitted, a match is made against a solicited/active publish
- * session whose packets are transmitted over-the-air).
- *
- * @param subscribeType Subscribe session type: active (
- * {@link SubscribeSettings#SUBSCRIBE_TYPE_ACTIVE}) or
- * passive ( {@link SubscribeSettings#SUBSCRIBE_TYPE_PASSIVE}
- * ).
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setSubscribeType(int subscribeType) {
- if (subscribeType < SUBSCRIBE_TYPE_PASSIVE || subscribeType > SUBSCRIBE_TYPE_ACTIVE) {
- throw new IllegalArgumentException("Invalid subscribeType - " + subscribeType);
- }
- mSubscribeType = subscribeType;
- return this;
- }
-
- /**
- * Sets the number of times an active (
- * {@link SubscribeSettings.Builder#setSubscribeType(int)}) subscribe
- * session will transmit a packet. When the count is reached an event
- * will be generated for
- * {@link WifiNanSessionListener#onSubscribeTerminated(int)} with reason=
- * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
- *
- * @param subscribeCount Number of subscribe packets to transmit.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setSubscribeCount(int subscribeCount) {
- if (subscribeCount < 0) {
- throw new IllegalArgumentException("Invalid subscribeCount - must be non-negative");
- }
- mSubscribeCount = subscribeCount;
- return this;
- }
-
- /**
- * Sets the time interval (in seconds) an active (
- * {@link SubscribeSettings.Builder#setSubscribeType(int)}) subscribe
- * session will be alive - i.e. transmitting a packet. When the TTL is
- * reached an event will be generated for
- * {@link WifiNanSessionListener#onSubscribeTerminated(int)} with reason=
- * {@link WifiNanSessionListener#TERMINATE_REASON_DONE}.
- *
- * @param ttlSec Lifetime of a subscribe session in seconds.
- * @return The builder to facilitate chaining
- * {@code builder.setXXX(..).setXXX(..)}.
- */
- public Builder setTtlSec(int ttlSec) {
- if (ttlSec < 0) {
- throw new IllegalArgumentException("Invalid ttlSec - must be non-negative");
- }
- mTtlSec = ttlSec;
- return this;
- }
-
- /**
- * Build {@link SubscribeSettings} given the current requests made on
- * the builder.
- */
- public SubscribeSettings build() {
- return new SubscribeSettings(mSubscribeType, mSubscribeCount, mTtlSec);
- }
- }
-}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanEventCallback.java b/wifi/java/android/net/wifi/nan/WifiNanEventCallback.java
new file mode 100644
index 000000000000..2b9a5fa133b0
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanEventCallback.java
@@ -0,0 +1,92 @@
+/*
+ * 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.nan;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Base class for NAN events callbacks. Should be extended by applications
+ * wanting notifications. These are callbacks applying to the NAN connection as
+ * a whole - not to specific publish or subscribe sessions - for that see
+ * {@link WifiNanSessionCallback}.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanEventCallback {
+ @IntDef({
+ REASON_INVALID_ARGS, REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG, REASON_OTHER
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface EventReasonCodes {
+ }
+
+ /**
+ * Failure reason flag for {@link WifiNanEventCallback} callbacks. Indicates
+ * invalid argument in the requested operation.
+ */
+ public static final int REASON_INVALID_ARGS = 1000;
+
+ /**
+ * Failure reason flag for {@link WifiNanEventCallback} callbacks. Indicates
+ * that a {@link ConfigRequest} passed in
+ * {@link WifiNanManager#connect(android.os.Looper, WifiNanEventCallback, ConfigRequest)}
+ * couldn't be applied since other connections already exist with an
+ * incompatible configurations.
+ */
+ public static final int REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG = 1001;
+
+ /**
+ * Failure reason flag for {@link WifiNanEventCallback} callbacks. Indicates
+ * an unspecified error occurred during the operation.
+ */
+ public static final int REASON_OTHER = 1003;
+
+ /**
+ * Called when NAN connect operation
+ * {@link WifiNanManager#connect(android.os.Looper, WifiNanEventCallback)}
+ * is completed. Doesn't necessarily mean that have joined or started a NAN
+ * cluster. An indication is provided by {@link #onIdentityChanged()}.
+ */
+ public void onConnectSuccess() {
+ /* empty */
+ }
+
+ /**
+ * Called when NAN connect operation
+ * {@code WifiNanManager#connect(android.os.Looper, WifiNanEventCallback)}
+ * failed.
+ *
+ * @param reason Failure reason code, see
+ * {@code WifiNanEventCallback.REASON_*}.
+ */
+ public void onConnectFail(@EventReasonCodes int reason) {
+ /* empty */
+ }
+
+ /**
+ * Called when NAN identity has changed. This may be due to joining a
+ * cluster, starting a cluster, or discovery interface change. The
+ * implication is that peers you've been communicating with may no longer
+ * recognize you and you need to re-establish your identity.
+ */
+ public void onIdentityChanged() {
+ /* empty */
+ }
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java b/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
deleted file mode 100644
index 9e6ed4ee9634..000000000000
--- a/wifi/java/android/net/wifi/nan/WifiNanEventListener.java
+++ /dev/null
@@ -1,205 +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.nan;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-/**
- * Base class for NAN events callbacks. Should be extended by applications
- * wanting notifications. These are callbacks applying to the NAN connection as
- * a whole - not to specific publish or subscribe sessions - for that see
- * {@link WifiNanSessionListener}.
- * <p>
- * During registration specify which specific events are desired using a set of
- * {@code NanEventListener.LISTEN_*} flags OR'd together. Only those events will
- * be delivered to the registered listener. Override those callbacks
- * {@code NanEventListener.on*} for the registered events.
- *
- * @hide PROPOSED_NAN_API
- */
-public class WifiNanEventListener {
- private static final String TAG = "WifiNanEventListener";
- private static final boolean DBG = false;
- private static final boolean VDBG = false; // STOPSHIP if true
-
- /**
- * Configuration completion callback event registration flag. Corresponding
- * callback is {@link WifiNanEventListener#onConfigCompleted(ConfigRequest)}.
- */
- public static final int LISTEN_CONFIG_COMPLETED = 0x1 << 0;
-
- /**
- * Configuration failed callback event registration flag. Corresponding
- * callback is
- * {@link WifiNanEventListener#onConfigFailed(ConfigRequest, int)}.
- */
- public static final int LISTEN_CONFIG_FAILED = 0x1 << 1;
-
- /**
- * NAN cluster is down callback event registration flag. Corresponding
- * callback is {@link WifiNanEventListener#onNanDown(int)}.
- */
- public static final int LISTEN_NAN_DOWN = 0x1 << 2;
-
- /**
- * NAN identity has changed event registration flag. This may be due to
- * joining a cluster, starting a cluster, or discovery interface change. The
- * implication is that peers you've been communicating with may no longer
- * recognize you and you need to re-establish your identity. Corresponding
- * callback is {@link WifiNanEventListener#onIdentityChanged()}.
- */
- public static final int LISTEN_IDENTITY_CHANGED = 0x1 << 3;
-
- private final Handler mHandler;
-
- /**
- * Constructs a {@link WifiNanEventListener} using the looper of the current
- * thread. I.e. all callbacks will be delivered on the current thread.
- */
- public WifiNanEventListener() {
- this(Looper.myLooper());
- }
-
- /**
- * Constructs a {@link WifiNanEventListener} using the specified looper. I.e.
- * all callbacks will delivered on the thread of the specified looper.
- *
- * @param looper The looper on which to execute the callbacks.
- */
- public WifiNanEventListener(Looper looper) {
- if (VDBG) Log.v(TAG, "ctor: looper=" + looper);
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
- switch (msg.what) {
- case LISTEN_CONFIG_COMPLETED:
- WifiNanEventListener.this.onConfigCompleted((ConfigRequest) msg.obj);
- break;
- case LISTEN_CONFIG_FAILED:
- WifiNanEventListener.this.onConfigFailed((ConfigRequest) msg.obj, msg.arg1);
- break;
- case LISTEN_NAN_DOWN:
- WifiNanEventListener.this.onNanDown(msg.arg1);
- break;
- case LISTEN_IDENTITY_CHANGED:
- WifiNanEventListener.this.onIdentityChanged();
- break;
- }
- }
- };
- }
-
- /**
- * Called when NAN configuration is completed. Event will only be delivered
- * if registered using {@link WifiNanEventListener#LISTEN_CONFIG_COMPLETED}. A
- * dummy (empty implementation printing out a warning). Make sure to
- * override if registered.
- *
- * @param completedConfig The actual configuration request which was
- * completed. Note that it may be different from that requested
- * by the application. The service combines configuration
- * requests from all applications.
- */
- public void onConfigCompleted(ConfigRequest completedConfig) {
- Log.w(TAG, "onConfigCompleted: called in stub - override if interested or disable");
- }
-
- /**
- * Called when NAN configuration failed. Event will only be delivered if
- * registered using {@link WifiNanEventListener#LISTEN_CONFIG_FAILED}. A dummy
- * (empty implementation printing out a warning). Make sure to override if
- * registered.
- *
- * @param reason Failure reason code, see {@code NanSessionListener.FAIL_*}.
- */
- public void onConfigFailed(ConfigRequest failedConfig, int reason) {
- Log.w(TAG, "onConfigFailed: called in stub - override if interested or disable");
- }
-
- /**
- * Called when NAN cluster is down. Event will only be delivered if
- * registered using {@link WifiNanEventListener#LISTEN_NAN_DOWN}. A dummy (empty
- * implementation printing out a warning). Make sure to override if
- * registered.
- *
- * @param reason Reason code for event, see {@code NanSessionListener.FAIL_*}.
- */
- public void onNanDown(int reason) {
- Log.w(TAG, "onNanDown: called in stub - override if interested or disable");
- }
-
- /**
- * Called when NAN identity has changed. This may be due to joining a
- * cluster, starting a cluster, or discovery interface change. The
- * implication is that peers you've been communicating with may no longer
- * recognize you and you need to re-establish your identity. Event will only
- * be delivered if registered using
- * {@link WifiNanEventListener#LISTEN_IDENTITY_CHANGED}. A dummy (empty
- * implementation printing out a warning). Make sure to override if
- * registered.
- */
- public void onIdentityChanged() {
- if (VDBG) Log.v(TAG, "onIdentityChanged: called in stub - override if interested");
- }
-
- /**
- * {@hide}
- */
- public IWifiNanEventListener callback = new IWifiNanEventListener.Stub() {
- @Override
- public void onConfigCompleted(ConfigRequest completedConfig) {
- if (VDBG) Log.v(TAG, "onConfigCompleted: configRequest=" + completedConfig);
-
- Message msg = mHandler.obtainMessage(LISTEN_CONFIG_COMPLETED);
- msg.obj = completedConfig;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onConfigFailed(ConfigRequest failedConfig, int reason) {
- if (VDBG) {
- Log.v(TAG, "onConfigFailed: failedConfig=" + failedConfig + ", reason=" + reason);
- }
-
- Message msg = mHandler.obtainMessage(LISTEN_CONFIG_FAILED);
- msg.arg1 = reason;
- msg.obj = failedConfig;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onNanDown(int reason) {
- if (VDBG) Log.v(TAG, "onNanDown: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(LISTEN_NAN_DOWN);
- msg.arg1 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onIdentityChanged() {
- if (VDBG) Log.v(TAG, "onIdentityChanged");
-
- Message msg = mHandler.obtainMessage(LISTEN_IDENTITY_CHANGED);
- mHandler.sendMessage(msg);
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanManager.java b/wifi/java/android/net/wifi/nan/WifiNanManager.java
index 1b78bebfbba7..905562266547 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanManager.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanManager.java
@@ -16,10 +16,25 @@
package android.net.wifi.nan;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.net.wifi.RttManager;
import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
/**
* This class provides the primary API for managing Wi-Fi NAN operation:
@@ -41,9 +56,57 @@ public class WifiNanManager {
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
- private IBinder mBinder;
+ private static final int INVALID_CLIENT_ID = 0;
+
+ /**
+ * Broadcast intent action to indicate whether Wi-Fi NAN is enabled or
+ * disabled. An extra {@link #EXTRA_WIFI_STATE} provides the state
+ * information as int.
+ *
+ * @see #EXTRA_WIFI_STATE
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String WIFI_NAN_STATE_CHANGED_ACTION = "android.net.wifi.nan.STATE_CHANGED";
+
+ /**
+ * The lookup key for an int that indicates whether Wi-Fi NAN is enabled or
+ * disabled. Retrieve it with
+ * {@link android.content.Intent#getIntExtra(String,int)}.
+ *
+ * @see #WIFI_NAN_STATE_DISABLED
+ * @see #WIFI_NAN_STATE_ENABLED
+ */
+ public static final String EXTRA_WIFI_STATE = "wifi_nan_state";
+
+ /**
+ * Wi-Fi NAN is disabled.
+ *
+ * @see #WIFI_NAN_STATE_CHANGED_ACTION
+ */
+ public static final int WIFI_NAN_STATE_DISABLED = 1;
+
+ /**
+ * Wi-Fi NAN is enabled.
+ *
+ * @see #WIFI_NAN_STATE_CHANGED_ACTION
+ */
+ public static final int WIFI_NAN_STATE_ENABLED = 2;
+
+ private final IWifiNanManager mService;
+
+ private final Object mLock = new Object(); // lock access to the following vars
+
+ @GuardedBy("mLock")
+ private final IBinder mBinder = new Binder();
- private IWifiNanManager mService;
+ @GuardedBy("mLock")
+ private int mClientId = INVALID_CLIENT_ID;
+
+ @GuardedBy("mLock")
+ private Looper mLooper;
+
+ @GuardedBy("mLock")
+ private SparseArray<RttManager.RttListener> mRangingListeners = new SparseArray<>();
/**
* {@hide}
@@ -53,280 +116,720 @@ public class WifiNanManager {
}
/**
- * Re-connect to the Wi-Fi NAN service - enabling the application to execute
- * {@link WifiNanManager} APIs. Application don't normally need to call this
- * API since it is executed in the constructor. However, applications which
- * have explicitly {@link WifiNanManager#disconnect()} need to call this
- * function to re-connect.
+ * Enable the usage of the NAN API. Doesn't actually turn on NAN cluster formation - that only
+ * happens when a connection is made. {@link #WIFI_NAN_STATE_CHANGED_ACTION} broadcast will be
+ * triggered.
*
- * @param listener A listener extended from {@link WifiNanEventListener}.
- * @param events The set of events to be delivered to the {@code listener}.
- * OR'd event flags from {@link WifiNanEventListener
- * NanEventListener.LISTEN*}.
+ * @hide PROPOSED_NAN_SYSTEM_API
*/
- public void connect(WifiNanEventListener listener, int events) {
+ public void enableUsage() {
try {
- if (VDBG) Log.v(TAG, "connect()");
- if (listener == null) {
- throw new IllegalArgumentException("Invalid listener - must not be null");
- }
- if (mBinder == null) {
- mBinder = new Binder();
- }
- mService.connect(mBinder, listener.callback, events);
+ mService.enableUsage();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
}
/**
- * Disconnect from the Wi-Fi NAN service and destroy all outstanding
- * operations - i.e. all publish and subscribes are terminated, any
- * outstanding data-link is shut-down, and all requested NAN configurations
- * are cancelled.
- * <p>
- * An application may then re-connect using
- * {@link WifiNanManager#connect(WifiNanEventListener, int)} .
+ * Disable the usage of the NAN API. All attempts to connect() will be rejected. All open
+ * connections and sessions will be terminated. {@link #WIFI_NAN_STATE_CHANGED_ACTION} broadcast
+ * will be triggered.
+ *
+ * @hide PROPOSED_NAN_SYSTEM_API
*/
- public void disconnect() {
+ public void disableUsage() {
try {
- if (VDBG) Log.v(TAG, "disconnect()");
- mService.disconnect(mBinder);
- mBinder = null;
+ mService.disableUsage();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
}
/**
- * Requests a NAN configuration, specified by {@link ConfigRequest}. Note
- * that NAN is a shared resource and the device can only be a member of a
- * single cluster. Thus the service may merge configuration requests from
- * multiple applications and configure NAN differently from individual
- * requests.
- * <p>
- * The {@link WifiNanEventListener#onConfigCompleted(ConfigRequest)} will be
- * called when configuration is completed (if a listener is registered for
- * this specific event).
+ * Returns the current status of NAN API: whether or not usage is enabled.
*
- * @param configRequest The requested NAN configuration.
+ * @return A boolean indicating whether the app can use the NAN API (true)
+ * or not (false).
*/
- public void requestConfig(ConfigRequest configRequest) {
- if (VDBG) Log.v(TAG, "requestConfig(): configRequest=" + configRequest);
+ public boolean isUsageEnabled() {
try {
- mService.requestConfig(configRequest);
+ return mService.isUsageEnabled();
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
+
+ return false;
}
/**
- * Request a NAN publish session. The results of the publish session
- * operation will result in callbacks to the indicated listener:
- * {@link WifiNanSessionListener NanSessionListener.on*}.
+ * Connect to the Wi-Fi NAN service - enabling the application to execute
+ * {@link WifiNanManager} APIs.
*
- * @param publishData The {@link PublishData} specifying the contents of the
- * publish session.
- * @param publishSettings The {@link PublishSettings} specifying the
- * settings for the publish session.
- * @param listener The {@link WifiNanSessionListener} derived objects to be used
- * for the event callbacks specified by {@code events}.
- * @param events The list of events to be delivered to the {@code listener}
- * object. An OR'd value of {@link WifiNanSessionListener
- * NanSessionListener.LISTEN_*}.
- * @return The {@link WifiNanPublishSession} which can be used to further
- * control the publish session.
+ * @param looper The Looper on which to execute all callbacks related to the
+ * connection - including all sessions opened as part of this
+ * connection.
+ * @param callback A callback extended from {@link WifiNanEventCallback}.
*/
- public WifiNanPublishSession publish(PublishData publishData, PublishSettings publishSettings,
- WifiNanSessionListener listener, int events) {
- return publishRaw(publishData, publishSettings, listener,
- events | WifiNanSessionListener.LISTEN_HIDDEN_FLAGS);
+ public void connect(@NonNull Looper looper, @NonNull WifiNanEventCallback callback) {
+ connect(looper, callback, null);
}
/**
- * Same as publish(*) but does not modify the event flag
+ * Connect to the Wi-Fi NAN service - enabling the application to execute
+ * {@link WifiNanManager} APIs. Allows requesting a specific configuration
+ * using {@link ConfigRequest} structure. Limited to privileged access.
*
- * @hide
+ * @param looper The Looper on which to execute all callbacks related to the
+ * connection - including all sessions opened as part of this
+ * connection.
+ * @param callback A callback extended from {@link WifiNanEventCallback}.
+ * @param configRequest The requested NAN configuration.
*/
- public WifiNanPublishSession publishRaw(PublishData publishData,
- PublishSettings publishSettings, WifiNanSessionListener listener, int events) {
- if (VDBG) Log.v(TAG, "publish(): data='" + publishData + "', settings=" + publishSettings);
-
- if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_UNSOLICITED
- && publishData.mRxFilterLength != 0) {
- throw new IllegalArgumentException("Invalid publish data & settings: UNSOLICITED "
- + "publishes (active) can't have an Rx filter");
- }
- if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_SOLICITED
- && publishData.mTxFilterLength != 0) {
- throw new IllegalArgumentException("Invalid publish data & settings: SOLICITED "
- + "publishes (passive) can't have a Tx filter");
+ public void connect(@NonNull Looper looper, @NonNull WifiNanEventCallback callback,
+ @Nullable ConfigRequest configRequest) {
+ if (VDBG) {
+ Log.v(TAG, "connect(): looper=" + looper + ", callback=" + callback + ", configRequest="
+ + configRequest);
}
- if (listener == null) {
- throw new IllegalArgumentException("Invalid listener - must not be null");
+
+ synchronized (mLock) {
+ mLooper = looper;
+
+ try {
+ mClientId = mService.connect(mBinder,
+ new WifiNanEventCallbackProxy(this, looper, callback), configRequest);
+ } catch (RemoteException e) {
+ mClientId = INVALID_CLIENT_ID;
+ mLooper = null;
+ e.rethrowFromSystemServer();
+ }
}
+ }
- int sessionId;
+ /**
+ * Disconnect from the Wi-Fi NAN service and destroy all outstanding
+ * operations - i.e. all publish and subscribes are terminated, any
+ * outstanding data-link is shut-down, and all requested NAN configurations
+ * are cancelled.
+ * <p>
+ * An application may then re-connect using
+ * {@link WifiNanManager#connect(Looper, WifiNanEventCallback)} .
+ */
+ public void disconnect() {
+ if (VDBG) Log.v(TAG, "disconnect()");
+
+ IBinder binder;
+ int clientId;
+ synchronized (mLock) {
+ if (mClientId == INVALID_CLIENT_ID) {
+ Log.w(TAG, "disconnect(): called with invalid client ID - not connected first?");
+ return;
+ }
+
+ binder = mBinder;
+ clientId = mClientId;
+
+ mLooper = null;
+ mClientId = INVALID_CLIENT_ID;
+ }
try {
- sessionId = mService.createSession(listener.callback, events);
- if (DBG) Log.d(TAG, "publish: session created - sessionId=" + sessionId);
- mService.publish(sessionId, publishData, publishSettings);
+ mService.disconnect(clientId, binder);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
+ }
- return new WifiNanPublishSession(this, sessionId);
+ @Override
+ protected void finalize() throws Throwable {
+ disconnect();
+ super.finalize();
}
/**
- * {@hide}
+ * Request a NAN publish session. The actual publish session is provided by
+ * the
+ * {@link WifiNanSessionCallback#onPublishStarted(WifiNanPublishSession)}
+ * callback. Other results of the publish session operation will result in
+ * callbacks to the indicated callback: {@link WifiNanSessionCallback
+ * NanSessionCallback.on*}.
+ *
+ * @param publishConfig The {@link PublishConfig} specifying the
+ * configuration of the publish session.
+ * @param callback The {@link WifiNanSessionCallback} derived objects to be
+ * used for the event callbacks specified by {@code events}.
*/
- public void publish(int sessionId, PublishData publishData, PublishSettings publishSettings) {
- if (VDBG) Log.v(TAG, "publish(): data='" + publishData + "', settings=" + publishSettings);
+ public void publish(@NonNull PublishConfig publishConfig,
+ @NonNull WifiNanSessionCallback callback) {
+ if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig);
- if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_UNSOLICITED
- && publishData.mRxFilterLength != 0) {
- throw new IllegalArgumentException("Invalid publish data & settings: UNSOLICITED "
- + "publishes (active) can't have an Rx filter");
- }
- if (publishSettings.mPublishType == PublishSettings.PUBLISH_TYPE_SOLICITED
- && publishData.mTxFilterLength != 0) {
- throw new IllegalArgumentException("Invalid publish data & settings: SOLICITED "
- + "publishes (passive) can't have a Tx filter");
- }
+ int clientId;
+ Looper looper;
+ synchronized (mLock) {
+ if (mLooper == null || mClientId == INVALID_CLIENT_ID) {
+ Log.e(TAG, "publish(): called with null looper or invalid client ID - "
+ + "not connected first?");
+ return;
+ }
+ clientId = mClientId;
+ looper = mLooper;
+ }
try {
- mService.publish(sessionId, publishData, publishSettings);
+ mService.publish(clientId, publishConfig,
+ new WifiNanSessionCallbackProxy(this, looper, true, callback));
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
}
+
/**
- * Request a NAN subscribe session. The results of the subscribe session
- * operation will result in callbacks to the indicated listener:
- * {@link WifiNanSessionListener NanSessionListener.on*}.
- *
- * @param subscribeData The {@link SubscribeData} specifying the contents of
- * the subscribe session.
- * @param subscribeSettings The {@link SubscribeSettings} specifying the
- * settings for the subscribe session.
- * @param listener The {@link WifiNanSessionListener} derived objects to be used
- * for the event callbacks specified by {@code events}.
- * @param events The list of events to be delivered to the {@code listener}
- * object. An OR'd value of {@link WifiNanSessionListener
- * NanSessionListener.LISTEN_*}.
- * @return The {@link WifiNanSubscribeSession} which can be used to further
- * control the subscribe session.
+ * {@hide}
*/
- public WifiNanSubscribeSession subscribe(SubscribeData subscribeData,
- SubscribeSettings subscribeSettings,
- WifiNanSessionListener listener, int events) {
- return subscribeRaw(subscribeData, subscribeSettings, listener,
- events | WifiNanSessionListener.LISTEN_HIDDEN_FLAGS);
+ public void updatePublish(int sessionId, PublishConfig publishConfig) {
+ if (VDBG) Log.v(TAG, "updatePublish(): config=" + publishConfig);
+
+ int clientId;
+ synchronized (mLock) {
+ if (mClientId == INVALID_CLIENT_ID) {
+ Log.e(TAG, "updatePublish(): called with invalid client ID - not connected first?");
+ return;
+ }
+
+ clientId = mClientId;
+ }
+ try {
+ mService.updatePublish(clientId, sessionId, publishConfig);
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
}
/**
- * Same as subscribe(*) but does not modify the event flag
+ * Request a NAN subscribe session. The actual subscribe session is provided
+ * by the
+ * {@link WifiNanSessionCallback#onSubscribeStarted(WifiNanSubscribeSession)}
+ * callback. Other results of the subscribe session operation will result in
+ * callbacks to the indicated callback: {@link WifiNanSessionCallback
+ * NanSessionCallback.on*}
*
- * @hide
+ * @param subscribeConfig The {@link SubscribeConfig} specifying the
+ * configuration of the subscribe session.
+ * @param callback The {@link WifiNanSessionCallback} derived objects to be
+ * used for the event callbacks specified by {@code events}.
*/
- public WifiNanSubscribeSession subscribeRaw(SubscribeData subscribeData,
- SubscribeSettings subscribeSettings, WifiNanSessionListener listener, int events) {
+ public void subscribe(@NonNull SubscribeConfig subscribeConfig,
+ @NonNull WifiNanSessionCallback callback) {
if (VDBG) {
- Log.v(TAG, "subscribe(): data='" + subscribeData + "', settings=" + subscribeSettings);
+ Log.v(TAG, "subscribe(): config=" + subscribeConfig);
}
- if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_ACTIVE
- && subscribeData.mRxFilterLength != 0) {
- throw new IllegalArgumentException(
- "Invalid subscribe data & settings: ACTIVE subscribes can't have an Rx filter");
- }
- if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE
- && subscribeData.mTxFilterLength != 0) {
- throw new IllegalArgumentException(
- "Invalid subscribe data & settings: PASSIVE subscribes can't have a Tx filter");
- }
+ int clientId;
+ Looper looper;
+ synchronized (mLock) {
+ if (mLooper == null || mClientId == INVALID_CLIENT_ID) {
+ Log.e(TAG, "subscribe(): called with null looper or invalid client ID - "
+ + "not connected first?");
+ return;
+ }
- int sessionId;
+ clientId = mClientId;
+ looper = mLooper;
+ }
try {
- sessionId = mService.createSession(listener.callback, events);
- if (DBG) Log.d(TAG, "subscribe: session created - sessionId=" + sessionId);
- mService.subscribe(sessionId, subscribeData, subscribeSettings);
+ mService.subscribe(clientId, subscribeConfig,
+ new WifiNanSessionCallbackProxy(this, looper, false, callback));
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
-
- return new WifiNanSubscribeSession(this, sessionId);
}
/**
* {@hide}
*/
- public void subscribe(int sessionId, SubscribeData subscribeData,
- SubscribeSettings subscribeSettings) {
+ public void updateSubscribe(int sessionId, SubscribeConfig subscribeConfig) {
if (VDBG) {
- Log.v(TAG, "subscribe(): data='" + subscribeData + "', settings=" + subscribeSettings);
+ Log.v(TAG, "subscribe(): config=" + subscribeConfig);
}
- if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_ACTIVE
- && subscribeData.mRxFilterLength != 0) {
- throw new IllegalArgumentException(
- "Invalid subscribe data & settings: ACTIVE subscribes can't have an Rx filter");
- }
- if (subscribeSettings.mSubscribeType == SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE
- && subscribeData.mTxFilterLength != 0) {
- throw new IllegalArgumentException(
- "Invalid subscribe data & settings: PASSIVE subscribes can't have a Tx filter");
+ int clientId;
+ synchronized (mLock) {
+ if (mClientId == INVALID_CLIENT_ID) {
+ Log.e(TAG,
+ "updateSubscribe(): called with invalid client ID - not connected first?");
+ return;
+ }
+
+ clientId = mClientId;
}
try {
- mService.subscribe(sessionId, subscribeData, subscribeSettings);
+ mService.updateSubscribe(clientId, sessionId, subscribeConfig);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
}
/**
* {@hide}
*/
- public void stopSession(int sessionId) {
- if (DBG) Log.d(TAG, "Stop NAN session #" + sessionId);
+ public void terminateSession(int sessionId) {
+ if (DBG) Log.d(TAG, "Terminate NAN session #" + sessionId);
+
+ int clientId;
+ synchronized (mLock) {
+ if (mClientId == INVALID_CLIENT_ID) {
+ Log.e(TAG,
+ "terminateSession(): called with invalid client ID - not connected first?");
+ return;
+ }
+
+ clientId = mClientId;
+ }
try {
- mService.stopSession(sessionId);
+ mService.terminateSession(clientId, sessionId);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
}
/**
* {@hide}
*/
- public void destroySession(int sessionId) {
- if (DBG) Log.d(TAG, "Destroy NAN session #" + sessionId);
+ public void sendMessage(int sessionId, int peerId, byte[] message, int messageLength,
+ int messageId, int retryCount) {
+ if (VDBG) {
+ Log.v(TAG, "sendMessage(): sessionId=" + sessionId + ", peerId=" + peerId
+ + ", messageLength=" + messageLength + ", messageId=" + messageId
+ + ", retryCount=" + retryCount);
+ }
+
+ int clientId;
+ synchronized (mLock) {
+ if (mClientId == INVALID_CLIENT_ID) {
+ Log.e(TAG, "sendMessage(): called with invalid client ID - not connected first?");
+ return;
+ }
+
+ clientId = mClientId;
+ }
try {
- mService.destroySession(sessionId);
+ mService.sendMessage(clientId, sessionId, peerId, message, messageLength, messageId,
+ retryCount);
} catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+ e.rethrowFromSystemServer();
}
}
/**
* {@hide}
*/
- public void sendMessage(int sessionId, int peerId, byte[] message, int messageLength,
- int messageId) {
+ public void startRanging(int sessionId, RttManager.RttParams[] params,
+ RttManager.RttListener listener) {
+ if (VDBG) {
+ Log.v(TAG, "startRanging: sessionId=" + sessionId + ", " + "params="
+ + Arrays.toString(params) + ", listener=" + listener);
+ }
+
+ int clientId;
+ synchronized (mLock) {
+ if (mClientId == INVALID_CLIENT_ID) {
+ Log.e(TAG, "startRanging(): called with invalid client ID - not connected first?");
+ return;
+ }
+
+ clientId = mClientId;
+ }
+
+ int rangingKey = 0;
try {
+ rangingKey = mService.startRanging(clientId, sessionId,
+ new RttManager.ParcelableRttParams(params));
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+
+ synchronized (mLock) {
+ mRangingListeners.put(rangingKey, listener);
+ }
+ }
+
+ private static class WifiNanEventCallbackProxy extends IWifiNanEventCallback.Stub {
+ private static final int CALLBACK_CONNECT_SUCCESS = 0;
+ private static final int CALLBACK_CONNECT_FAIL = 1;
+ private static final int CALLBACK_IDENTITY_CHANGED = 2;
+ private static final int CALLBACK_RANGING_SUCCESS = 3;
+ private static final int CALLBACK_RANGING_FAILURE = 4;
+ private static final int CALLBACK_RANGING_ABORTED = 5;
+
+ private final Handler mHandler;
+ private final WeakReference<WifiNanManager> mNanManager;
+
+ RttManager.RttListener getAndRemoveRangingListener(int rangingId) {
+ WifiNanManager mgr = mNanManager.get();
+ if (mgr == null) {
+ Log.w(TAG, "getAndRemoveRangingListener: called post GC");
+ return null;
+ }
+
+ synchronized (mgr.mLock) {
+ RttManager.RttListener listener = mgr.mRangingListeners.get(rangingId);
+ mgr.mRangingListeners.delete(rangingId);
+ return listener;
+ }
+ }
+
+ /**
+ * Constructs a {@link WifiNanEventCallback} using the specified looper.
+ * I.e. all callbacks will delivered on the thread of the specified looper.
+ *
+ * @param looper The looper on which to execute the callbacks.
+ */
+ WifiNanEventCallbackProxy(WifiNanManager mgr, Looper looper,
+ final WifiNanEventCallback originalCallback) {
+ mNanManager = new WeakReference<>(mgr);
+
+ if (VDBG) Log.v(TAG, "WifiNanEventCallbackProxy ctor: looper=" + looper);
+ mHandler = new Handler(looper) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (DBG) {
+ Log.d(TAG, "WifiNanEventCallbackProxy: What=" + msg.what + ", msg=" + msg);
+ }
+
+ WifiNanManager mgr = mNanManager.get();
+ if (mgr == null) {
+ Log.w(TAG, "WifiNanEventCallbackProxy: handleMessage post GC");
+ return;
+ }
+
+ switch (msg.what) {
+ case CALLBACK_CONNECT_SUCCESS:
+ originalCallback.onConnectSuccess();
+ break;
+ case CALLBACK_CONNECT_FAIL:
+ synchronized (mgr.mLock) {
+ mgr.mLooper = null;
+ mgr.mClientId = INVALID_CLIENT_ID;
+ }
+ mNanManager.clear();
+ originalCallback.onConnectFail(msg.arg1);
+ break;
+ case CALLBACK_IDENTITY_CHANGED:
+ originalCallback.onIdentityChanged();
+ break;
+ case CALLBACK_RANGING_SUCCESS: {
+ RttManager.RttListener listener = getAndRemoveRangingListener(msg.arg1);
+ if (listener == null) {
+ Log.e(TAG, "CALLBACK_RANGING_SUCCESS rangingId=" + msg.arg1
+ + ": no listener registered (anymore)");
+ } else {
+ listener.onSuccess(
+ ((RttManager.ParcelableRttResults) msg.obj).mResults);
+ }
+ break;
+ }
+ case CALLBACK_RANGING_FAILURE: {
+ RttManager.RttListener listener = getAndRemoveRangingListener(msg.arg1);
+ if (listener == null) {
+ Log.e(TAG, "CALLBACK_RANGING_SUCCESS rangingId=" + msg.arg1
+ + ": no listener registered (anymore)");
+ } else {
+ listener.onFailure(msg.arg2, (String) msg.obj);
+ }
+ break;
+ }
+ case CALLBACK_RANGING_ABORTED: {
+ RttManager.RttListener listener = getAndRemoveRangingListener(msg.arg1);
+ if (listener == null) {
+ Log.e(TAG, "CALLBACK_RANGING_SUCCESS rangingId=" + msg.arg1
+ + ": no listener registered (anymore)");
+ } else {
+ listener.onAborted();
+ }
+ break;
+ }
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onConnectSuccess() {
+ if (VDBG) Log.v(TAG, "onConnectSuccess");
+
+ Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_SUCCESS);
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onConnectFail(int reason) {
+ if (VDBG) Log.v(TAG, "onConfigFailed: reason=" + reason);
+
+ Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_FAIL);
+ msg.arg1 = reason;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onIdentityChanged() {
+ if (VDBG) Log.v(TAG, "onIdentityChanged");
+
+ Message msg = mHandler.obtainMessage(CALLBACK_IDENTITY_CHANGED);
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onRangingSuccess(int rangingId, RttManager.ParcelableRttResults results) {
if (VDBG) {
- Log.v(TAG, "sendMessage(): sessionId=" + sessionId + ", peerId=" + peerId
- + ", messageLength=" + messageLength + ", messageId=" + messageId);
+ Log.v(TAG, "onRangingSuccess: rangingId=" + rangingId + ", results=" + results);
}
- mService.sendMessage(sessionId, peerId, message, messageLength, messageId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
+
+ Message msg = mHandler.obtainMessage(CALLBACK_RANGING_SUCCESS);
+ msg.arg1 = rangingId;
+ msg.obj = results;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onRangingFailure(int rangingId, int reason, String description) {
+ if (VDBG) {
+ Log.v(TAG, "onRangingSuccess: rangingId=" + rangingId + ", reason=" + reason
+ + ", description=" + description);
+ }
+
+ Message msg = mHandler.obtainMessage(CALLBACK_RANGING_FAILURE);
+ msg.arg1 = rangingId;
+ msg.arg2 = reason;
+ msg.obj = description;
+ mHandler.sendMessage(msg);
+
+ }
+
+ @Override
+ public void onRangingAborted(int rangingId) {
+ if (VDBG) Log.v(TAG, "onRangingAborted: rangingId=" + rangingId);
+
+ Message msg = mHandler.obtainMessage(CALLBACK_RANGING_ABORTED);
+ msg.arg1 = rangingId;
+ mHandler.sendMessage(msg);
+
+ }
+ }
+
+ private static class WifiNanSessionCallbackProxy extends IWifiNanSessionCallback.Stub {
+ private static final int CALLBACK_SESSION_STARTED = 0;
+ private static final int CALLBACK_SESSION_CONFIG_SUCCESS = 1;
+ private static final int CALLBACK_SESSION_CONFIG_FAIL = 2;
+ private static final int CALLBACK_SESSION_TERMINATED = 3;
+ private static final int CALLBACK_MATCH = 4;
+ private static final int CALLBACK_MESSAGE_SEND_SUCCESS = 5;
+ private static final int CALLBACK_MESSAGE_SEND_FAIL = 6;
+ private static final int CALLBACK_MESSAGE_RECEIVED = 7;
+
+ private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id";
+ private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
+ private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
+
+ private final WeakReference<WifiNanManager> mNanManager;
+ private final boolean mIsPublish;
+ private final WifiNanSessionCallback mOriginalCallback;
+
+ private final Handler mHandler;
+ private WifiNanSession mSession;
+
+ WifiNanSessionCallbackProxy(WifiNanManager mgr, Looper looper, boolean isPublish,
+ WifiNanSessionCallback originalCallback) {
+ mNanManager = new WeakReference<>(mgr);
+ mIsPublish = isPublish;
+ mOriginalCallback = originalCallback;
+
+ if (VDBG) Log.v(TAG, "WifiNanSessionCallbackProxy ctor: isPublish=" + isPublish);
+
+ mHandler = new Handler(looper) {
+ @Override
+ public void handleMessage(Message msg) {
+ if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
+
+ if (mNanManager.get() == null) {
+ Log.w(TAG, "WifiNanSessionCallbackProxy: handleMessage post GC");
+ return;
+ }
+
+ switch (msg.what) {
+ case CALLBACK_SESSION_STARTED:
+ onProxySessionStarted(msg.arg1);
+ break;
+ case CALLBACK_SESSION_CONFIG_SUCCESS:
+ mOriginalCallback.onSessionConfigSuccess();
+ break;
+ case CALLBACK_SESSION_CONFIG_FAIL:
+ mOriginalCallback.onSessionConfigFail(msg.arg1);
+ if (mSession == null) {
+ /*
+ * creation failed (as opposed to update
+ * failing)
+ */
+ mNanManager.clear();
+ }
+ break;
+ case CALLBACK_SESSION_TERMINATED:
+ onProxySessionTerminated(msg.arg1);
+ break;
+ case CALLBACK_MATCH:
+ mOriginalCallback.onMatch(
+ msg.getData().getInt(MESSAGE_BUNDLE_KEY_PEER_ID),
+ msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
+ msg.arg1,
+ msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2),
+ msg.arg2);
+ break;
+ case CALLBACK_MESSAGE_SEND_SUCCESS:
+ mOriginalCallback.onMessageSendSuccess(msg.arg1);
+ break;
+ case CALLBACK_MESSAGE_SEND_FAIL:
+ mOriginalCallback.onMessageSendFail(msg.arg1, msg.arg2);
+ break;
+ case CALLBACK_MESSAGE_RECEIVED:
+ mOriginalCallback.onMessageReceived(msg.arg2,
+ msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
+ msg.arg1);
+ break;
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onSessionStarted(int sessionId) {
+ if (VDBG) Log.v(TAG, "onSessionStarted: sessionId=" + sessionId);
+
+ Message msg = mHandler.obtainMessage(CALLBACK_SESSION_STARTED);
+ msg.arg1 = sessionId;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onSessionConfigSuccess() {
+ if (VDBG) Log.v(TAG, "onSessionConfigSuccess");
+
+ Message msg = mHandler.obtainMessage(CALLBACK_SESSION_CONFIG_SUCCESS);
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onSessionConfigFail(int reason) {
+ if (VDBG) Log.v(TAG, "onSessionConfigFail: reason=" + reason);
+
+ Message msg = mHandler.obtainMessage(CALLBACK_SESSION_CONFIG_FAIL);
+ msg.arg1 = reason;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onSessionTerminated(int reason) {
+ if (VDBG) Log.v(TAG, "onSessionTerminated: reason=" + reason);
+
+ Message msg = mHandler.obtainMessage(CALLBACK_SESSION_TERMINATED);
+ msg.arg1 = reason;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onMatch(int peerId, byte[] serviceSpecificInfo,
+ int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) {
+ if (VDBG) Log.v(TAG, "onMatch: peerId=" + peerId);
+
+ Bundle data = new Bundle();
+ data.putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId);
+ data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, serviceSpecificInfo);
+ data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2, matchFilter);
+
+ Message msg = mHandler.obtainMessage(CALLBACK_MATCH);
+ msg.arg1 = serviceSpecificInfoLength;
+ msg.arg2 = matchFilterLength;
+ msg.setData(data);
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onMessageSendSuccess(int messageId) {
+ if (VDBG) Log.v(TAG, "onMessageSendSuccess");
+
+ Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_SEND_SUCCESS);
+ msg.arg1 = messageId;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onMessageSendFail(int messageId, int reason) {
+ if (VDBG) Log.v(TAG, "onMessageSendFail: reason=" + reason);
+
+ Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_SEND_FAIL);
+ msg.arg1 = messageId;
+ msg.arg2 = reason;
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public void onMessageReceived(int peerId, byte[] message, int messageLength) {
+ if (VDBG) {
+ Log.v(TAG, "onMessageReceived: peerId='" + peerId + "', messageLength="
+ + messageLength);
+ }
+
+ Bundle data = new Bundle();
+ data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message);
+
+ Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_RECEIVED);
+ msg.arg1 = messageLength;
+ msg.arg2 = peerId;
+ msg.setData(data);
+ mHandler.sendMessage(msg);
+ }
+
+ /*
+ * Proxied methods
+ */
+ public void onProxySessionStarted(int sessionId) {
+ if (VDBG) Log.v(TAG, "Proxy: onSessionStarted: sessionId=" + sessionId);
+ if (mSession != null) {
+ Log.e(TAG,
+ "onSessionStarted: sessionId=" + sessionId + ": session already created!?");
+ throw new IllegalStateException(
+ "onSessionStarted: sessionId=" + sessionId + ": session already created!?");
+ }
+
+ WifiNanManager mgr = mNanManager.get();
+ if (mgr == null) {
+ Log.w(TAG, "onProxySessionStarted: mgr GC'd");
+ return;
+ }
+
+ if (mIsPublish) {
+ WifiNanPublishSession session = new WifiNanPublishSession(mgr, sessionId);
+ mSession = session;
+ mOriginalCallback.onPublishStarted(session);
+ } else {
+ WifiNanSubscribeSession session = new WifiNanSubscribeSession(mgr, sessionId);
+ mSession = session;
+ mOriginalCallback.onSubscribeStarted(session);
+ }
+ }
+
+ public void onProxySessionTerminated(int reason) {
+ if (VDBG) Log.v(TAG, "Proxy: onSessionTerminated: reason=" + reason);
+ if (mSession != null) {
+ mSession.setTerminated();
+ mSession = null;
+ } else {
+ Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
+ }
+ mNanManager.clear();
+ mOriginalCallback.onSessionTerminated(reason);
}
}
}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java b/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java
index 81b38f4c12a3..a0e3fbad36c9 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanPublishSession.java
@@ -16,15 +16,20 @@
package android.net.wifi.nan;
+import android.annotation.NonNull;
+import android.util.Log;
+
/**
* A representation of a NAN publish session. Created when
- * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
- * is executed. The object can be used to stop and re-start (re-configure) the
+ * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} is
+ * executed. The object can be used to stop and re-start (re-configure) the
* publish session.
*
* @hide PROPOSED_NAN_API
*/
public class WifiNanPublishSession extends WifiNanSession {
+ private static final String TAG = "WifiNanPublishSession";
+
/**
* {@hide}
*/
@@ -33,15 +38,25 @@ public class WifiNanPublishSession extends WifiNanSession {
}
/**
- * Restart/re-configure the publish session. Note that the
- * {@link WifiNanSessionListener} is not replaced - the same listener used at
- * creation is still used.
+ * Re-configure the publish session. Note that the
+ * {@link WifiNanSessionCallback} is not replaced - the same listener used
+ * at creation is still used.
*
- * @param publishData The data ({@link PublishData}) to publish.
- * @param publishSettings The settings ({@link PublishSettings}) of the
+ * @param publishConfig The configuration ({@link PublishConfig}) of the
* publish session.
*/
- public void publish(PublishData publishData, PublishSettings publishSettings) {
- mManager.publish(mSessionId, publishData, publishSettings);
+ public void updatePublish(@NonNull PublishConfig publishConfig) {
+ if (mTerminated) {
+ Log.w(TAG, "updatePublish: called on terminated session");
+ return;
+ } else {
+ WifiNanManager mgr = mMgr.get();
+ if (mgr == null) {
+ Log.w(TAG, "updatePublish: called post GC on WifiNanManager");
+ return;
+ }
+
+ mgr.updatePublish(mSessionId, publishConfig);
+ }
}
}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSession.java b/wifi/java/android/net/wifi/nan/WifiNanSession.java
index bc1787fee478..3533c02184b3 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSession.java
@@ -16,8 +16,11 @@
package android.net.wifi.nan;
+import android.net.wifi.RttManager;
import android.util.Log;
+import java.lang.ref.WeakReference;
+
/**
* A representation of a single publish or subscribe NAN session. This object
* will not be created directly - only its child classes are available:
@@ -30,20 +33,22 @@ public class WifiNanSession {
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
+ public static final int MAX_SEND_RETRY_COUNT = 5;
+
/**
- * {@hide}
+ * @hide
*/
- protected WifiNanManager mManager;
+ protected WeakReference<WifiNanManager> mMgr;
/**
- * {@hide}
+ * @hide
*/
- protected int mSessionId;
+ protected final int mSessionId;
/**
- * {@hide}
+ * @hide
*/
- private boolean mDestroyed;
+ protected boolean mTerminated = false;
/**
* {@hide}
@@ -51,63 +56,129 @@ public class WifiNanSession {
public WifiNanSession(WifiNanManager manager, int sessionId) {
if (VDBG) Log.v(TAG, "New client created: manager=" + manager + ", sessionId=" + sessionId);
- mManager = manager;
+ mMgr = new WeakReference<>(manager);
mSessionId = sessionId;
- mDestroyed = false;
}
/**
* Terminate the current publish or subscribe session - i.e. stop
* transmitting packet on-air (for an active session) or listening for
- * matches (for a passive session). Note that the session may still receive
- * incoming messages and may be re-configured/re-started at a later time.
+ * matches (for a passive session). The session may not be used for any
+ * additional operations are termination.
*/
- public void stop() {
- mManager.stopSession(mSessionId);
+ public void terminate() {
+ WifiNanManager mgr = mMgr.get();
+ if (mgr == null) {
+ Log.w(TAG, "terminate: called post GC on WifiNanManager");
+ return;
+ }
+ mgr.terminateSession(mSessionId);
+ mTerminated = true;
+ mMgr.clear();
}
/**
- * Destroy the current publish or subscribe session. Performs a
- * {@link WifiNanSession#stop()} function but in addition destroys the session -
- * it will not be able to receive any messages or to be restarted at a later
- * time.
+ * Sets the status of the session to terminated - i.e. an indication that
+ * already terminated rather than executing a termination.
+ *
+ * @hide
*/
- public void destroy() {
- mManager.destroySession(mSessionId);
- mDestroyed = true;
+ public void setTerminated() {
+ if (mTerminated) {
+ Log.w(TAG, "terminate: already terminated.");
+ return;
+ }
+ mTerminated = true;
+ mMgr.clear();
}
- /**
- * {@hide}
- */
@Override
protected void finalize() throws Throwable {
- if (!mDestroyed) {
+ if (!mTerminated) {
Log.w(TAG, "WifiNanSession mSessionId=" + mSessionId
- + " was not explicitly destroyed. The session may use resources until "
- + "destroyed so step should be done explicitly");
+ + " was not explicitly terminated. The session may use resources until "
+ + "terminated so step should be done explicitly");
+ terminate();
}
- destroy();
+ super.finalize();
}
/**
- * Sends a message to the specified destination. Message transmission is
- * part of the current discovery session - i.e. executed subsequent to a
- * publish/subscribe
- * {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}
- * event.
+ * Sends a message to the specified destination. Message transmission is part of the current
+ * discovery session - i.e. executed subsequent to a publish/subscribe
+ * {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)} event.
*
* @param peerId The peer's ID for the message. Must be a result of an
- * {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}
- * event.
+ * {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)} event.
* @param message The message to be transmitted.
- * @param messageLength The number of bytes from the {@code message} to be
- * transmitted.
- * @param messageId An arbitrary integer used by the caller to identify the
- * message. The same integer ID will be returned in the callbacks
- * indicated message send success or failure.
+ * @param messageLength The number of bytes from the {@code message} to be transmitted.
+ * @param messageId An arbitrary integer used by the caller to identify the message. The same
+ * integer ID will be returned in the callbacks indicated message send success or
+ * failure.
+ * @param retryCount An integer specifying how many additional service-level (as opposed to PHY
+ * or MAC level) retries should be attempted if there is no ACK from the receiver
+ * (note: no retransmissions are attempted in other failure cases). A value of 0
+ * indicates no retries. Max possible value is {@link #MAX_SEND_RETRY_COUNT}.
+ */
+ public void sendMessage(int peerId, byte[] message, int messageLength, int messageId,
+ int retryCount) {
+ if (mTerminated) {
+ Log.w(TAG, "sendMessage: called on terminated session");
+ return;
+ } else {
+ WifiNanManager mgr = mMgr.get();
+ if (mgr == null) {
+ Log.w(TAG, "sendMessage: called post GC on WifiNanManager");
+ return;
+ }
+
+ mgr.sendMessage(mSessionId, peerId, message, messageLength, messageId, retryCount);
+ }
+ }
+
+ /**
+ * Sends a message to the specified destination. Message transmission is part of the current
+ * discovery session - i.e. executed subsequent to a publish/subscribe
+ * {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)} event. This is
+ * equivalent to {@link #sendMessage(int, byte[], int, int, int)} with a {@code retryCount} of
+ * 0.
+ *
+ * @param peerId The peer's ID for the message. Must be a result of an
+ * {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)} event.
+ * @param message The message to be transmitted.
+ * @param messageLength The number of bytes from the {@code message} to be transmitted.
+ * @param messageId An arbitrary integer used by the caller to identify the message. The same
+ * integer ID will be returned in the callbacks indicated message send success or
+ * failure.
*/
public void sendMessage(int peerId, byte[] message, int messageLength, int messageId) {
- mManager.sendMessage(mSessionId, peerId, message, messageLength, messageId);
+ sendMessage(peerId, message, messageLength, messageId, 0);
+ }
+
+ /**
+ * Start a ranging operation with the specified peers. The peer IDs are obtained from an
+ * {@link WifiNanSessionCallback#onMatch(int, byte[], int, byte[], int)} or
+ * {@link WifiNanSessionCallback#onMessageReceived(int, byte[], int)} operation - i.e. can only
+ * range devices which are part of an ongoing discovery session.
+ *
+ * @param params RTT parameters - each corresponding to a specific peer ID (the array sizes
+ * must be identical). The
+ * {@link android.net.wifi.RttManager.RttParams#bssid} member must be set to
+ * a peer ID - not to a MAC address.
+ * @param listener The listener to receive the results of the ranging session.
+ */
+ public void startRanging(RttManager.RttParams[] params, RttManager.RttListener listener) {
+ if (mTerminated) {
+ Log.w(TAG, "startRanging: called on terminated session");
+ return;
+ } else {
+ WifiNanManager mgr = mMgr.get();
+ if (mgr == null) {
+ Log.w(TAG, "startRanging: called post GC on WifiNanManager");
+ return;
+ }
+
+ mgr.startRanging(mSessionId, params, listener);
+ }
}
}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSessionCallback.java b/wifi/java/android/net/wifi/nan/WifiNanSessionCallback.java
new file mode 100644
index 000000000000..b1f41006413b
--- /dev/null
+++ b/wifi/java/android/net/wifi/nan/WifiNanSessionCallback.java
@@ -0,0 +1,213 @@
+/*
+ * 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.nan;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Base class for NAN session events callbacks. Should be extended by
+ * applications wanting notifications. The callbacks are registered when a
+ * publish or subscribe session is created using
+ * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} or
+ * {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} .
+ * These are callbacks applying to a specific NAN session.
+ * <p>
+ * A single callback is registered at session creation - it cannot be replaced.
+ *
+ * @hide PROPOSED_NAN_API
+ */
+public class WifiNanSessionCallback {
+ @IntDef({
+ REASON_NO_RESOURCES, REASON_INVALID_ARGS, REASON_NO_MATCH_SESSION,
+ REASON_TX_FAIL, REASON_OTHER })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SessionReasonCodes {
+ }
+
+ @IntDef({
+ TERMINATE_REASON_DONE, TERMINATE_REASON_FAIL })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SessionTerminateCodes {
+ }
+
+ /**
+ * Failure reason flag for {@link WifiNanSessionCallback} callbacks.
+ * Indicates no resources to execute the requested operation.
+ */
+ public static final int REASON_NO_RESOURCES = 0;
+
+ /**
+ * Failure reason flag for {@link WifiNanSessionCallback} callbacks.
+ * Indicates invalid argument in the requested operation.
+ */
+ public static final int REASON_INVALID_ARGS = 1;
+
+ /**
+ * Failure reason flag for {@link WifiNanSessionCallback} callbacks.
+ * Indicates a message is transmitted without a match (i.e. a discovery)
+ * occurring first.
+ */
+ public static final int REASON_NO_MATCH_SESSION = 2;
+
+ /**
+ * Failure reason flag for
+ * {@link WifiNanSessionCallback#onMessageSendFail(int, int)} callback.
+ * Indicates transmission failure: this may be due to local transmission
+ * failure or to no ACK received - i.e. remote device didn't receive the
+ * sent message.
+ */
+ public static final int REASON_TX_FAIL = 3;
+
+ /**
+ * Failure reason flag for {@link WifiNanSessionCallback} callbacks.
+ * Indicates an unspecified error occurred during the operation.
+ */
+ public static final int REASON_OTHER = 4;
+
+ /**
+ * Failure reason flag for
+ * {@link WifiNanSessionCallback#onSessionTerminated(int)} callback.
+ * Indicates that publish or subscribe session is done - i.e. all the
+ * requested operations (per {@link PublishConfig} or
+ * {@link SubscribeConfig}) have been executed.
+ */
+ public static final int TERMINATE_REASON_DONE = 100;
+
+ /**
+ * Failure reason flag for
+ * {@link WifiNanSessionCallback#onSessionTerminated(int)} callback.
+ * Indicates that publish or subscribe session is terminated due to a
+ * failure.
+ */
+ public static final int TERMINATE_REASON_FAIL = 101;
+
+ /**
+ * Called when a publish operation is started successfully.
+ *
+ * @param session The {@link WifiNanPublishSession} used to control the
+ * discovery session.
+ */
+ public void onPublishStarted(@NonNull WifiNanPublishSession session) {
+ /* empty */
+ }
+
+ /**
+ * Called when a subscribe operation is started successfully.
+ *
+ * @param session The {@link WifiNanSubscribeSession} used to control the
+ * discovery session.
+ */
+ public void onSubscribeStarted(@NonNull WifiNanSubscribeSession session) {
+ /* empty */
+ }
+
+ /**
+ * Called when a session update configuration (publish or subscribe update)
+ * succeeds.
+ */
+ public void onSessionConfigSuccess() {
+ /* empty */
+ }
+
+ /**
+ * Called when a session configuration (publish or subscribe setup or
+ * update) fails.
+ *
+ * @param reason The failure reason using
+ * {@code WifiNanSessionCallback.REASON_*} codes.
+ */
+ public void onSessionConfigFail(@SessionReasonCodes int reason) {
+ /* empty */
+ }
+
+ /**
+ * Called when a session (publish or subscribe) terminates.
+ *
+ * @param reason The termination reason using
+ * {@code WifiNanSessionCallback.TERMINATE_*} codes.
+ */
+ public void onSessionTerminated(@SessionTerminateCodes int reason) {
+ /* empty */
+ }
+
+ /**
+ * Called when a discovery (publish or subscribe) operation results in a
+ * match - i.e. when a peer is discovered.
+ *
+ * @param peerId The ID of the peer matching our discovery operation.
+ * @param serviceSpecificInfo The service specific information (arbitrary
+ * byte array) provided by the peer as part of its discovery
+ * packet.
+ * @param serviceSpecificInfoLength The length of the service specific
+ * information array.
+ * @param matchFilter The filter (Tx on advertiser and Rx on listener) which
+ * resulted in this match.
+ * @param matchFilterLength The length of the match filter array.
+ */
+ public void onMatch(int peerId, byte[] serviceSpecificInfo,
+ int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) {
+ /* empty */
+ }
+
+ /**
+ * Called when a message is transmitted successfully - i.e. when we know
+ * that it was received successfully (corresponding to an ACK being
+ * received).
+ * <p>
+ * Note that either this callback or
+ * {@link WifiNanSessionCallback#onMessageSendFail(int, int)} will be
+ * received - never both.
+ */
+ public void onMessageSendSuccess(@SuppressWarnings("unused") int messageId) {
+ /* empty */
+ }
+
+ /**
+ * Called when a message transmission fails - i.e. when no ACK is received.
+ * The hardware will usually attempt to re-transmit several times - this
+ * event is received after all retries are exhausted. There is a possibility
+ * that message was received by the destination successfully but the ACK was
+ * lost
+ * <p>
+ * Note that either this callback or
+ * {@link WifiNanSessionCallback#onMessageSendSuccess(int)} will be received
+ * - never both
+ *
+ * @param reason The failure reason using
+ * {@code WifiNanSessionCallback.REASON_*} codes.
+ */
+ public void onMessageSendFail(@SuppressWarnings("unused") int messageId,
+ @SessionReasonCodes int reason) {
+ /* empty */
+ }
+
+ /**
+ * Called when a message is received from a discovery session peer.
+ *
+ * @param peerId The ID of the peer sending the message.
+ * @param message A byte array containing the message.
+ * @param messageLength The length of the byte array containing the relevant
+ * message bytes.
+ */
+ public void onMessageReceived(int peerId, byte[] message, int messageLength) {
+ /* empty */
+ }
+}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java b/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
deleted file mode 100644
index b9af7def6868..000000000000
--- a/wifi/java/android/net/wifi/nan/WifiNanSessionListener.java
+++ /dev/null
@@ -1,439 +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.nan;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-/**
- * Base class for NAN session events callbacks. Should be extended by
- * applications wanting notifications. The callbacks are registered when a
- * publish or subscribe session is created using
- * {@link WifiNanManager#publish(PublishData, PublishSettings, WifiNanSessionListener, int)}
- * or
- * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
- * . These are callbacks applying to a specific NAN session. Events
- * corresponding to the NAN link are delivered using {@link WifiNanEventListener}.
- * <p>
- * A single listener is registered at session creation - it cannot be replaced.
- * <p>
- * During registration specify which specific events are desired using a set of
- * {@code NanSessionListener.LISTEN_*} flags OR'd together. Only those events
- * will be delivered to the registered listener. Override those callbacks
- * {@code NanSessionListener.on*} for the registered events.
- *
- * @hide PROPOSED_NAN_API
- */
-public class WifiNanSessionListener {
- private static final String TAG = "WifiNanSessionListener";
- private static final boolean DBG = false;
- private static final boolean VDBG = false; // STOPSHIP if true
-
- /**
- * Publish fail callback event registration flag. Corresponding callback is
- * {@link WifiNanSessionListener#onPublishFail(int)}.
- *
- * @hide
- */
- public static final int LISTEN_PUBLISH_FAIL = 0x1 << 0;
-
- /**
- * Publish terminated callback event registration flag. Corresponding
- * callback is {@link WifiNanSessionListener#onPublishTerminated(int)}.
- */
- public static final int LISTEN_PUBLISH_TERMINATED = 0x1 << 1;
-
- /**
- * Subscribe fail callback event registration flag. Corresponding callback
- * is {@link WifiNanSessionListener#onSubscribeFail(int)}.
- *
- * @hide
- */
- public static final int LISTEN_SUBSCRIBE_FAIL = 0x1 << 2;
-
- /**
- * Subscribe terminated callback event registration flag. Corresponding
- * callback is {@link WifiNanSessionListener#onSubscribeTerminated(int)}.
- */
- public static final int LISTEN_SUBSCRIBE_TERMINATED = 0x1 << 3;
-
- /**
- * Match (discovery: publish or subscribe) callback event registration flag.
- * Corresponding callback is
- * {@link WifiNanSessionListener#onMatch(int, byte[], int, byte[], int)}.
- *
- * @hide
- */
- public static final int LISTEN_MATCH = 0x1 << 4;
-
- /**
- * Message sent successfully callback event registration flag. Corresponding
- * callback is {@link WifiNanSessionListener#onMessageSendSuccess()}.
- *
- * @hide
- */
- public static final int LISTEN_MESSAGE_SEND_SUCCESS = 0x1 << 5;
-
- /**
- * Message sending failure callback event registration flag. Corresponding
- * callback is {@link WifiNanSessionListener#onMessageSendFail(int)}.
- *
- * @hide
- */
- public static final int LISTEN_MESSAGE_SEND_FAIL = 0x1 << 6;
-
- /**
- * Message received callback event registration flag. Corresponding callback
- * is {@link WifiNanSessionListener#onMessageReceived(int, byte[], int)}.
- *
- * @hide
- */
- public static final int LISTEN_MESSAGE_RECEIVED = 0x1 << 7;
-
- /**
- * List of hidden events: which are mandatory - i.e. they will be added to
- * every request.
- *
- * @hide
- */
- public static final int LISTEN_HIDDEN_FLAGS = LISTEN_PUBLISH_FAIL | LISTEN_SUBSCRIBE_FAIL
- | LISTEN_MATCH | LISTEN_MESSAGE_SEND_SUCCESS | LISTEN_MESSAGE_SEND_FAIL
- | LISTEN_MESSAGE_RECEIVED;
-
- /**
- * Failure reason flag for {@link WifiNanEventListener} and
- * {@link WifiNanSessionListener} callbacks. Indicates no resources to execute
- * the requested operation.
- */
- public static final int FAIL_REASON_NO_RESOURCES = 0;
-
- /**
- * Failure reason flag for {@link WifiNanEventListener} and
- * {@link WifiNanSessionListener} callbacks. Indicates invalid argument in the
- * requested operation.
- */
- public static final int FAIL_REASON_INVALID_ARGS = 1;
-
- /**
- * Failure reason flag for {@link WifiNanEventListener} and
- * {@link WifiNanSessionListener} callbacks. Indicates a message is transmitted
- * without a match (i.e. a discovery) occurring first.
- */
- public static final int FAIL_REASON_NO_MATCH_SESSION = 2;
-
- /**
- * Failure reason flag for {@link WifiNanEventListener} and
- * {@link WifiNanSessionListener} callbacks. Indicates an unspecified error
- * occurred during the operation.
- */
- public static final int FAIL_REASON_OTHER = 3;
-
- /**
- * Failure reason flag for
- * {@link WifiNanSessionListener#onPublishTerminated(int)} and
- * {@link WifiNanSessionListener#onSubscribeTerminated(int)} callbacks.
- * Indicates that publish or subscribe session is done - i.e. all the
- * requested operations (per {@link PublishSettings} or
- * {@link SubscribeSettings}) have been executed.
- */
- public static final int TERMINATE_REASON_DONE = 0;
-
- /**
- * Failure reason flag for
- * {@link WifiNanSessionListener#onPublishTerminated(int)} and
- * {@link WifiNanSessionListener#onSubscribeTerminated(int)} callbacks.
- * Indicates that publish or subscribe session is terminated due to a
- * failure.
- */
- public static final int TERMINATE_REASON_FAIL = 1;
-
- private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id";
- private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message";
- private static final String MESSAGE_BUNDLE_KEY_MESSAGE2 = "message2";
-
- private final Handler mHandler;
-
- /**
- * Constructs a {@link WifiNanSessionListener} using the looper of the current
- * thread. I.e. all callbacks will be delivered on the current thread.
- */
- public WifiNanSessionListener() {
- this(Looper.myLooper());
- }
-
- /**
- * Constructs a {@link WifiNanSessionListener} using the specified looper. I.e.
- * all callbacks will delivered on the thread of the specified looper.
- *
- * @param looper The looper on which to execute the callbacks.
- */
- public WifiNanSessionListener(Looper looper) {
- if (VDBG) Log.v(TAG, "ctor: looper=" + looper);
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
- switch (msg.what) {
- case LISTEN_PUBLISH_FAIL:
- WifiNanSessionListener.this.onPublishFail(msg.arg1);
- break;
- case LISTEN_PUBLISH_TERMINATED:
- WifiNanSessionListener.this.onPublishTerminated(msg.arg1);
- break;
- case LISTEN_SUBSCRIBE_FAIL:
- WifiNanSessionListener.this.onSubscribeFail(msg.arg1);
- break;
- case LISTEN_SUBSCRIBE_TERMINATED:
- WifiNanSessionListener.this.onSubscribeTerminated(msg.arg1);
- break;
- case LISTEN_MATCH:
- WifiNanSessionListener.this.onMatch(
- msg.getData().getInt(MESSAGE_BUNDLE_KEY_PEER_ID),
- msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1,
- msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2), msg.arg2);
- break;
- case LISTEN_MESSAGE_SEND_SUCCESS:
- WifiNanSessionListener.this.onMessageSendSuccess(msg.arg1);
- break;
- case LISTEN_MESSAGE_SEND_FAIL:
- WifiNanSessionListener.this.onMessageSendFail(msg.arg1, msg.arg2);
- break;
- case LISTEN_MESSAGE_RECEIVED:
- WifiNanSessionListener.this.onMessageReceived(msg.arg2,
- msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1);
- break;
- }
- }
- };
- }
-
- /**
- * Called when a publish operation fails. It is dummy method (empty
- * implementation printing out a log message). Override to implement your
- * custom response.
- *
- * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
- * codes.
- */
- public void onPublishFail(int reason) {
- if (VDBG) Log.v(TAG, "onPublishFail: called in stub - override if interested");
- }
-
- /**
- * Called when a publish operation terminates. Event will only be delivered
- * if registered using {@link WifiNanSessionListener#LISTEN_PUBLISH_TERMINATED}.
- * A dummy (empty implementation printing out a warning). Make sure to
- * override if registered.
- *
- * @param reason The termination reason using
- * {@code NanSessionListener.TERMINATE_*} codes.
- */
- public void onPublishTerminated(int reason) {
- Log.w(TAG, "onPublishTerminated: called in stub - override if interested or disable");
- }
-
- /**
- * Called when a subscribe operation fails. It is dummy method (empty
- * implementation printing out a log message). Override to implement your
- * custom response.
- *
- * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
- * codes.
- */
- public void onSubscribeFail(int reason) {
- if (VDBG) Log.v(TAG, "onSubscribeFail: called in stub - override if interested");
- }
-
- /**
- * Called when a subscribe operation terminates. Event will only be
- * delivered if registered using
- * {@link WifiNanSessionListener#LISTEN_SUBSCRIBE_TERMINATED}. A dummy (empty
- * implementation printing out a warning). Make sure to override if
- * registered.
- *
- * @param reason The termination reason using
- * {@code NanSessionListener.TERMINATE_*} codes.
- */
- public void onSubscribeTerminated(int reason) {
- Log.w(TAG, "onSubscribeTerminated: called in stub - override if interested or disable");
- }
-
- /**
- * Called when a discovery (publish or subscribe) operation results in a
- * match - i.e. when a peer is discovered. It is dummy method (empty
- * implementation printing out a log message). Override to implement your
- * custom response.
- *
- * @param peerId The ID of the peer matching our discovery operation.
- * @param serviceSpecificInfo The service specific information (arbitrary
- * byte array) provided by the peer as part of its discovery
- * packet.
- * @param serviceSpecificInfoLength The length of the service specific
- * information array.
- * @param matchFilter The filter (Tx on advertiser and Rx on listener) which
- * resulted in this match.
- * @param matchFilterLength The length of the match filter array.
- */
- public void onMatch(int peerId, byte[] serviceSpecificInfo,
- int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) {
- if (VDBG) Log.v(TAG, "onMatch: called in stub - override if interested");
- }
-
- /**
- * Called when a message is transmitted successfully - i.e. when we know
- * that it was received successfully (corresponding to an ACK being
- * received). It is dummy method (empty implementation printing out a log
- * message). Override to implement your custom response.
- * <p>
- * Note that either this callback or
- * {@link WifiNanSessionListener#onMessageSendFail(int, int)} will be
- * received - never both.
- */
- public void onMessageSendSuccess(int messageId) {
- if (VDBG) Log.v(TAG, "onMessageSendSuccess: called in stub - override if interested");
- }
-
- /**
- * Called when a message transmission fails - i.e. when no ACK is received.
- * The hardware will usually attempt to re-transmit several times - this
- * event is received after all retries are exhausted. There is a possibility
- * that message was received by the destination successfully but the ACK was
- * lost. It is dummy method (empty implementation printing out a log
- * message). Override to implement your custom response.
- * <p>
- * Note that either this callback or
- * {@link WifiNanSessionListener#onMessageSendSuccess(int)} will be received
- * - never both
- *
- * @param reason The failure reason using {@code NanSessionListener.FAIL_*}
- * codes.
- */
- public void onMessageSendFail(int messageId, int reason) {
- if (VDBG) Log.v(TAG, "onMessageSendFail: called in stub - override if interested");
- }
-
- /**
- * Called when a message is received from a discovery session peer. It is
- * dummy method (empty implementation printing out a log message). Override
- * to implement your custom response.
- *
- * @param peerId The ID of the peer sending the message.
- * @param message A byte array containing the message.
- * @param messageLength The length of the byte array containing the relevant
- * message bytes.
- */
- public void onMessageReceived(int peerId, byte[] message, int messageLength) {
- if (VDBG) Log.v(TAG, "onMessageReceived: called in stub - override if interested");
- }
-
- /**
- * {@hide}
- */
- public IWifiNanSessionListener callback = new IWifiNanSessionListener.Stub() {
- @Override
- public void onPublishFail(int reason) {
- if (VDBG) Log.v(TAG, "onPublishFail: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(LISTEN_PUBLISH_FAIL);
- msg.arg1 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onPublishTerminated(int reason) {
- if (VDBG) Log.v(TAG, "onPublishResponse: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(LISTEN_PUBLISH_TERMINATED);
- msg.arg1 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onSubscribeFail(int reason) {
- if (VDBG) Log.v(TAG, "onSubscribeFail: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(LISTEN_SUBSCRIBE_FAIL);
- msg.arg1 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onSubscribeTerminated(int reason) {
- if (VDBG) Log.v(TAG, "onSubscribeTerminated: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(LISTEN_SUBSCRIBE_TERMINATED);
- msg.arg1 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onMatch(int peerId, byte[] serviceSpecificInfo,
- int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) {
- if (VDBG) Log.v(TAG, "onMatch: peerId=" + peerId);
-
- Bundle data = new Bundle();
- data.putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId);
- data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, serviceSpecificInfo);
- data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2, matchFilter);
-
- Message msg = mHandler.obtainMessage(LISTEN_MATCH);
- msg.arg1 = serviceSpecificInfoLength;
- msg.arg2 = matchFilterLength;
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onMessageSendSuccess(int messageId) {
- if (VDBG) Log.v(TAG, "onMessageSendSuccess");
-
- Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_SEND_SUCCESS);
- msg.arg1 = messageId;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onMessageSendFail(int messageId, int reason) {
- if (VDBG) Log.v(TAG, "onMessageSendFail: reason=" + reason);
-
- Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_SEND_FAIL);
- msg.arg1 = messageId;
- msg.arg2 = reason;
- mHandler.sendMessage(msg);
- }
-
- @Override
- public void onMessageReceived(int peerId, byte[] message, int messageLength) {
- if (VDBG) {
- Log.v(TAG, "onMessageReceived: peerId='" + peerId + "', messageLength="
- + messageLength);
- }
-
- Bundle data = new Bundle();
- data.putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message);
-
- Message msg = mHandler.obtainMessage(LISTEN_MESSAGE_RECEIVED);
- msg.arg1 = messageLength;
- msg.arg2 = peerId;
- msg.setData(data);
- mHandler.sendMessage(msg);
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java b/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java
index 7dfdd32a2f74..2e6d7695fb44 100644
--- a/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java
+++ b/wifi/java/android/net/wifi/nan/WifiNanSubscribeSession.java
@@ -16,15 +16,20 @@
package android.net.wifi.nan;
+import android.annotation.NonNull;
+import android.util.Log;
+
/**
* A representation of a NAN subscribe session. Created when
- * {@link WifiNanManager#subscribe(SubscribeData, SubscribeSettings, WifiNanSessionListener, int)}
- * is executed. The object can be used to stop and re-start (re-configure) the
+ * {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} is
+ * executed. The object can be used to stop and re-start (re-configure) the
* subscribe session.
*
* @hide PROPOSED_NAN_API
*/
public class WifiNanSubscribeSession extends WifiNanSession {
+ private static final String TAG = "WifiNanSubscribeSession";
+
/**
* {@hide}
*/
@@ -33,15 +38,25 @@ public class WifiNanSubscribeSession extends WifiNanSession {
}
/**
- * Restart/re-configure the subscribe session. Note that the
- * {@link WifiNanSessionListener} is not replaced - the same listener used at
- * creation is still used.
+ * Re-configure the subscribe session. Note that the
+ * {@link WifiNanSessionCallback} is not replaced - the same listener used
+ * at creation is still used.
*
- * @param subscribeData The data ({@link SubscribeData}) to subscribe.
- * @param subscribeSettings The settings ({@link SubscribeSettings}) of the
+ * @param subscribeConfig The configuration ({@link SubscribeConfig}) of the
* subscribe session.
*/
- public void subscribe(SubscribeData subscribeData, SubscribeSettings subscribeSettings) {
- mManager.subscribe(mSessionId, subscribeData, subscribeSettings);
+ public void updateSubscribe(@NonNull SubscribeConfig subscribeConfig) {
+ if (mTerminated) {
+ Log.w(TAG, "updateSubscribe: called on terminated session");
+ return;
+ } else {
+ WifiNanManager mgr = mMgr.get();
+ if (mgr == null) {
+ Log.w(TAG, "updateSubscribe: called post GC on WifiNanManager");
+ return;
+ }
+
+ mgr.updateSubscribe(mSessionId, subscribeConfig);
+ }
}
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index a0cb035fb4d5..a68bcd98cac5 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -66,19 +66,28 @@ public class WifiP2pDevice implements Parcelable {
/* Device Capability bitmap */
private static final int DEVICE_CAPAB_SERVICE_DISCOVERY = 1;
+ @SuppressWarnings("unused")
private static final int DEVICE_CAPAB_CLIENT_DISCOVERABILITY = 1<<1;
+ @SuppressWarnings("unused")
private static final int DEVICE_CAPAB_CONCURRENT_OPER = 1<<2;
+ @SuppressWarnings("unused")
private static final int DEVICE_CAPAB_INFRA_MANAGED = 1<<3;
+ @SuppressWarnings("unused")
private static final int DEVICE_CAPAB_DEVICE_LIMIT = 1<<4;
private static final int DEVICE_CAPAB_INVITATION_PROCEDURE = 1<<5;
/* Group Capability bitmap */
private static final int GROUP_CAPAB_GROUP_OWNER = 1;
+ @SuppressWarnings("unused")
private static final int GROUP_CAPAB_PERSISTENT_GROUP = 1<<1;
private static final int GROUP_CAPAB_GROUP_LIMIT = 1<<2;
+ @SuppressWarnings("unused")
private static final int GROUP_CAPAB_INTRA_BSS_DIST = 1<<3;
+ @SuppressWarnings("unused")
private static final int GROUP_CAPAB_CROSS_CONN = 1<<4;
+ @SuppressWarnings("unused")
private static final int GROUP_CAPAB_PERSISTENT_RECONN = 1<<5;
+ @SuppressWarnings("unused")
private static final int GROUP_CAPAB_GROUP_FORMATION = 1<<6;
/**
@@ -305,6 +314,7 @@ public class WifiP2pDevice implements Parcelable {
return other.deviceAddress.equals(deviceAddress);
}
+ @Override
public String toString() {
StringBuffer sbuf = new StringBuffer();
sbuf.append("Device: ").append(deviceName);
@@ -320,6 +330,7 @@ public class WifiP2pDevice implements Parcelable {
}
/** Implement the Parcelable interface */
+ @Override
public int describeContents() {
return 0;
}
@@ -340,6 +351,7 @@ public class WifiP2pDevice implements Parcelable {
}
/** Implement the Parcelable interface */
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(deviceName);
dest.writeString(deviceAddress);
@@ -360,6 +372,7 @@ public class WifiP2pDevice implements Parcelable {
/** Implement the Parcelable interface */
public static final Creator<WifiP2pDevice> CREATOR =
new Creator<WifiP2pDevice>() {
+ @Override
public WifiP2pDevice createFromParcel(Parcel in) {
WifiP2pDevice device = new WifiP2pDevice();
device.deviceName = in.readString();
@@ -376,6 +389,7 @@ public class WifiP2pDevice implements Parcelable {
return device;
}
+ @Override
public WifiP2pDevice[] newArray(int size) {
return new WifiP2pDevice[size];
}