[NAN] Refactor session lifecycle to clarify API & eliminate race conditions [DO NOT MERGE]

Bug: 27257965
Change-Id: I4d7eaa6fa1f089bed2e9185f59a37f59b530975d
This commit is contained in:
Etan Cohen
2016-03-14 18:06:46 -07:00
parent a5ed693788
commit 2a73c7fb2a
8 changed files with 474 additions and 435 deletions

View File

@@ -36,12 +36,14 @@ interface IWifiNanManager
void disconnect(int clientId, in IBinder binder); void disconnect(int clientId, in IBinder binder);
void requestConfig(int clientId, in ConfigRequest configRequest); void requestConfig(int clientId, in ConfigRequest configRequest);
void publish(int clientId, in PublishConfig publishConfig, in IWifiNanSessionCallback callback);
void subscribe(int clientId, in SubscribeConfig subscribeConfig,
in IWifiNanSessionCallback callback);
// session API // session API
int createSession(int clientId, in IWifiNanSessionCallback callback); void updatePublish(int clientId, int sessionId, in PublishConfig publishConfig);
void publish(int clientId, int sessionId, in PublishConfig publishConfig); void updateSubscribe(int clientId, int sessionId, in SubscribeConfig subscribeConfig);
void subscribe(int clientId, int sessionId, in SubscribeConfig subscribeConfig);
void sendMessage(int clientId, int sessionId, int peerId, in byte[] message, int messageLength, void sendMessage(int clientId, int sessionId, int peerId, in byte[] message, int messageLength,
int messageId); int messageId);
void stopSession(int clientId, int sessionId); void terminateSession(int clientId, int sessionId);
void destroySession(int clientId, int sessionId);
} }

View File

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

View File

@@ -16,11 +16,6 @@
package android.net.wifi.nan; 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 * Base class for NAN events callbacks. Should be extended by applications
* wanting notifications. These are callbacks applying to the NAN connection as * wanting notifications. These are callbacks applying to the NAN connection as
@@ -30,65 +25,8 @@ import android.util.Log;
* @hide PROPOSED_NAN_API * @hide PROPOSED_NAN_API
*/ */
public class WifiNanEventCallback { public class WifiNanEventCallback {
private static final String TAG = "WifiNanEventCallback";
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
/** @hide */
public static final int CALLBACK_CONFIG_COMPLETED = 0;
/** @hide */
public static final int CALLBACK_CONFIG_FAILED = 1;
/** @hide */
public static final int CALLBACK_NAN_DOWN = 2;
/** @hide */
public static final int CALLBACK_IDENTITY_CHANGED = 3;
private final Handler mHandler;
/** /**
* Constructs a {@link WifiNanEventCallback} using the looper of the current * Called when NAN configuration is completed.
* thread. I.e. all callbacks will be delivered on the current thread.
*/
public WifiNanEventCallback() {
this(Looper.myLooper());
}
/**
* 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.
*/
public WifiNanEventCallback(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 CALLBACK_CONFIG_COMPLETED:
WifiNanEventCallback.this.onConfigCompleted((ConfigRequest) msg.obj);
break;
case CALLBACK_CONFIG_FAILED:
WifiNanEventCallback.this.onConfigFailed((ConfigRequest) msg.obj, msg.arg1);
break;
case CALLBACK_NAN_DOWN:
WifiNanEventCallback.this.onNanDown(msg.arg1);
break;
case CALLBACK_IDENTITY_CHANGED:
WifiNanEventCallback.this.onIdentityChanged();
break;
}
}
};
}
/**
* Called when NAN configuration is completed. Event will only be delivered
* if registered using
* {@link WifiNanEventCallback#CALLBACK_CONFIG_COMPLETED}. A dummy (empty
* implementation printing out a warning). Make sure to override if
* registered.
* *
* @param completedConfig The actual configuration request which was * @param completedConfig The actual configuration request which was
* completed. Note that it may be different from that requested * completed. Note that it may be different from that requested
@@ -96,89 +34,36 @@ public class WifiNanEventCallback {
* requests from all applications. * requests from all applications.
*/ */
public void onConfigCompleted(ConfigRequest completedConfig) { public void onConfigCompleted(ConfigRequest completedConfig) {
Log.w(TAG, "onConfigCompleted: called in stub - override if interested or disable"); /* empty */
} }
/** /**
* Called when NAN configuration failed. Event will only be delivered if * Called when NAN configuration failed.
* registered using {@link WifiNanEventCallback#CALLBACK_CONFIG_FAILED}. A
* dummy (empty implementation printing out a warning). Make sure to
* override if registered.
* *
* @param reason Failure reason code, see * @param reason Failure reason code, see
* {@code WifiNanSessionCallback.FAIL_*}. * {@code WifiNanSessionCallback.FAIL_*}.
*/ */
public void onConfigFailed(ConfigRequest failedConfig, int reason) { public void onConfigFailed(@SuppressWarnings("unused") ConfigRequest failedConfig, int reason) {
Log.w(TAG, "onConfigFailed: called in stub - override if interested or disable"); /* empty */
} }
/** /**
* Called when NAN cluster is down. Event will only be delivered if * Called when NAN cluster is down
* registered using {@link WifiNanEventCallback#CALLBACK_NAN_DOWN}. A dummy
* (empty implementation printing out a warning). Make sure to override if
* registered.
* *
* @param reason Reason code for event, see * @param reason Reason code for event, see
* {@code WifiNanSessionCallback.FAIL_*}. * {@code WifiNanSessionCallback.FAIL_*}.
*/ */
public void onNanDown(int reason) { public void onNanDown(int reason) {
Log.w(TAG, "onNanDown: called in stub - override if interested or disable"); /* empty */
} }
/** /**
* Called when NAN identity has changed. This may be due to joining a * Called when NAN identity has changed. This may be due to joining a
* cluster, starting a cluster, or discovery interface change. The * cluster, starting a cluster, or discovery interface change. The
* implication is that peers you've been communicating with may no longer * 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 * recognize you and you need to re-establish your identity.
* be delivered if registered using
* {@link WifiNanEventCallback#CALLBACK_IDENTITY_CHANGED}. A dummy (empty
* implementation printing out a warning). Make sure to override if
* registered.
*/ */
public void onIdentityChanged() { public void onIdentityChanged() {
if (VDBG) Log.v(TAG, "onIdentityChanged: called in stub - override if interested"); /* empty */
} }
/**
* {@hide}
*/
public IWifiNanEventCallback callback = new IWifiNanEventCallback.Stub() {
@Override
public void onConfigCompleted(ConfigRequest completedConfig) {
if (VDBG) Log.v(TAG, "onConfigCompleted: configRequest=" + completedConfig);
Message msg = mHandler.obtainMessage(CALLBACK_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(CALLBACK_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(CALLBACK_NAN_DOWN);
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);
}
};
} }

