Merge "[NAN] Re-factor connect/config flow" into mm-wireless-dev

This commit is contained in:
Etan Cohen
2016-04-08 15:00:12 +00:00
committed by Android Partner Code Review
12 changed files with 624 additions and 263 deletions

View File

@@ -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
*/
@@ -146,6 +147,30 @@ public class ConfigRequest implements Parcelable {
&& 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;
}
@Override
public int hashCode() {
int result = 17;
@@ -159,6 +184,39 @@ public class ConfigRequest implements Parcelable {
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.
*/
@@ -175,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;
@@ -188,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) {
@@ -214,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) {
@@ -238,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) {

View File

@@ -25,8 +25,8 @@ import android.net.wifi.nan.ConfigRequest;
*/
oneway interface IWifiNanEventCallback
{
void onConfigCompleted(in ConfigRequest completedConfig);
void onConfigFailed(in ConfigRequest failedConfig, int reason);
void onConnectSuccess();
void onConnectFail(int reason);
void onNanDown(int reason);
void onIdentityChanged();
}

View File

@@ -32,9 +32,9 @@ import android.net.wifi.nan.SubscribeConfig;
interface IWifiNanManager
{
// client API
int connect(in IBinder binder, in IWifiNanEventCallback callback);
int connect(in IBinder binder, in IWifiNanEventCallback callback,
in ConfigRequest configRequest);
void disconnect(int clientId, in IBinder binder);
void requestConfig(int clientId, in ConfigRequest configRequest);
void publish(int clientId, in PublishConfig publishConfig, in IWifiNanSessionCallback callback);
void subscribe(int clientId, in SubscribeConfig subscribeConfig,

View File

@@ -24,6 +24,7 @@ package android.net.wifi.nan;
oneway interface IWifiNanSessionCallback
{
void onSessionStarted(int sessionId);
void onSessionConfigSuccess();
void onSessionConfigFail(int reason);
void onSessionTerminated(int reason);

View File

@@ -24,8 +24,8 @@ import java.util.Arrays;
/**
* Defines the configuration of a NAN publish session. Built using
* {@link PublishConfig.Builder}. Publish is done using
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback, int)} or
* {@link WifiNanPublishSession#publish(PublishConfig)}.
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} or
* {@link WifiNanPublishSession#updatePublish(PublishConfig)}.
*
* @hide PROPOSED_NAN_API
*/
@@ -264,6 +264,45 @@ public class PublishConfig implements Parcelable {
return result;
}
/**
* 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.
*/
@@ -417,7 +456,7 @@ public class PublishConfig implements Parcelable {
* 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#onPublishTerminated(int)}
* generated for {@link WifiNanSessionCallback#onSessionTerminated(int)}
* with reason={@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
*
* @param publishCount Number of publish packets to transmit.
@@ -437,7 +476,7 @@ public class PublishConfig implements Parcelable {
* {@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#onPublishTerminated(int)} with reason=
* {@link WifiNanSessionCallback#onSessionTerminated(int)} with reason=
* {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
*
* @param ttlSec Lifetime of a publish session in seconds.
@@ -454,7 +493,7 @@ public class PublishConfig implements Parcelable {
/**
* Configure whether a publish terminate notification
* {@link WifiNanSessionCallback#onPublishTerminated(int)} is reported
* {@link WifiNanSessionCallback#onSessionTerminated(int)} is reported
* back to the callback.
*
* @param enable If true the terminate callback will be called when the

View File

@@ -25,7 +25,7 @@ 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#subscribe(SubscribeConfig)}.
* {@link WifiNanSubscribeSession#updateSubscribe(SubscribeConfig)}.
*
* @hide PROPOSED_NAN_API
*/
@@ -286,6 +286,49 @@ public class SubscribeConfig implements Parcelable {
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.
*/
@@ -332,6 +375,11 @@ public class SubscribeConfig implements Parcelable {
*/
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;
@@ -374,6 +422,10 @@ public class SubscribeConfig implements Parcelable {
* {@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;
@@ -397,6 +449,10 @@ public class SubscribeConfig implements Parcelable {
* {@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;
@@ -427,8 +483,8 @@ public class SubscribeConfig implements Parcelable {
* {@link SubscribeConfig.Builder#setSubscribeType(int)}) subscribe
* session will transmit a packet. When the count is reached an event
* will be generated for
* {@link WifiNanSessionCallback#onSubscribeTerminated(int)} with
* reason= {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
* {@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
@@ -447,8 +503,8 @@ public class SubscribeConfig implements Parcelable {
* {@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#onSubscribeTerminated(int)} with
* reason= {@link WifiNanSessionCallback#TERMINATE_REASON_DONE}.
* {@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
@@ -486,7 +542,7 @@ public class SubscribeConfig implements Parcelable {
/**
* Configure whether a subscribe terminate notification
* {@link WifiNanSessionCallback#onSubscribeTerminated(int)} is reported
* {@link WifiNanSessionCallback#onSessionTerminated(int)} is reported
* back to the callback.
*
* @param enable If true the terminate callback will be called when the

View File

@@ -16,6 +16,11 @@
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
@@ -25,25 +30,59 @@ package android.net.wifi.nan;
* @hide PROPOSED_NAN_API
*/
public class WifiNanEventCallback {
@IntDef({
REASON_INVALID_ARGS, REASON_ALREADY_CONNECTED_INCOMPAT_CONFIG, REASON_REQUESTED,
REASON_OTHER })
@Retention(RetentionPolicy.SOURCE)
public @interface EventReasonCodes {
}
/**
* Called when NAN configuration is completed.
*
* @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.
* Failure reason flag for {@link WifiNanEventCallback} callbacks. Indicates
* invalid argument in the requested operation.
*/
public void onConfigCompleted(ConfigRequest completedConfig) {
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;
/**
* Reason flag for {@link WifiNanEventCallback#onNanDown(int)} callback.
* Indicates NAN is shut-down per user request.
*/
public static final int REASON_REQUESTED = 1002;
/**
* 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 configuration failed.
* Called when NAN connect operation
* {@code WifiNanManager#connect(android.os.Looper, WifiNanEventCallback)}
* failed.
*
* @param reason Failure reason code, see
* {@code WifiNanSessionCallback.FAIL_*}.
* {@code WifiNanEventCallback.REASON_*}.
*/
public void onConfigFailed(@SuppressWarnings("unused") ConfigRequest failedConfig, int reason) {
public void onConnectFail(@EventReasonCodes int reason) {
/* empty */
}
@@ -51,9 +90,9 @@ public class WifiNanEventCallback {
* Called when NAN cluster is down
*
* @param reason Reason code for event, see
* {@code WifiNanSessionCallback.FAIL_*}.
* {@code WifiNanEventCallback.REASON_*}.
*/
public void onNanDown(int reason) {
public void onNanDown(@EventReasonCodes int reason) {
/* empty */
}

View File

@@ -25,6 +25,10 @@ import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import java.lang.ref.WeakReference;
/**
* This class provides the primary API for managing Wi-Fi NAN operation:
* including discovery and data-links. Get an instance of this class by calling
@@ -45,9 +49,31 @@ public class WifiNanManager {
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
private final IWifiNanManager mService;
/*
* State transitions:
* UNCONNECTED -- (connect()) --> CONNECTING -- (onConnectSuccess()) --> CONNECTED
* UNCONNECTED -- (connect()) --> CONNECTING -- (onConnectFail()) --> UNCONNECTED
* CONNECTED||CONNECTING -- (disconnect()) --> UNCONNECTED
* CONNECTED||CONNECTING -- onNanDown() --> UNCONNECTED
*/
private static final int STATE_UNCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
private Object mLock = new Object(); // lock access to the following vars
@GuardedBy("mLock")
private int mState = STATE_UNCONNECTED;
@GuardedBy("mLock")
private IBinder mBinder;
private int mClientId = -1;
private IWifiNanManager mService;
@GuardedBy("mLock")
private int mClientId;
@GuardedBy("mLock")
private Looper mLooper;
/**
@@ -58,7 +84,7 @@ public class WifiNanManager {
}
/**
* Re-connect to the Wi-Fi NAN service - enabling the application to execute
* Connect to the Wi-Fi NAN service - enabling the application to execute
* {@link WifiNanManager} APIs.
*
* @param looper The Looper on which to execute all callbacks related to the
@@ -67,25 +93,45 @@ public class WifiNanManager {
* @param callback A callback extended from {@link WifiNanEventCallback}.
*/
public void connect(Looper looper, WifiNanEventCallback callback) {
if (VDBG) Log.v(TAG, "connect()");
connect(looper, callback, null);
}
if (callback == null) {
throw new IllegalArgumentException("Invalid callback - must not be null");
/**
* 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.
*
* @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 void connect(Looper looper, WifiNanEventCallback callback, ConfigRequest configRequest) {
if (VDBG) {
Log.v(TAG, "connect(): looper=" + looper + ", callback=" + callback + ", configRequest="
+ configRequest);
}
if (mClientId != -1) {
Log.e(TAG, "connect(): mClientId=" + mClientId
+ ": seems to calling connect() without disconnecting() first!");
throw new IllegalStateException("Calling connect() without disconnecting() first!");
}
synchronized (mLock) {
if (mState != STATE_UNCONNECTED) {
Log.e(TAG, "connect(): Calling connect() when state != UNCONNECTED!");
return;
}
mLooper = looper;
mBinder = new Binder();
mLooper = looper;
mBinder = new Binder();
mState = STATE_CONNECTING;
try {
mClientId = mService.connect(mBinder, new WifiNanEventCallbackProxy(mLooper, callback));
} catch (RemoteException e) {
Log.w(TAG, "connect RemoteException (FYI - ignoring): " + e);
try {
mClientId = mService.connect(mBinder,
new WifiNanEventCallbackProxy(this, looper, callback), configRequest);
} catch (RemoteException e) {
mLooper = null;
mBinder = null;
mState = STATE_UNCONNECTED;
e.rethrowAsRuntimeException();
}
}
}
@@ -99,61 +145,39 @@ public class WifiNanManager {
* {@link WifiNanManager#connect(Looper, WifiNanEventCallback)} .
*/
public void disconnect() {
if (mClientId == -1) {
/*
* Warning only since could be called multiple times as cleaning-up
* (and no damage done).
*/
Log.w(TAG, "disconnect(): called without calling connect() first - or called "
+ "multiple times.");
return;
}
try {
if (VDBG) Log.v(TAG, "disconnect()");
mService.disconnect(mClientId, mBinder);
if (VDBG) Log.v(TAG, "disconnect()");
IBinder binder;
int clientId;
synchronized (mLock) {
if (mState == STATE_UNCONNECTED) {
Log.e(TAG, "disconnect(): called while UNCONNECTED - ignored");
return;
}
binder = mBinder;
clientId = mClientId;
mState = STATE_UNCONNECTED;
mBinder = null;
mClientId = -1;
mLooper = null;
mClientId = 0;
}
try {
mService.disconnect(clientId, binder);
} catch (RemoteException e) {
Log.w(TAG, "disconnect RemoteException (FYI - ignoring): " + e);
e.rethrowAsRuntimeException();
}
}
@Override
protected void finalize() throws Throwable {
if (mBinder != null) {
if (DBG) Log.d(TAG, "finalize: disconnect() not called - executing now");
if (mState != STATE_UNCONNECTED) {
disconnect();
}
}
/**
* 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 WifiNanEventCallback#onConfigCompleted(ConfigRequest)} will be
* called when configuration is completed (if a callback is registered for
* this specific event).
*
* @param configRequest The requested NAN configuration.
*/
public void requestConfig(ConfigRequest configRequest) {
if (VDBG) Log.v(TAG, "requestConfig(): configRequest=" + configRequest);
if (mClientId == -1) {
Log.e(TAG, "requestConfig(): called without an initial connect()!");
throw new IllegalStateException("Calling requestConfig() without a connect() first!");
}
try {
mService.requestConfig(mClientId, configRequest);
} catch (RemoteException e) {
Log.w(TAG, "requestConfig RemoteException (FYI - ignoring): " + e);
}
}
/**
* Request a NAN publish session. The actual publish session is provided by
* the
@@ -170,30 +194,22 @@ public class WifiNanManager {
public void publish(PublishConfig publishConfig, WifiNanSessionCallback callback) {
if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig);
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
&& publishConfig.mRxFilterLength != 0) {
throw new IllegalArgumentException("Invalid publish config: UNSOLICITED "
+ "publishes (active) can't have an Rx filter");
}
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_SOLICITED
&& publishConfig.mTxFilterLength != 0) {
throw new IllegalArgumentException("Invalid publish config: SOLICITED "
+ "publishes (passive) can't have a Tx filter");
}
if (callback == null) {
throw new IllegalArgumentException("Invalid callback - must not be null");
}
int clientId;
Looper looper;
synchronized (mLock) {
if (mState != STATE_CONNECTED) {
Log.e(TAG, "publish(): called when not CONNECTED!");
return;
}
if (mClientId == -1) {
Log.e(TAG, "publish(): called without an initial connect()!");
throw new IllegalStateException("Calling publish() without a connect() first!");
clientId = mClientId;
looper = mLooper;
}
try {
mService.publish(mClientId, publishConfig,
new WifiNanSessionCallbackProxy(mLooper, true, callback));
mService.publish(clientId, publishConfig,
new WifiNanSessionCallbackProxy(this, looper, true, callback));
} catch (RemoteException e) {
Log.w(TAG, "publish RemoteException: " + e);
e.rethrowAsRuntimeException();
}
}
@@ -203,21 +219,19 @@ public class WifiNanManager {
public void updatePublish(int sessionId, PublishConfig publishConfig) {
if (VDBG) Log.v(TAG, "updatePublish(): config=" + publishConfig);
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
&& publishConfig.mRxFilterLength != 0) {
throw new IllegalArgumentException("Invalid publish config: UNSOLICITED "
+ "publishes (active) can't have an Rx filter");
}
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_SOLICITED
&& publishConfig.mTxFilterLength != 0) {
throw new IllegalArgumentException("Invalid publish config: SOLICITED "
+ "publishes (passive) can't have a Tx filter");
}
int clientId;
synchronized (mLock) {
if (mState != STATE_CONNECTED) {
Log.e(TAG, "updatePublish(): called when not CONNECTED)!");
return;
}
clientId = mClientId;
}
try {
mService.updatePublish(mClientId, sessionId, publishConfig);
mService.updatePublish(clientId, sessionId, publishConfig);
} catch (RemoteException e) {
Log.w(TAG, "updatePublish RemoteException: " + e);
e.rethrowAsRuntimeException();
}
}
@@ -239,27 +253,23 @@ public class WifiNanManager {
Log.v(TAG, "subscribe(): config=" + subscribeConfig);
}
if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
&& subscribeConfig.mRxFilterLength != 0) {
throw new IllegalArgumentException(
"Invalid subscribe config: ACTIVE subscribes can't have an Rx filter");
}
if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE
&& subscribeConfig.mTxFilterLength != 0) {
throw new IllegalArgumentException(
"Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
}
int clientId;
Looper looper;
synchronized (mLock) {
if (mState != STATE_CONNECTED) {
Log.e(TAG, "subscribe(): called when not CONNECTED!");
return;
}
if (mClientId == -1) {
Log.e(TAG, "subscribe(): called without an initial connect()!");
throw new IllegalStateException("Calling subscribe() without a connect() first!");
clientId = mClientId;
looper = mLooper;
}
try {
mService.subscribe(mClientId, subscribeConfig,
new WifiNanSessionCallbackProxy(mLooper, false, callback));
mService.subscribe(clientId, subscribeConfig,
new WifiNanSessionCallbackProxy(this, looper, false, callback));
} catch (RemoteException e) {
Log.w(TAG, "subscribe RemoteException: " + e);
e.rethrowAsRuntimeException();
}
}
@@ -271,21 +281,20 @@ public class WifiNanManager {
Log.v(TAG, "subscribe(): config=" + subscribeConfig);
}
if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
&& subscribeConfig.mRxFilterLength != 0) {
throw new IllegalArgumentException(
"Invalid subscribe config: ACTIVE subscribes can't have an Rx filter");
}
if (subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE
&& subscribeConfig.mTxFilterLength != 0) {
throw new IllegalArgumentException(
"Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
int clientId;
synchronized (mLock) {
if (mState != STATE_CONNECTED) {
Log.e(TAG, "updateSubscribe(): called when not CONNECTED!");
return;
}
clientId = mClientId;
}
try {
mService.updateSubscribe(mClientId, sessionId, subscribeConfig);
mService.updateSubscribe(clientId, sessionId, subscribeConfig);
} catch (RemoteException e) {
Log.w(TAG, "updateSubscribe RemoteException: " + e);
e.rethrowAsRuntimeException();
}
}
@@ -295,10 +304,20 @@ public class WifiNanManager {
public void terminateSession(int sessionId) {
if (DBG) Log.d(TAG, "Terminate NAN session #" + sessionId);
int clientId;
synchronized (mLock) {
if (mState != STATE_CONNECTED) {
Log.e(TAG, "terminateSession(): called when not CONNECTED!");
return;
}
clientId = mClientId;
}
try {
mService.terminateSession(mClientId, sessionId);
mService.terminateSession(clientId, sessionId);
} catch (RemoteException e) {
Log.w(TAG, "terminateSession RemoteException (FYI - ignoring): " + e);
e.rethrowAsRuntimeException();
}
}
@@ -307,24 +326,34 @@ public class WifiNanManager {
*/
public void sendMessage(int sessionId, int peerId, byte[] message, int messageLength,
int messageId) {
try {
if (VDBG) {
Log.v(TAG, "sendMessage(): sessionId=" + sessionId + ", peerId=" + peerId
+ ", messageLength=" + messageLength + ", messageId=" + messageId);
if (VDBG) {
Log.v(TAG, "sendMessage(): sessionId=" + sessionId + ", peerId=" + peerId
+ ", messageLength=" + messageLength + ", messageId=" + messageId);
}
int clientId;
synchronized (mLock) {
if (mState != STATE_CONNECTED) {
Log.e(TAG, "sendMessage(): called when not CONNECTED!");
return;
}
mService.sendMessage(mClientId, sessionId, peerId, message, messageLength, messageId);
clientId = mClientId;
}
try {
mService.sendMessage(clientId, sessionId, peerId, message, messageLength, messageId);
} catch (RemoteException e) {
Log.w(TAG, "subscribe RemoteException (FYI - ignoring): " + e);
e.rethrowAsRuntimeException();
}
}
private static class WifiNanEventCallbackProxy extends IWifiNanEventCallback.Stub {
private static final int CALLBACK_CONFIG_COMPLETED = 0;
private static final int CALLBACK_CONFIG_FAILED = 1;
private static final int CALLBACK_CONNECT_SUCCESS = 0;
private static final int CALLBACK_CONNECT_FAIL = 1;
private static final int CALLBACK_NAN_DOWN = 2;
private static final int CALLBACK_IDENTITY_CHANGED = 3;
private final WifiNanEventCallback mOriginalCallback;
private final Handler mHandler;
/**
@@ -333,26 +362,64 @@ public class WifiNanManager {
*
* @param looper The looper on which to execute the callbacks.
*/
WifiNanEventCallbackProxy(Looper looper, WifiNanEventCallback originalCallback) {
mOriginalCallback = originalCallback;
WifiNanEventCallbackProxy(WifiNanManager mgr, Looper looper,
final WifiNanEventCallback originalCallback) {
final WeakReference<WifiNanManager> nanManager = new WeakReference<WifiNanManager>(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, "What=" + msg.what + ", msg=" + msg);
if (DBG) {
Log.d(TAG, "WifiNanEventCallbackProxy: What=" + msg.what + ", msg=" + msg);
}
WifiNanManager mgr = nanManager.get();
if (mgr == null) {
Log.w(TAG, "WifiNanEventCallbackProxy: handleMessage post GC");
return;
}
switch (msg.what) {
case CALLBACK_CONFIG_COMPLETED:
mOriginalCallback.onConfigCompleted((ConfigRequest) msg.obj);
case CALLBACK_CONNECT_SUCCESS:
synchronized (mgr.mLock) {
if (mgr.mState != STATE_CONNECTING) {
Log.w(TAG, "onConnectSuccess indication received but not in "
+ "CONNECTING state. Ignoring.");
return;
}
mgr.mState = STATE_CONNECTED;
}
originalCallback.onConnectSuccess();
break;
case CALLBACK_CONFIG_FAILED:
mOriginalCallback.onConfigFailed((ConfigRequest) msg.obj, msg.arg1);
case CALLBACK_CONNECT_FAIL:
synchronized (mgr.mLock) {
if (mgr.mState != STATE_CONNECTING) {
Log.w(TAG, "onConnectFail indication received but not in "
+ "CONNECTING state. Ignoring.");
return;
}
mgr.mState = STATE_UNCONNECTED;
mgr.mBinder = null;
mgr.mLooper = null;
mgr.mClientId = 0;
}
nanManager.clear();
originalCallback.onConnectFail(msg.arg1);
break;
case CALLBACK_NAN_DOWN:
mOriginalCallback.onNanDown(msg.arg1);
synchronized (mgr.mLock) {
mgr.mState = STATE_UNCONNECTED;
mgr.mBinder = null;
mgr.mLooper = null;
mgr.mClientId = 0;
}
nanManager.clear();
originalCallback.onNanDown(msg.arg1);
break;
case CALLBACK_IDENTITY_CHANGED:
mOriginalCallback.onIdentityChanged();
originalCallback.onIdentityChanged();
break;
}
}
@@ -360,24 +427,19 @@ public class WifiNanManager {
}
@Override
public void onConfigCompleted(ConfigRequest completedConfig) {
if (VDBG) Log.v(TAG, "onConfigCompleted: configRequest=" + completedConfig);
public void onConnectSuccess() {
if (VDBG) Log.v(TAG, "onConnectSuccess");
Message msg = mHandler.obtainMessage(CALLBACK_CONFIG_COMPLETED);
msg.obj = completedConfig;
Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_SUCCESS);
mHandler.sendMessage(msg);
}
@Override
public void onConfigFailed(ConfigRequest failedConfig, int reason) {
if (VDBG) {
Log.v(TAG,
"onConfigFailed: failedConfig=" + failedConfig + ", reason=" + reason);
}
public void onConnectFail(int reason) {
if (VDBG) Log.v(TAG, "onConfigFailed: reason=" + reason);
Message msg = mHandler.obtainMessage(CALLBACK_CONFIG_FAILED);
Message msg = mHandler.obtainMessage(CALLBACK_CONNECT_FAIL);
msg.arg1 = reason;
msg.obj = failedConfig;
mHandler.sendMessage(msg);
}
@@ -399,27 +461,30 @@ public class WifiNanManager {
}
}
private class WifiNanSessionCallbackProxy extends IWifiNanSessionCallback.Stub {
private static class WifiNanSessionCallbackProxy extends IWifiNanSessionCallback.Stub {
private static final int CALLBACK_SESSION_STARTED = 0;
private static final int CALLBACK_SESSION_CONFIG_FAIL = 1;
private static final int CALLBACK_SESSION_TERMINATED = 2;
private static final int CALLBACK_MATCH = 3;
private static final int CALLBACK_MESSAGE_SEND_SUCCESS = 4;
private static final int CALLBACK_MESSAGE_SEND_FAIL = 5;
private static final int CALLBACK_MESSAGE_RECEIVED = 6;
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(Looper looper, boolean isPublish,
WifiNanSessionCallbackProxy(WifiNanManager mgr, Looper looper, boolean isPublish,
WifiNanSessionCallback originalCallback) {
mNanManager = new WeakReference<>(mgr);
mIsPublish = isPublish;
mOriginalCallback = originalCallback;
@@ -429,12 +494,28 @@ public class WifiNanManager {
@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:
onProxySessionConfigFail(msg.arg1);
mOriginalCallback.onSessionConfigFail(msg.arg1);
if (mSession == null) {
/*
* creation failed (as opposed to update
* failing)
*/
mNanManager.clear();
}
break;
case CALLBACK_SESSION_TERMINATED:
onProxySessionTerminated(msg.arg1);
@@ -472,6 +553,14 @@ public class WifiNanManager {
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);
@@ -554,32 +643,34 @@ public class WifiNanManager {
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(WifiNanManager.this,
sessionId, mOriginalCallback);
WifiNanPublishSession session = new WifiNanPublishSession(mgr, sessionId);
mSession = session;
mOriginalCallback.onPublishStarted(session);
} else {
WifiNanSubscribeSession session = new WifiNanSubscribeSession(WifiNanManager.this,
sessionId, mOriginalCallback);
WifiNanSubscribeSession session = new WifiNanSubscribeSession(mgr, sessionId);
mSession = session;
mOriginalCallback.onSubscribeStarted(session);
}
}
public void onProxySessionConfigFail(int reason) {
if (VDBG) Log.v(TAG, "Proxy: onSessionConfigFail: reason=" + reason);
mOriginalCallback.onSessionConfigFail(reason);
}
public void onProxySessionTerminated(int reason) {
if (VDBG) Log.v(TAG, "Proxy: onSessionTerminated: reason=" + reason);
mOriginalCallback.onSessionTerminated(reason);
if (mSession != null) {
mSession.terminate();
mSession.setTerminated();
mSession = null;
} else {
Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
}
mNanManager.clear();
mOriginalCallback.onSessionTerminated(reason);
}
}
}

View File

@@ -16,6 +16,8 @@
package android.net.wifi.nan;
import android.util.Log;
/**
* A representation of a NAN publish session. Created when
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} is
@@ -25,12 +27,13 @@ package android.net.wifi.nan;
* @hide PROPOSED_NAN_API
*/
public class WifiNanPublishSession extends WifiNanSession {
private static final String TAG = "WifiNanPublishSession";
/**
* {@hide}
*/
public WifiNanPublishSession(WifiNanManager manager, int sessionId,
WifiNanSessionCallback callback) {
super(manager, sessionId, callback);
public WifiNanPublishSession(WifiNanManager manager, int sessionId) {
super(manager, sessionId);
}
/**
@@ -43,10 +46,16 @@ public class WifiNanPublishSession extends WifiNanSession {
*/
public void updatePublish(PublishConfig publishConfig) {
if (mTerminated) {
mCallback.onSessionConfigFail(WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
Log.w(TAG, "updatePublish: called on terminated session");
return;
} else {
mManager.updatePublish(mSessionId, publishConfig);
WifiNanManager mgr = mMgr.get();
if (mgr == null) {
Log.w(TAG, "updatePublish: called post GC on WifiNanManager");
return;
}
mgr.updatePublish(mSessionId, publishConfig);
}
}
}

View File

@@ -18,6 +18,8 @@ package android.net.wifi.nan;
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,22 +32,29 @@ public class WifiNanSession {
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
protected WifiNanManager mManager;
protected final int mSessionId;
protected final WifiNanSessionCallback mCallback;
/**
* @hide
*/
protected WeakReference<WifiNanManager> mMgr;
/**
* @hide
*/
protected final int mSessionId;
/**
* @hide
*/
protected boolean mTerminated = false;
/**
* {@hide}
*/
public WifiNanSession(WifiNanManager manager, int sessionId,
WifiNanSessionCallback callback) {
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;
mCallback = callback;
}
/**
@@ -55,9 +64,29 @@ public class WifiNanSession {
* additional operations are termination.
*/
public void terminate() {
mManager.terminateSession(mSessionId);
WifiNanManager mgr = mMgr.get();
if (mgr == null) {
Log.w(TAG, "terminate: called post GC on WifiNanManager");
return;
}
mgr.terminateSession(mSessionId);
mTerminated = true;
mManager = null;
mMgr.clear();
}
/**
* Sets the status of the session to terminated - i.e. an indication that
* already terminated rather than executing a termination.
*
* @hide
*/
public void setTerminated() {
if (mTerminated) {
Log.w(TAG, "terminate: already terminated.");
return;
}
mTerminated = true;
mMgr.clear();
}
@Override
@@ -66,8 +95,8 @@ public class WifiNanSession {
Log.w(TAG, "WifiNanSession mSessionId=" + mSessionId
+ " was not explicitly terminated. The session may use resources until "
+ "terminated so step should be done explicitly");
terminate();
}
terminate();
}
/**
@@ -89,11 +118,16 @@ public class WifiNanSession {
*/
public void sendMessage(int peerId, byte[] message, int messageLength, int messageId) {
if (mTerminated) {
mCallback.onMessageSendFail(messageId,
WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
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;
}
mManager.sendMessage(mSessionId, peerId, message, messageLength, messageId);
mgr.sendMessage(mSessionId, peerId, message, messageLength, messageId);
}
}
}

View File

@@ -16,57 +16,70 @@
package android.net.wifi.nan;
import android.annotation.IntDef;
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. Events corresponding
* to the NAN link are delivered using {@link WifiNanEventCallback}.
* 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 {
/**
* Failure reason flag for {@link WifiNanEventCallback} and
* {@link WifiNanSessionCallback} callbacks. Indicates no resources to
* execute the requested operation.
*/
public static final int FAIL_REASON_NO_RESOURCES = 0;
@IntDef({
REASON_NO_RESOURCES, REASON_INVALID_ARGS, REASON_NO_MATCH_SESSION,
REASON_TX_FAIL, REASON_OTHER })
@Retention(RetentionPolicy.SOURCE)
public @interface SessionReasonCodes {
}
/**
* Failure reason flag for {@link WifiNanEventCallback} and
* {@link WifiNanSessionCallback} callbacks. Indicates invalid argument in
* the requested operation.
*/
public static final int FAIL_REASON_INVALID_ARGS = 1;
/**
* Failure reason flag for {@link WifiNanEventCallback} and
* {@link WifiNanSessionCallback} 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;
@IntDef({
TERMINATE_REASON_DONE, TERMINATE_REASON_FAIL })
@Retention(RetentionPolicy.SOURCE)
public @interface SessionTerminateCodes {
}
/**
* Failure reason flag for {@link WifiNanSessionCallback} callbacks.
* Indicates that a command has been issued to a session which is
* terminated. Session termination may have been caused explicitly by the
* user using the {@code WifiNanSession#terminate()} or implicitly as a
* result of the original session reaching its lifetime or being terminated
* due to an error.
* Indicates no resources to execute the requested operation.
*/
public static final int FAIL_REASON_SESSION_TERMINATED = 3;
public static final int REASON_NO_RESOURCES = 0;
/**
* Failure reason flag for {@link WifiNanEventCallback} and
* {@link WifiNanSessionCallback} callbacks. Indicates an unspecified error
* occurred during the operation.
* Failure reason flag for {@link WifiNanSessionCallback} callbacks.
* Indicates invalid argument in the requested operation.
*/
public static final int FAIL_REASON_OTHER = 4;
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
@@ -75,7 +88,7 @@ public class WifiNanSessionCallback {
* requested operations (per {@link PublishConfig} or
* {@link SubscribeConfig}) have been executed.
*/
public static final int TERMINATE_REASON_DONE = 0;
public static final int TERMINATE_REASON_DONE = 100;
/**
* Failure reason flag for
@@ -83,7 +96,7 @@ public class WifiNanSessionCallback {
* Indicates that publish or subscribe session is terminated due to a
* failure.
*/
public static final int TERMINATE_REASON_FAIL = 1;
public static final int TERMINATE_REASON_FAIL = 101;
/**
* Called when a publish operation is started successfully.
@@ -105,15 +118,22 @@ public class WifiNanSessionCallback {
/* 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.FAIL_*} codes.
* {@code WifiNanSessionCallback.REASON_*} codes.
*/
public void onSessionConfigFail(int reason) {
public void onSessionConfigFail(@SessionReasonCodes int reason) {
/* empty */
}
@@ -123,7 +143,7 @@ public class WifiNanSessionCallback {
* @param reason The termination reason using
* {@code WifiNanSessionCallback.TERMINATE_*} codes.
*/
public void onSessionTerminated(int reason) {
public void onSessionTerminated(@SessionTerminateCodes int reason) {
/* empty */
}
@@ -171,9 +191,10 @@ public class WifiNanSessionCallback {
* - never both
*
* @param reason The failure reason using
* {@code WifiNanSessionCallback.FAIL_*} codes.
* {@code WifiNanSessionCallback.REASON_*} codes.
*/
public void onMessageSendFail(@SuppressWarnings("unused") int messageId, int reason) {
public void onMessageSendFail(@SuppressWarnings("unused") int messageId,
@SessionReasonCodes int reason) {
/* empty */
}

View File

@@ -16,6 +16,8 @@
package android.net.wifi.nan;
import android.util.Log;
/**
* A representation of a NAN subscribe session. Created when
* {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} is
@@ -25,12 +27,13 @@ package android.net.wifi.nan;
* @hide PROPOSED_NAN_API
*/
public class WifiNanSubscribeSession extends WifiNanSession {
private static final String TAG = "WifiNanSubscribeSession";
/**
* {@hide}
*/
public WifiNanSubscribeSession(WifiNanManager manager, int sessionId,
WifiNanSessionCallback callback) {
super(manager, sessionId, callback);
public WifiNanSubscribeSession(WifiNanManager manager, int sessionId) {
super(manager, sessionId);
}
/**
@@ -43,10 +46,16 @@ public class WifiNanSubscribeSession extends WifiNanSession {
*/
public void updateSubscribe(SubscribeConfig subscribeConfig) {
if (mTerminated) {
mCallback.onSessionConfigFail(WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
Log.w(TAG, "updateSubscribe: called on terminated session");
return;
} else {
mManager.updateSubscribe(mSessionId, subscribeConfig);
WifiNanManager mgr = mMgr.get();
if (mgr == null) {
Log.w(TAG, "updateSubscribe: called post GC on WifiNanManager");
return;
}
mgr.updateSubscribe(mSessionId, subscribeConfig);
}
}
}