View File

@@ -17,7 +17,11 @@
package android.net.wifi.nan; package android.net.wifi.nan;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
@@ -44,6 +48,7 @@ public class WifiNanManager {
private IBinder mBinder; private IBinder mBinder;
private int mClientId = -1; private int mClientId = -1;
private IWifiNanManager mService; private IWifiNanManager mService;
private Looper mLooper;
/** /**
* {@hide} * {@hide}
@@ -56,22 +61,29 @@ public class WifiNanManager {
* Re-connect to the Wi-Fi NAN service - enabling the application to execute * Re-connect to the Wi-Fi NAN service - enabling the application to execute
* {@link WifiNanManager} APIs. * {@link WifiNanManager} APIs.
* *
* @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 callback A callback extended from {@link WifiNanEventCallback}.
*/ */
public void connect(WifiNanEventCallback callback) { public void connect(Looper looper, WifiNanEventCallback callback) {
if (VDBG) Log.v(TAG, "connect()");
if (callback == null) {
throw new IllegalArgumentException("Invalid callback - must not be null");
}
if (mClientId != -1) {
Log.e(TAG, "connect(): mClientId=" + mClientId
+ ": seems to calling connect() without disconnecting() first!");
throw new IllegalStateException("Calling connect() without disconnecting() first!");
}
mLooper = looper;
mBinder = new Binder();
try { try {
if (VDBG) Log.v(TAG, "connect()"); mClientId = mService.connect(mBinder, new WifiNanEventCallbackProxy(mLooper, callback));
if (callback == null) {
throw new IllegalArgumentException("Invalid callback - must not be null");
}
if (mClientId != -1) {
Log.w(TAG, "connect(): mClientId=" + mClientId
+ ": seems to calling connect() without disconnecting() first!");
}
if (mBinder == null) {
mBinder = new Binder();
}
mClientId = mService.connect(mBinder, callback.callback);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "connect RemoteException (FYI - ignoring): " + e); Log.w(TAG, "connect RemoteException (FYI - ignoring): " + e);
} }
@@ -84,9 +96,18 @@ public class WifiNanManager {
* are cancelled. * are cancelled.
* <p> * <p>
* An application may then re-connect using * An application may then re-connect using
* {@link WifiNanManager#connect(WifiNanEventCallback, int)} . * {@link WifiNanManager#connect(Looper, WifiNanEventCallback)} .
*/ */
public void disconnect() { 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 { try {
if (VDBG) Log.v(TAG, "disconnect()"); if (VDBG) Log.v(TAG, "disconnect()");
mService.disconnect(mClientId, mBinder); mService.disconnect(mClientId, mBinder);
@@ -97,6 +118,14 @@ public class WifiNanManager {
} }
} }
@Override
protected void finalize() throws Throwable {
if (mBinder != null) {
if (DBG) Log.d(TAG, "finalize: disconnect() not called - executing now");
disconnect();
}
}
/** /**
* Requests a NAN configuration, specified by {@link ConfigRequest}. Note * 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 * that NAN is a shared resource and the device can only be a member of a
@@ -112,6 +141,12 @@ public class WifiNanManager {
*/ */
public void requestConfig(ConfigRequest configRequest) { public void requestConfig(ConfigRequest configRequest) {
if (VDBG) Log.v(TAG, "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 { try {
mService.requestConfig(mClientId, configRequest); mService.requestConfig(mClientId, configRequest);
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -120,19 +155,19 @@ public class WifiNanManager {
} }
/** /**
* Request a NAN publish session. The results of the publish session * Request a NAN publish session. The actual publish session is provided by
* operation will result in callbacks to the indicated callback: * the
* {@link WifiNanSessionCallback NanSessionCallback.on*}. * {@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 * @param publishConfig The {@link PublishConfig} specifying the
* configuration of the publish session. * configuration of the publish session.
* @param callback The {@link WifiNanSessionCallback} derived objects to be * @param callback The {@link WifiNanSessionCallback} derived objects to be
* used for the event callbacks specified by {@code events}. * used for the event callbacks specified by {@code events}.
* @return The {@link WifiNanPublishSession} which can be used to further
* control the publish session.
*/ */
public WifiNanPublishSession publish(PublishConfig publishConfig, public void publish(PublishConfig publishConfig, WifiNanSessionCallback callback) {
WifiNanSessionCallback callback) {
if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig); if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig);
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
@@ -149,25 +184,24 @@ public class WifiNanManager {
throw new IllegalArgumentException("Invalid callback - must not be null"); throw new IllegalArgumentException("Invalid callback - must not be null");
} }
int sessionId; if (mClientId == -1) {
Log.e(TAG, "publish(): called without an initial connect()!");
try { throw new IllegalStateException("Calling publish() without a connect() first!");
sessionId = mService.createSession(mClientId, callback.callback);
if (DBG) Log.d(TAG, "publish: session created - sessionId=" + sessionId);
mService.publish(mClientId, sessionId, publishConfig);
} catch (RemoteException e) {
Log.w(TAG, "createSession/publish RemoteException: " + e);
return null;
} }
return new WifiNanPublishSession(this, sessionId); try {
mService.publish(mClientId, publishConfig,
new WifiNanSessionCallbackProxy(mLooper, true, callback));
} catch (RemoteException e) {
Log.w(TAG, "publish RemoteException: " + e);
}
} }
/** /**
* {@hide} * {@hide}
*/ */
public void publish(int sessionId, PublishConfig publishConfig) { public void updatePublish(int sessionId, PublishConfig publishConfig) {
if (VDBG) Log.v(TAG, "publish(): config=" + publishConfig); if (VDBG) Log.v(TAG, "updatePublish(): config=" + publishConfig);
if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED if (publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
&& publishConfig.mRxFilterLength != 0) { && publishConfig.mRxFilterLength != 0) {
@@ -181,26 +215,26 @@ public class WifiNanManager {
} }
try { try {
mService.publish(mClientId, sessionId, publishConfig); mService.updatePublish(mClientId, sessionId, publishConfig);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "publish RemoteException: " + e); Log.w(TAG, "updatePublish RemoteException: " + e);
} }
} }
/** /**
* Request a NAN subscribe session. The results of the subscribe session * Request a NAN subscribe session. The actual subscribe session is provided
* operation will result in callbacks to the indicated callback: * by the
* {@link WifiNanSessionCallback WifiNanSessionCallback.on*}. * {@link WifiNanSessionCallback#onSubscribeStarted(WifiNanSubscribeSession)}
* callback. Other results of the subscribe session operation will result in
* callbacks to the indicated callback: {@link WifiNanSessionCallback
* NanSessionCallback.on*}
* *
* @param subscribeConfig The {@link SubscribeConfig} specifying the * @param subscribeConfig The {@link SubscribeConfig} specifying the
* configuration of the subscribe session. * configuration of the subscribe session.
* @param callback The {@link WifiNanSessionCallback} derived objects to be * @param callback The {@link WifiNanSessionCallback} derived objects to be
* used for the event callbacks specified by {@code events}. * used for the event callbacks specified by {@code events}.
* @return The {@link WifiNanSubscribeSession} which can be used to further
* control the subscribe session.
*/ */
public WifiNanSubscribeSession subscribe(SubscribeConfig subscribeConfig, public void subscribe(SubscribeConfig subscribeConfig, WifiNanSessionCallback callback) {
WifiNanSessionCallback callback) {
if (VDBG) { if (VDBG) {
Log.v(TAG, "subscribe(): config=" + subscribeConfig); Log.v(TAG, "subscribe(): config=" + subscribeConfig);
} }
@@ -216,41 +250,14 @@ public class WifiNanManager {
"Invalid subscribe config: PASSIVE subscribes can't have a Tx filter"); "Invalid subscribe config: PASSIVE subscribes can't have a Tx filter");
} }
int sessionId; if (mClientId == -1) {
Log.e(TAG, "subscribe(): called without an initial connect()!");
try { throw new IllegalStateException("Calling subscribe() without a connect() first!");
sessionId = mService.createSession(mClientId, callback.callback);
if (DBG) Log.d(TAG, "subscribe: session created - sessionId=" + sessionId);
mService.subscribe(mClientId, sessionId, subscribeConfig);
} catch (RemoteException e) {
Log.w(TAG, "createSession/subscribe RemoteException: " + e);
return null;
}
return new WifiNanSubscribeSession(this, sessionId);
}
/**
* {@hide}
*/
public void subscribe(int sessionId, SubscribeConfig subscribeConfig) {
if (VDBG) {
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");
} }
try { try {
mService.subscribe(mClientId, sessionId, subscribeConfig); mService.subscribe(mClientId, subscribeConfig,
new WifiNanSessionCallbackProxy(mLooper, false, callback));
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "subscribe RemoteException: " + e); Log.w(TAG, "subscribe RemoteException: " + e);
} }
@@ -259,26 +266,39 @@ public class WifiNanManager {
/** /**
* {@hide} * {@hide}
*/ */
public void stopSession(int sessionId) { public void updateSubscribe(int sessionId, SubscribeConfig subscribeConfig) {
if (DBG) Log.d(TAG, "Stop NAN session #" + sessionId); if (VDBG) {
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");
}
try { try {
mService.stopSession(mClientId, sessionId); mService.updateSubscribe(mClientId, sessionId, subscribeConfig);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "stopSession RemoteException (FYI - ignoring): " + e); Log.w(TAG, "updateSubscribe RemoteException: " + e);
} }
} }
/** /**
* {@hide} * {@hide}
*/ */
public void destroySession(int sessionId) { public void terminateSession(int sessionId) {
if (DBG) Log.d(TAG, "Destroy NAN session #" + sessionId); if (DBG) Log.d(TAG, "Terminate NAN session #" + sessionId);
try { try {
mService.destroySession(mClientId, sessionId); mService.terminateSession(mClientId, sessionId);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "destroySession RemoteException (FYI - ignoring): " + e); Log.w(TAG, "terminateSession RemoteException (FYI - ignoring): " + e);
} }
} }
@@ -297,4 +317,269 @@ public class WifiNanManager {
Log.w(TAG, "subscribe RemoteException (FYI - ignoring): " + e); Log.w(TAG, "subscribe RemoteException (FYI - ignoring): " + e);
} }
} }
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_NAN_DOWN = 2;
private static final int CALLBACK_IDENTITY_CHANGED = 3;
private final WifiNanEventCallback mOriginalCallback;
private final Handler mHandler;
/**
* 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(Looper looper, WifiNanEventCallback originalCallback) {
mOriginalCallback = originalCallback;
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);
switch (msg.what) {
case CALLBACK_CONFIG_COMPLETED:
mOriginalCallback.onConfigCompleted((ConfigRequest) msg.obj);
break;
case CALLBACK_CONFIG_FAILED:
mOriginalCallback.onConfigFailed((ConfigRequest) msg.obj, msg.arg1);
break;
case CALLBACK_NAN_DOWN:
mOriginalCallback.onNanDown(msg.arg1);
break;
case CALLBACK_IDENTITY_CHANGED:
mOriginalCallback.onIdentityChanged();
break;
}
}
};
}
@Override
public void onConfigCompleted(ConfigRequest completedConfig) {
if (VDBG) Log.v(TAG, "onConfigCompleted: configRequest=" + completedConfig);
Message msg = mHandler.obtainMessage(CALLBACK_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(CALLBACK_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(CALLBACK_NAN_DOWN);
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);
}
}
private 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 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 boolean mIsPublish;
private final WifiNanSessionCallback mOriginalCallback;
private final Handler mHandler;
private WifiNanSession mSession;
WifiNanSessionCallbackProxy(Looper looper, boolean isPublish,
WifiNanSessionCallback originalCallback) {
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);
switch (msg.what) {
case CALLBACK_SESSION_STARTED:
onProxySessionStarted(msg.arg1);
break;
case CALLBACK_SESSION_CONFIG_FAIL:
onProxySessionConfigFail(msg.arg1);
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 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!?");
}
if (mIsPublish) {
WifiNanPublishSession session = new WifiNanPublishSession(WifiNanManager.this,
sessionId, mOriginalCallback);
mSession = session;
mOriginalCallback.onPublishStarted(session);
} else {
WifiNanSubscribeSession session = new WifiNanSubscribeSession(WifiNanManager.this,
sessionId, mOriginalCallback);
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();
} else {
Log.w(TAG, "Proxy: onSessionTerminated called but mSession is null!?");
}
}
}
} }

View File

@@ -18,7 +18,7 @@ package android.net.wifi.nan;
/** /**
* A representation of a NAN publish session. Created when * A representation of a NAN publish session. Created when
* {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback, int)} is * {@link WifiNanManager#publish(PublishConfig, WifiNanSessionCallback)} is
* executed. The object can be used to stop and re-start (re-configure) the * executed. The object can be used to stop and re-start (re-configure) the
* publish session. * publish session.
* *
@@ -28,19 +28,25 @@ public class WifiNanPublishSession extends WifiNanSession {
/** /**
* {@hide} * {@hide}
*/ */
public WifiNanPublishSession(WifiNanManager manager, int sessionId) { public WifiNanPublishSession(WifiNanManager manager, int sessionId,
super(manager, sessionId); WifiNanSessionCallback callback) {
super(manager, sessionId, callback);
} }
/** /**
* Restart/re-configure the publish session. Note that the * Re-configure the publish session. Note that the
* {@link WifiNanSessionCallback} is not replaced - the same listener used * {@link WifiNanSessionCallback} is not replaced - the same listener used
* at creation is still used. * at creation is still used.
* *
* @param publishConfig The configuration ({@link PublishConfig}) of the * @param publishConfig The configuration ({@link PublishConfig}) of the
* publish session. * publish session.
*/ */
public void publish(PublishConfig publishConfig) { public void updatePublish(PublishConfig publishConfig) {
mManager.publish(mSessionId, publishConfig); if (mTerminated) {
mCallback.onSessionConfigFail(WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
return;
} else {
mManager.updatePublish(mSessionId, publishConfig);
}
} }
} }

View File

@@ -30,64 +30,44 @@ public class WifiNanSession {
private static final boolean DBG = false; private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true private static final boolean VDBG = false; // STOPSHIP if true
/**
* {@hide}
*/
protected WifiNanManager mManager; protected WifiNanManager mManager;
protected final int mSessionId;
protected final WifiNanSessionCallback mCallback;
protected boolean mTerminated = false;
/** /**
* {@hide} * {@hide}
*/ */
protected int mSessionId; public WifiNanSession(WifiNanManager manager, int sessionId,
WifiNanSessionCallback callback) {
/**
* {@hide}
*/
private boolean mDestroyed;
/**
* {@hide}
*/
public WifiNanSession(WifiNanManager manager, int sessionId) {
if (VDBG) Log.v(TAG, "New client created: manager=" + manager + ", sessionId=" + sessionId); if (VDBG) Log.v(TAG, "New client created: manager=" + manager + ", sessionId=" + sessionId);
mManager = manager; mManager = manager;
mSessionId = sessionId; mSessionId = sessionId;
mDestroyed = false; mCallback = callback;
} }
/** /**
* Terminate the current publish or subscribe session - i.e. stop * Terminate the current publish or subscribe session - i.e. stop
* transmitting packet on-air (for an active session) or listening for * transmitting packet on-air (for an active session) or listening for
* matches (for a passive session). Note that the session may still receive * matches (for a passive session). The session may not be used for any
* incoming messages and may be re-configured/re-started at a later time. * additional operations are termination.
*/ */
public void stop() { public void terminate() {
mManager.stopSession(mSessionId); mManager.terminateSession(mSessionId);
mTerminated = true;
mManager = null;
} }
/**
* 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.
*/
public void destroy() {
mManager.destroySession(mSessionId);
mDestroyed = true;
}
/**
* {@hide}
*/
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
if (!mDestroyed) { if (!mTerminated) {
Log.w(TAG, "WifiNanSession mSessionId=" + mSessionId Log.w(TAG, "WifiNanSession mSessionId=" + mSessionId
+ " was not explicitly destroyed. The session may use resources until " + " was not explicitly terminated. The session may use resources until "
+ "destroyed so step should be done explicitly"); + "terminated so step should be done explicitly");
} }
destroy(); terminate();
} }
/** /**
@@ -108,6 +88,12 @@ public class WifiNanSession {
* indicated message send success or failure. * indicated message send success or failure.
*/ */
public void sendMessage(int peerId, byte[] message, int messageLength, int messageId) { public void sendMessage(int peerId, byte[] message, int messageLength, int messageId) {
if (mTerminated) {
mCallback.onMessageSendFail(messageId,
WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
return;
}
mManager.sendMessage(mSessionId, peerId, message, messageLength, messageId); mManager.sendMessage(mSessionId, peerId, message, messageLength, messageId);
} }
} }

View File

@@ -16,12 +16,6 @@
package android.net.wifi.nan; 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 * Base class for NAN session events callbacks. Should be extended by
* applications wanting notifications. The callbacks are registered when a * applications wanting notifications. The callbacks are registered when a
@@ -36,23 +30,6 @@ import android.util.Log;
* @hide PROPOSED_NAN_API * @hide PROPOSED_NAN_API
*/ */
public class WifiNanSessionCallback { public class WifiNanSessionCallback {
private static final String TAG = "WifiNanSessionCallback";
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
/** @hide */
public static final int CALLBACK_SESSION_CONFIG_FAIL = 0;
/** @hide */
public static final int CALLBACK_SESSION_TERMINATED = 1;
/** @hide */
public static final int CALLBACK_MATCH = 2;
/** @hide */
public static final int CALLBACK_MESSAGE_SEND_SUCCESS = 3;
/** @hide */
public static final int CALLBACK_MESSAGE_SEND_FAIL = 4;
/** @hide */
public static final int CALLBACK_MESSAGE_RECEIVED = 5;
/** /**
* Failure reason flag for {@link WifiNanEventCallback} and * Failure reason flag for {@link WifiNanEventCallback} and
* {@link WifiNanSessionCallback} callbacks. Indicates no resources to * {@link WifiNanSessionCallback} callbacks. Indicates no resources to
@@ -74,12 +51,22 @@ public class WifiNanSessionCallback {
*/ */
public static final int FAIL_REASON_NO_MATCH_SESSION = 2; public static final int FAIL_REASON_NO_MATCH_SESSION = 2;
/**
* 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.
*/
public static final int FAIL_REASON_SESSION_TERMINATED = 3;
/** /**
* Failure reason flag for {@link WifiNanEventCallback} and * Failure reason flag for {@link WifiNanEventCallback} and
* {@link WifiNanSessionCallback} callbacks. Indicates an unspecified error * {@link WifiNanSessionCallback} callbacks. Indicates an unspecified error
* occurred during the operation. * occurred during the operation.
*/ */
public static final int FAIL_REASON_OTHER = 3; public static final int FAIL_REASON_OTHER = 4;
/** /**
* Failure reason flag for * Failure reason flag for
@@ -98,90 +85,51 @@ public class WifiNanSessionCallback {
*/ */
public static final int TERMINATE_REASON_FAIL = 1; 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 WifiNanSessionCallback} using the looper of the * Called when a publish operation is started successfully.
* current thread. I.e. all callbacks will be delivered on the current
* thread.
*/
public WifiNanSessionCallback() {
this(Looper.myLooper());
}
/**
* Constructs a {@link WifiNanSessionCallback} 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. * @param session The {@link WifiNanPublishSession} used to control the
* discovery session.
*/ */
public WifiNanSessionCallback(Looper looper) { public void onPublishStarted(WifiNanPublishSession session) {
if (VDBG) Log.v(TAG, "ctor: looper=" + looper); /* empty */
mHandler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
if (DBG) Log.d(TAG, "What=" + msg.what + ", msg=" + msg);
switch (msg.what) {
case CALLBACK_SESSION_CONFIG_FAIL:
WifiNanSessionCallback.this.onSessionConfigFail(msg.arg1);
break;
case CALLBACK_SESSION_TERMINATED:
WifiNanSessionCallback.this.onSessionTerminated(msg.arg1);
break;
case CALLBACK_MATCH:
WifiNanSessionCallback.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 CALLBACK_MESSAGE_SEND_SUCCESS:
WifiNanSessionCallback.this.onMessageSendSuccess(msg.arg1);
break;
case CALLBACK_MESSAGE_SEND_FAIL:
WifiNanSessionCallback.this.onMessageSendFail(msg.arg1, msg.arg2);
break;
case CALLBACK_MESSAGE_RECEIVED:
WifiNanSessionCallback.this.onMessageReceived(msg.arg2,
msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE), msg.arg1);
break;
}
}
};
} }
/** /**
* Called when a session configuration (publish or subscribe setup) fails. * Called when a subscribe operation is started successfully.
* It is dummy method (empty implementation printing out a log message). *
* Override to implement your custom response. * @param session The {@link WifiNanSubscribeSession} used to control the
* discovery session.
*/
public void onSubscribeStarted(WifiNanSubscribeSession session) {
/* empty */
}
/**
* Called when a session configuration (publish or subscribe setup or
* update) fails.
* *
* @param reason The failure reason using * @param reason The failure reason using
* {@code WifiNanSessionCallback.FAIL_*} codes. * {@code WifiNanSessionCallback.FAIL_*} codes.
*/ */
public void onSessionConfigFail(int reason) { public void onSessionConfigFail(int reason) {
if (VDBG) Log.v(TAG, "onSessionConfigFail: called in stub - override if interested"); /* empty */
} }
/** /**
* Called when a session (publish or subscribe) terminates. A dummy (empty * Called when a session (publish or subscribe) terminates.
* implementation printing out a warning). Make sure to override if
* registered.
* *
* @param reason The termination reason using * @param reason The termination reason using
* {@code WifiNanSessionCallback.TERMINATE_*} codes. * {@code WifiNanSessionCallback.TERMINATE_*} codes.
*/ */
public void onSessionTerminated(int reason) { public void onSessionTerminated(int reason) {
Log.w(TAG, "onSessionTerminated: called in stub - override if interested or disable"); /* empty */
} }
/** /**
* Called when a discovery (publish or subscribe) operation results in a * Called when a discovery (publish or subscribe) operation results in a
* match - i.e. when a peer is discovered. It is dummy method (empty * match - i.e. when a peer is discovered.
* implementation printing out a log message). Override to implement your
* custom response.
* *
* @param peerId The ID of the peer matching our discovery operation. * @param peerId The ID of the peer matching our discovery operation.
* @param serviceSpecificInfo The service specific information (arbitrary * @param serviceSpecificInfo The service specific information (arbitrary
@@ -195,21 +143,20 @@ public class WifiNanSessionCallback {
*/ */
public void onMatch(int peerId, byte[] serviceSpecificInfo, public void onMatch(int peerId, byte[] serviceSpecificInfo,
int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) { int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) {
if (VDBG) Log.v(TAG, "onMatch: called in stub - override if interested"); /* empty */
} }
/** /**
* Called when a message is transmitted successfully - i.e. when we know * Called when a message is transmitted successfully - i.e. when we know
* that it was received successfully (corresponding to an ACK being * that it was received successfully (corresponding to an ACK being
* received). It is dummy method (empty implementation printing out a log * received).
* message). Override to implement your custom response.
* <p> * <p>
* Note that either this callback or * Note that either this callback or
* {@link WifiNanSessionCallback#onMessageSendFail(int, int)} will be * {@link WifiNanSessionCallback#onMessageSendFail(int, int)} will be
* received - never both. * received - never both.
*/ */
public void onMessageSendSuccess(int messageId) { public void onMessageSendSuccess(@SuppressWarnings("unused") int messageId) {
if (VDBG) Log.v(TAG, "onMessageSendSuccess: called in stub - override if interested"); /* empty */
} }
/** /**
@@ -217,8 +164,7 @@ public class WifiNanSessionCallback {
* The hardware will usually attempt to re-transmit several times - this * The hardware will usually attempt to re-transmit several times - this
* event is received after all retries are exhausted. There is a possibility * event is received after all retries are exhausted. There is a possibility
* that message was received by the destination successfully but the ACK was * that message was received by the destination successfully but the ACK was
* lost. It is dummy method (empty implementation printing out a log * lost
* message). Override to implement your custom response.
* <p> * <p>
* Note that either this callback or * Note that either this callback or
* {@link WifiNanSessionCallback#onMessageSendSuccess(int)} will be received * {@link WifiNanSessionCallback#onMessageSendSuccess(int)} will be received
@@ -227,14 +173,12 @@ public class WifiNanSessionCallback {
* @param reason The failure reason using * @param reason The failure reason using
* {@code WifiNanSessionCallback.FAIL_*} codes. * {@code WifiNanSessionCallback.FAIL_*} codes.
*/ */
public void onMessageSendFail(int messageId, int reason) { public void onMessageSendFail(@SuppressWarnings("unused") int messageId, int reason) {
if (VDBG) Log.v(TAG, "onMessageSendFail: called in stub - override if interested"); /* empty */
} }
/** /**
* Called when a message is received from a discovery session peer. It is * Called when a message is received from a discovery session peer.
* 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 peerId The ID of the peer sending the message.
* @param message A byte array containing the message. * @param message A byte array containing the message.
@@ -242,82 +186,6 @@ public class WifiNanSessionCallback {
* message bytes. * message bytes.
*/ */
public void onMessageReceived(int peerId, byte[] message, int messageLength) { public void onMessageReceived(int peerId, byte[] message, int messageLength) {
if (VDBG) Log.v(TAG, "onMessageReceived: called in stub - override if interested"); /* empty */
} }
/**
* {@hide}
*/
public IWifiNanSessionCallback callback = new IWifiNanSessionCallback.Stub() {
@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);
}
};
} }

View File

@@ -18,8 +18,8 @@ package android.net.wifi.nan;
/** /**
* A representation of a NAN subscribe session. Created when * A representation of a NAN subscribe session. Created when
* {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback, int)} * {@link WifiNanManager#subscribe(SubscribeConfig, WifiNanSessionCallback)} is
* is executed. The object can be used to stop and re-start (re-configure) the * executed. The object can be used to stop and re-start (re-configure) the
* subscribe session. * subscribe session.
* *
* @hide PROPOSED_NAN_API * @hide PROPOSED_NAN_API
@@ -28,19 +28,25 @@ public class WifiNanSubscribeSession extends WifiNanSession {
/** /**
* {@hide} * {@hide}
*/ */
public WifiNanSubscribeSession(WifiNanManager manager, int sessionId) { public WifiNanSubscribeSession(WifiNanManager manager, int sessionId,
super(manager, sessionId); WifiNanSessionCallback callback) {
super(manager, sessionId, callback);
} }
/** /**
* Restart/re-configure the subscribe session. Note that the * Re-configure the subscribe session. Note that the
* {@link WifiNanSessionCallback} is not replaced - the same listener used * {@link WifiNanSessionCallback} is not replaced - the same listener used
* at creation is still used. * at creation is still used.
* *
* @param subscribeConfig The configuration ({@link SubscribeConfig}) of the * @param subscribeConfig The configuration ({@link SubscribeConfig}) of the
* subscribe session. * subscribe session.
*/ */
public void subscribe(SubscribeConfig subscribeConfig) { public void updateSubscribe(SubscribeConfig subscribeConfig) {
mManager.subscribe(mSessionId, subscribeConfig); if (mTerminated) {
mCallback.onSessionConfigFail(WifiNanSessionCallback.FAIL_REASON_SESSION_TERMINATED);
return;
} else {
mManager.updateSubscribe(mSessionId, subscribeConfig);
}
} }
} }