diff options
author | Etan Cohen <etancohen@google.com> | 2016-02-05 18:27:08 +0000 |
---|---|---|
committer | Android Partner Code Review <android-gerrit-partner@google.com> | 2016-02-05 18:27:08 +0000 |
commit | a40a871604177637c12f190cbbfbf71752c490bd (patch) | |
tree | 72228b58759fafb8a0b9f6f1f2f8f8f24c7f3bc4 | |
parent | d852b3a37c17c4d4595fbe0389c90fec06ed9382 (diff) | |
parent | 22b4156d2948e3108ae8439dc72f76fb97526ace (diff) |
Merge "NAN: Adding tests for internal state of WifiNanStateManager" into mm-wireless-dev
9 files changed, 980 insertions, 404 deletions
diff --git a/service/java/com/android/server/wifi/nan/WifiNanClientState.java b/service/java/com/android/server/wifi/nan/WifiNanClientState.java index d4b7438cc..2333ea628 100644 --- a/service/java/com/android/server/wifi/nan/WifiNanClientState.java +++ b/service/java/com/android/server/wifi/nan/WifiNanClientState.java @@ -65,13 +65,28 @@ public class WifiNanClientState { return mConfigRequest; } + public int getUid() { + return mUid; + } + + public WifiNanSessionState getNanSessionStateForPubSubId(int pubSubId) { + for (int i = 0; i < mSessions.size(); ++i) { + WifiNanSessionState session = mSessions.valueAt(i); + if (session.isPubSubIdSession(pubSubId)) { + return session; + } + } + + return null; + } + public void createSession(int sessionId, IWifiNanSessionListener listener, int events) { WifiNanSessionState session = mSessions.get(sessionId); if (session != null) { Log.e(TAG, "createSession: sessionId already exists (replaced) - " + sessionId); } - mSessions.put(sessionId, new WifiNanSessionState(mUid, sessionId, listener, events)); + mSessions.put(sessionId, new WifiNanSessionState(sessionId, listener, events)); } public void destroySession(int sessionId) { @@ -99,10 +114,10 @@ public class WifiNanClientState { } } - public void onConfigFailed(int reason) { + public void onConfigFailed(ConfigRequest failedConfig, int reason) { if (mListener != null && (mEvents & WifiNanEventListener.LISTEN_CONFIG_FAILED) != 0) { try { - mListener.onConfigFailed(reason); + mListener.onConfigFailed(failedConfig, reason); } catch (RemoteException e) { Log.w(TAG, "onConfigFailed: RemoteException - ignored: " + e); } diff --git a/service/java/com/android/server/wifi/nan/WifiNanNative.java b/service/java/com/android/server/wifi/nan/WifiNanNative.java index 78afe333a..f43040046 100644 --- a/service/java/com/android/server/wifi/nan/WifiNanNative.java +++ b/service/java/com/android/server/wifi/nan/WifiNanNative.java @@ -66,7 +66,7 @@ public class WifiNanNative { return sWifiNanNativeSingleton; } - public native static int initNanHandlersNative(Object cls, int iface); + public static native int initNanHandlersNative(Object cls, int iface); private boolean isNanInit(boolean tryToInit) { if (!tryToInit || sNanNativeInit) { @@ -95,7 +95,7 @@ public class WifiNanNative { // do nothing } - private native static int enableAndConfigureNative(short transactionId, Object cls, int iface, + private static native int enableAndConfigureNative(short transactionId, Object cls, int iface, ConfigRequest configRequest); public void enableAndConfigure(short transactionId, ConfigRequest configRequest) { @@ -119,7 +119,7 @@ public class WifiNanNative { // TODO: do something on !success - send failure message back } - private native static int disableNative(short transactionId, Object cls, int iface); + private static native int disableNative(short transactionId, Object cls, int iface); public void disable(short transactionId) { boolean success; @@ -140,7 +140,7 @@ public class WifiNanNative { // TODO: do something on !success - send failure message back } - private native static int publishNative(short transactionId, int publishId, Object cls, + private static native int publishNative(short transactionId, int publishId, Object cls, int iface, PublishData publishData, PublishSettings publishSettings); @@ -169,7 +169,7 @@ public class WifiNanNative { // TODO: do something on !success - send failure message back } - private native static int subscribeNative(short transactionId, int subscribeId, Object cls, + private static native int subscribeNative(short transactionId, int subscribeId, Object cls, int iface, SubscribeData subscribeData, SubscribeSettings subscribeSettings); public void subscribe(short transactionId, int subscribeId, SubscribeData subscribeData, @@ -197,7 +197,7 @@ public class WifiNanNative { // TODO: do something on !success - send failure message back } - private native static int sendMessageNative(short transactionId, Object cls, int iface, + private static native int sendMessageNative(short transactionId, Object cls, int iface, int pubSubId, int requestorInstanceId, byte[] dest, byte[] message, int messageLength); public void sendMessage(short transactionId, int pubSubId, int requestorInstanceId, byte[] dest, @@ -228,7 +228,7 @@ public class WifiNanNative { // TODO: do something on !success - send failure message back } - private native static int stopPublishNative(short transactionId, Object cls, int iface, + private static native int stopPublishNative(short transactionId, Object cls, int iface, int pubSubId); public void stopPublish(short transactionId, int pubSubId) { @@ -254,7 +254,7 @@ public class WifiNanNative { // TODO: do something on !success - send failure message back } - private native static int stopSubscribeNative(short transactionId, Object cls, int iface, + private static native int stopSubscribeNative(short transactionId, Object cls, int iface, int pubSubId); public void stopSubscribe(short transactionId, int pubSubId) { @@ -431,8 +431,8 @@ public class WifiNanNative { if (status == NAN_STATUS_SUCCESS) { WifiNanStateManager.getInstance().onConfigCompleted(transactionId); } else { - WifiNanStateManager.getInstance() - .onConfigFailed(translateHalStatusToPublicStatus(status)); + WifiNanStateManager.getInstance().onConfigFailed(transactionId, + translateHalStatusToPublicStatus(status)); } break; case NAN_RESPONSE_PUBLISH: diff --git a/service/java/com/android/server/wifi/nan/WifiNanSessionState.java b/service/java/com/android/server/wifi/nan/WifiNanSessionState.java index 8e7b1ec22..741ef55f8 100644 --- a/service/java/com/android/server/wifi/nan/WifiNanSessionState.java +++ b/service/java/com/android/server/wifi/nan/WifiNanSessionState.java @@ -36,11 +36,8 @@ public class WifiNanSessionState { private static final boolean DBG = true; private static final boolean VDBG = false; // STOPSHIP if true - private static final SparseArray<WifiNanSessionState> sSessionsByPubSubId = new SparseArray<>(); + private final SparseArray<String> mMacByRequestorInstanceId = new SparseArray<>(); - private static final SparseArray<String> sMacByRequestorInstanceId = new SparseArray<>(); - - private int mUid; private int mSessionId; private IWifiNanSessionListener mListener; private int mEvents; @@ -53,36 +50,29 @@ public class WifiNanSessionState { private static final int SESSION_TYPE_SUBSCRIBE = 2; private int mSessionType = SESSION_TYPE_NOT_INIT; - public static WifiNanSessionState getNanSessionStateForPubSubId(int pubSubId) { - return sSessionsByPubSubId.get(pubSubId); - } - - public WifiNanSessionState(int uid, int sessionId, IWifiNanSessionListener listener, - int events) { - mUid = uid; + public WifiNanSessionState(int sessionId, IWifiNanSessionListener listener, int events) { mSessionId = sessionId; mListener = listener; mEvents = events; } public void destroy() { - stop(WifiNanStateManager.getInstance().getTransactionId()); + stop(WifiNanStateManager.getInstance().createNextTransactionId()); if (mPubSubIdValid) { - WifiNanSessionState.sSessionsByPubSubId.delete(mPubSubId); - sMacByRequestorInstanceId.clear(); + mMacByRequestorInstanceId.clear(); mListener = null; mPubSubIdValid = false; } } - public int getUid() { - return mUid; - } - public int getSessionId() { return mSessionId; } + public boolean isPubSubIdSession(int pubSubId) { + return mPubSubIdValid && mPubSubId == pubSubId; + } + public void publish(short transactionId, PublishData data, PublishSettings settings) { if (mSessionType == SESSION_TYPE_SUBSCRIBE) { throw new IllegalStateException("A SUBSCRIBE session is being used for publish"); @@ -112,7 +102,7 @@ public class WifiNanSessionState { return; } - String peerMacStr = sMacByRequestorInstanceId.get(peerId); + String peerMacStr = mMacByRequestorInstanceId.get(peerId); if (peerMacStr == null) { Log.e(TAG, "sendMessage: attempting to send a message to an address which didn't " + "match/contact us"); @@ -140,13 +130,8 @@ public class WifiNanSessionState { } public void onPublishSuccess(int publishId) { - if (mPubSubIdValid) { - WifiNanSessionState.sSessionsByPubSubId.delete(mPubSubId); - } - mPubSubId = publishId; mPubSubIdValid = true; - WifiNanSessionState.sSessionsByPubSubId.put(mPubSubId, this); } public void onPublishFail(int status) { @@ -173,13 +158,8 @@ public class WifiNanSessionState { } public void onSubscribeSuccess(int subscribeId) { - if (mPubSubIdValid) { - WifiNanSessionState.sSessionsByPubSubId.delete(mPubSubId); - } - mPubSubId = subscribeId; mPubSubIdValid = true; - WifiNanSessionState.sSessionsByPubSubId.put(mPubSubId, this); } public void onSubscribeFail(int status) { @@ -230,8 +210,8 @@ public class WifiNanSessionState { public void onMatch(int requestorInstanceId, byte[] peerMac, byte[] serviceSpecificInfo, int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) { - String prevMac = sMacByRequestorInstanceId.get(requestorInstanceId); - sMacByRequestorInstanceId.put(requestorInstanceId, new String(HexEncoding.encode(peerMac))); + String prevMac = mMacByRequestorInstanceId.get(requestorInstanceId); + mMacByRequestorInstanceId.put(requestorInstanceId, new String(HexEncoding.encode(peerMac))); if (DBG) Log.d(TAG, "onMatch: previous peer MAC replaced - " + prevMac); @@ -247,8 +227,8 @@ public class WifiNanSessionState { public void onMessageReceived(int requestorInstanceId, byte[] peerMac, byte[] message, int messageLength) { - String prevMac = sMacByRequestorInstanceId.get(requestorInstanceId); - sMacByRequestorInstanceId.put(requestorInstanceId, new String(HexEncoding.encode(peerMac))); + String prevMac = mMacByRequestorInstanceId.get(requestorInstanceId); + mMacByRequestorInstanceId.put(requestorInstanceId, new String(HexEncoding.encode(peerMac))); if (DBG) { Log.d(TAG, "onMessageReceived: previous peer MAC replaced - " + prevMac); @@ -266,16 +246,10 @@ public class WifiNanSessionState { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("NanSessionState:"); - pw.println(" mUid: " + mUid); pw.println(" mSessionId: " + mSessionId); pw.println(" mSessionType: " + mSessionType); pw.println(" mEvents: " + mEvents); pw.println(" mPubSubId: " + (mPubSubIdValid ? Integer.toString(mPubSubId) : "not valid")); - pw.println(" sMacByRequestorInstanceId: [" + sMacByRequestorInstanceId + "]"); - } - - public static void dumpS(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println("NanSessionState Static:"); - pw.println(" sSessionsByPubSubId: " + WifiNanSessionState.sSessionsByPubSubId); + pw.println(" mMacByRequestorInstanceId: [" + mMacByRequestorInstanceId + "]"); } } diff --git a/service/java/com/android/server/wifi/nan/WifiNanStateManager.java b/service/java/com/android/server/wifi/nan/WifiNanStateManager.java index 6273e0f12..ce32827f9 100644 --- a/service/java/com/android/server/wifi/nan/WifiNanStateManager.java +++ b/service/java/com/android/server/wifi/nan/WifiNanStateManager.java @@ -42,7 +42,7 @@ public class WifiNanStateManager { private static final boolean DBG = true; private static final boolean VDBG = false; // STOPSHIP if true - private static WifiNanStateManager sNanStatemanagerSingleton; + private static WifiNanStateManager sNanStateManagerSingleton; private static final int MESSAGE_CONNECT = 0; private static final int MESSAGE_DISCONNECT = 1; @@ -92,8 +92,7 @@ public class WifiNanStateManager { // no synchronization necessary: only access through Handler private final SparseArray<WifiNanClientState> mClients = new SparseArray<>(); - private final SparseArray<TransactionInfo> mPendingResponses = new SparseArray<>(); - private final SparseArray<ConfigRequest> mPendingConfigs = new SparseArray<>(); + private final SparseArray<TransactionInfoBase> mPendingResponses = new SparseArray<>(); private short mNextTransactionId = 1; private WifiNanStateManager() { @@ -101,11 +100,11 @@ public class WifiNanStateManager { } public static WifiNanStateManager getInstance() { - if (sNanStatemanagerSingleton == null) { - sNanStatemanagerSingleton = new WifiNanStateManager(); + if (sNanStateManagerSingleton == null) { + sNanStateManagerSingleton = new WifiNanStateManager(); } - return sNanStatemanagerSingleton; + return sNanStateManagerSingleton; } public void start(Looper looper) { @@ -209,9 +208,10 @@ public class WifiNanStateManager { mHandler.sendMessage(msg); } - public void onConfigFailed(int reason) { + public void onConfigFailed(short transactionId, int reason) { Message msg = mHandler.obtainMessage(MESSAGE_ON_CONFIG_FAILED); - msg.arg1 = reason; + msg.arg1 = transactionId; + msg.arg2 = reason; mHandler.sendMessage(msg); } @@ -335,32 +335,44 @@ public class WifiNanStateManager { @Override public void handleMessage(Message msg) { - if (DBG) Log.d(TAG, "Message: " + msg.what); + if (DBG) { + Log.d(TAG, "Message: " + msg.what); + } switch (msg.what) { case MESSAGE_CONNECT: { - if (VDBG) Log.d(TAG, "NAN connection request received"); + if (VDBG) { + Log.d(TAG, "NAN connection request received"); + } connectLocal(msg.arg1, (IWifiNanEventListener) msg.obj, msg.arg2); break; } case MESSAGE_DISCONNECT: { - if (VDBG) Log.d(TAG, "NAN disconnection request received"); + if (VDBG) { + Log.d(TAG, "NAN disconnection request received"); + } disconnectLocal(msg.arg1); break; } case MESSAGE_REQUEST_CONFIG: { - if (VDBG) Log.d(TAG, "NAN configuration request received"); + if (VDBG) { + Log.d(TAG, "NAN configuration request received"); + } requestConfigLocal(msg.arg1, (ConfigRequest) msg.obj); break; } case MESSAGE_CREATE_SESSION: { - if (VDBG) Log.d(TAG, "Create session"); + if (VDBG) { + Log.d(TAG, "Create session"); + } int events = msg.getData().getInt(MESSAGE_BUNDLE_KEY_EVENTS); createSessionLocal(msg.arg1, msg.arg2, (IWifiNanSessionListener) msg.obj, events); break; } case MESSAGE_DESTROY_SESSION: { - if (VDBG) Log.d(TAG, "Destroy session"); + if (VDBG) { + Log.d(TAG, "Destroy session"); + } destroySessionLocal(msg.arg1, msg.arg2); break; } @@ -409,7 +421,9 @@ public class WifiNanStateManager { break; } case MESSAGE_STOP_SESSION: { - if (VDBG) Log.d(TAG, "Stop session"); + if (VDBG) { + Log.d(TAG, "Stop session"); + } stopSessionLocal(msg.arg1, msg.arg2); break; } @@ -417,7 +431,7 @@ public class WifiNanStateManager { onConfigCompletedLocal((short) msg.arg1); break; case MESSAGE_ON_CONFIG_FAILED: - onConfigFailedLocal(msg.arg1); + onConfigFailedLocal((short) msg.arg1, msg.arg2); break; case MESSAGE_ON_NAN_DOWN: onNanDownLocal(msg.arg1); @@ -487,6 +501,110 @@ public class WifiNanStateManager { } } + /* + * Transaction management classes & operations + */ + + // non-synchronized (should be ok as long as only used from NanStateManager, + // NanClientState, and NanSessionState) + /* package */ short createNextTransactionId() { + return mNextTransactionId++; + } + + private static class TransactionInfoBase { + short mTransactionId; + } + + private static class TransactionInfoSession extends TransactionInfoBase { + public WifiNanClientState mClient; + public WifiNanSessionState mSession; + } + + private static class TransactionInfoMessage extends TransactionInfoSession { + public int mMessageId; + } + + private static class TransactionInfoConfig extends TransactionInfoBase { + public ConfigRequest mConfig; + } + + private void allocateAndRegisterTransactionId(TransactionInfoBase info) { + info.mTransactionId = createNextTransactionId(); + + mPendingResponses.put(info.mTransactionId, info); + } + + private void fillInTransactionInfoSession(TransactionInfoSession info, int uid, + int sessionId) { + WifiNanClientState client = mClients.get(uid); + if (client == null) { + throw new IllegalStateException( + "getAndRegisterTransactionId: no client exists for uid=" + uid); + } + info.mClient = client; + + WifiNanSessionState session = info.mClient.getSession(sessionId); + if (session == null) { + throw new IllegalStateException( + "getAndRegisterSessionTransactionId: no session exists for uid=" + uid + + ", sessionId=" + sessionId); + } + info.mSession = session; + } + + private TransactionInfoBase createTransactionInfo() { + TransactionInfoBase info = new TransactionInfoBase(); + allocateAndRegisterTransactionId(info); + return info; + } + + private TransactionInfoSession createTransactionInfoSession(int uid, int sessionId) { + TransactionInfoSession info = new TransactionInfoSession(); + fillInTransactionInfoSession(info, uid, sessionId); + allocateAndRegisterTransactionId(info); + return info; + } + + private TransactionInfoMessage createTransactionInfoMessage(int uid, int sessionId, + int messageId) { + TransactionInfoMessage info = new TransactionInfoMessage(); + fillInTransactionInfoSession(info, uid, sessionId); + info.mMessageId = messageId; + allocateAndRegisterTransactionId(info); + return info; + } + + private TransactionInfoConfig createTransactionInfoConfig(ConfigRequest configRequest) { + TransactionInfoConfig info = new TransactionInfoConfig(); + info.mConfig = configRequest; + allocateAndRegisterTransactionId(info); + return info; + } + + private TransactionInfoBase getAndRemovePendingResponseTransactionInfo(short transactionId) { + TransactionInfoBase transInfo = mPendingResponses.get(transactionId); + if (transInfo != null) { + mPendingResponses.remove(transactionId); + } + + return transInfo; + } + + private WifiNanSessionState getNanSessionStateForPubSubId(int pubSubId) { + for (int i = 0; i < mClients.size(); ++i) { + WifiNanSessionState session = mClients.valueAt(i) + .getNanSessionStateForPubSubId(pubSubId); + if (session != null) { + return session; + } + } + + return null; + } + + /* + * Actions (calls from API to service) + */ private void connectLocal(int uid, IWifiNanEventListener listener, int events) { if (VDBG) { Log.v(TAG, "connect(): uid=" + uid + ", listener=" + listener + ", events=" + events); @@ -502,7 +620,9 @@ public class WifiNanStateManager { } private void disconnectLocal(int uid) { - if (VDBG) Log.v(TAG, "disconnect(): uid=" + uid); + if (VDBG) { + Log.v(TAG, "disconnect(): uid=" + uid); + } WifiNanClientState client = mClients.get(uid); mClients.delete(uid); @@ -514,30 +634,35 @@ public class WifiNanStateManager { List<Integer> toRemove = new ArrayList<>(); for (int i = 0; i < mPendingResponses.size(); ++i) { - if (mPendingResponses.valueAt(i).mSession.getUid() == uid) { + TransactionInfoBase info = mPendingResponses.valueAt(i); + if (!(info instanceof TransactionInfoSession)) { + continue; + } + if (((TransactionInfoSession) info).mClient.getUid() == uid) { toRemove.add(i); } } for (Integer id : toRemove) { - mPendingResponses.delete(id); + mPendingResponses.removeAt(id); } client.destroy(); if (mClients.size() == 0) { - WifiNanNative.getInstance().disable(getTransactionId()); + WifiNanNative.getInstance().disable(createTransactionInfo().mTransactionId); return; } - short transactionId = getTransactionId(); ConfigRequest merged = mergeConfigRequests(); - mPendingConfigs.put(transactionId, merged); - WifiNanNative.getInstance().enableAndConfigure(transactionId, merged); + WifiNanNative.getInstance() + .enableAndConfigure(createTransactionInfoConfig(merged).mTransactionId, merged); } private void requestConfigLocal(int uid, ConfigRequest configRequest) { - if (VDBG) Log.v(TAG, "requestConfig(): uid=" + uid + ", configRequest=" + configRequest); + if (VDBG) { + Log.v(TAG, "requestConfig(): uid=" + uid + ", configRequest=" + configRequest); + } WifiNanClientState client = mClients.get(uid); if (client == null) { @@ -547,11 +672,10 @@ public class WifiNanStateManager { client.setConfigRequest(configRequest); - short transactionId = getTransactionId(); ConfigRequest merged = mergeConfigRequests(); - mPendingConfigs.put(transactionId, merged); - WifiNanNative.getInstance().enableAndConfigure(transactionId, merged); + WifiNanNative.getInstance() + .enableAndConfigure(createTransactionInfoConfig(merged).mTransactionId, merged); } private void createSessionLocal(int uid, int sessionId, IWifiNanSessionListener listener, @@ -571,7 +695,9 @@ public class WifiNanStateManager { } private void destroySessionLocal(int uid, int sessionId) { - if (VDBG) Log.v(TAG, "destroySession(): uid=" + uid + ", sessionId=" + sessionId); + if (VDBG) { + Log.v(TAG, "destroySession(): uid=" + uid + ", sessionId=" + sessionId); + } WifiNanClientState client = mClients.get(uid); if (client == null) { @@ -581,66 +707,23 @@ public class WifiNanStateManager { List<Integer> toRemove = new ArrayList<>(); for (int i = 0; i < mPendingResponses.size(); ++i) { - WifiNanSessionState session = mPendingResponses.valueAt(i).mSession; - if (session.getUid() == uid && session.getSessionId() == sessionId) { + TransactionInfoBase info = mPendingResponses.valueAt(i); + if (!(info instanceof TransactionInfoSession)) { + continue; + } + TransactionInfoSession infoSession = (TransactionInfoSession) info; + if (infoSession.mClient.getUid() == uid + && infoSession.mSession.getSessionId() == sessionId) { toRemove.add(i); } } for (Integer id : toRemove) { - mPendingResponses.delete(id); + mPendingResponses.removeAt(id); } client.destroySession(sessionId); } - // non-synchronized (should be ok as long as only used from NanStateManager, - // NanClientState, and NanSessionState - /* package */ short getTransactionId() { - return mNextTransactionId++; - } - - private static class TransactionInfo { - // always used - public short mTransactionId; - public WifiNanSessionState mSession; - - // used by some callers - public int mMessageId; - } - - private TransactionInfo getAndRegisterTransactionId(int uid, int sessionId) { - WifiNanClientState client = mClients.get(uid); - if (client == null) { - throw new IllegalStateException( - "getAndRegisterTransactionId: no client exists for uid=" + uid); - } - - WifiNanSessionState session = client.getSession(sessionId); - if (session == null) { - throw new IllegalStateException( - "getAndRegisterTransactionId: no session exists for uid=" + uid + ", sessionId=" - + sessionId); - } - - short transactionId = mNextTransactionId++; - - if (mPendingResponses.get(transactionId) != null) { - throw new IllegalStateException("getAndRegisterTransactionId: pending response " - + "already exists for transactionId=" + transactionId); - } - - TransactionInfo bag = new TransactionInfo(); - bag.mTransactionId = transactionId; - bag.mSession = session; - mPendingResponses.put(transactionId, bag); - - if (DBG) { - Log.d(TAG, "getAndRegisterTransactionId: transaction ID issued - " + transactionId); - } - - return bag; - } - private void publishLocal(int uid, int sessionId, PublishData publishData, PublishSettings publishSettings) { if (VDBG) { @@ -648,15 +731,9 @@ public class WifiNanStateManager { + publishData + ", settings=" + publishSettings); } - TransactionInfo transInfo; - try { - transInfo = getAndRegisterTransactionId(uid, sessionId); - } catch (IllegalStateException e) { - Log.e(TAG, e.toString()); - return; - } + TransactionInfoSession info = createTransactionInfoSession(uid, sessionId); - transInfo.mSession.publish(transInfo.mTransactionId, publishData, publishSettings); + info.mSession.publish(info.mTransactionId, publishData, publishSettings); } private void subscribeLocal(int uid, int sessionId, SubscribeData subscribeData, @@ -666,16 +743,9 @@ public class WifiNanStateManager { + subscribeData + ", settings=" + subscribeSettings); } - TransactionInfo transInfo; - try { - transInfo = getAndRegisterTransactionId(uid, sessionId); - - } catch (IllegalStateException e) { - Log.e(TAG, e.toString()); - return; - } + TransactionInfoSession info = createTransactionInfoSession(uid, sessionId); - transInfo.mSession.subscribe(transInfo.mTransactionId, subscribeData, subscribeSettings); + info.mSession.subscribe(info.mTransactionId, subscribeData, subscribeSettings); } private void sendFollowonMessageLocal(int uid, int sessionId, int peerId, byte[] message, @@ -685,59 +755,83 @@ public class WifiNanStateManager { + peerId + ", messageLength=" + messageLength + ", messageId=" + messageId); } - TransactionInfo transInfo; - try { - transInfo = getAndRegisterTransactionId(uid, sessionId); - } catch (IllegalStateException e) { - Log.e(TAG, e.toString()); - return; - } + TransactionInfoMessage info = createTransactionInfoMessage(uid, sessionId, messageId); - transInfo.mMessageId = messageId; - transInfo.mSession.sendMessage(transInfo.mTransactionId, peerId, message, messageLength, - messageId); + info.mSession.sendMessage(info.mTransactionId, peerId, message, messageLength, messageId); } private void stopSessionLocal(int uid, int sessionId) { - if (VDBG) Log.v(TAG, "stopSession(): uid=" + uid + ", sessionId=" + sessionId); - - TransactionInfo transInfo; - try { - transInfo = getAndRegisterTransactionId(uid, sessionId); - } catch (IllegalStateException e) { - Log.e(TAG, e.toString()); - return; + if (VDBG) { + Log.v(TAG, "stopSession(): uid=" + uid + ", sessionId=" + sessionId); } - transInfo.mSession.stop(transInfo.mTransactionId); + TransactionInfoSession info = createTransactionInfoSession(uid, sessionId); + + info.mSession.stop(info.mTransactionId); } - // events for all clients + /* + * Callbacks (calls from HAL/Native to service) + */ private void onConfigCompletedLocal(short transactionId) { - if (VDBG) Log.v(TAG, "onConfigCompleted: transactionId=" + transactionId); + if (VDBG) { + Log.v(TAG, "onConfigCompleted: transactionId=" + transactionId); + } - ConfigRequest request = mPendingConfigs.get(transactionId); - if (DBG) Log.d(TAG, "onConfigCompleted: request=" + request); - mPendingConfigs.delete(transactionId); + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { + Log.e(TAG, "onConfigCompleted: no transaction info for transactionId=" + transactionId); + return; + } + if (!(info instanceof TransactionInfoConfig)) { + Log.e(TAG, "onConfigCompleted: invalid info structure stored for transactionId=" + + transactionId); + return; + } + TransactionInfoConfig infoConfig = (TransactionInfoConfig) info; + + if (DBG) { + Log.d(TAG, "onConfigCompleted: request=" + infoConfig.mConfig); + } for (int i = 0; i < mClients.size(); ++i) { WifiNanClientState client = mClients.valueAt(i); - client.onConfigCompleted(request); + client.onConfigCompleted(infoConfig.mConfig); } } - private void onConfigFailedLocal(int reason) { - if (VDBG) Log.v(TAG, "onEnableFailed: reason=" + reason); + private void onConfigFailedLocal(short transactionId, int reason) { + if (VDBG) { + Log.v(TAG, "onEnableFailed: transactionId=" + transactionId + ", reason=" + reason); + } + + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { + Log.e(TAG, "onConfigFailed: no transaction info for transactionId=" + transactionId); + return; + } + if (!(info instanceof TransactionInfoConfig)) { + Log.e(TAG, "onConfigCompleted: invalid info structure stored for transactionId=" + + transactionId); + return; + } + TransactionInfoConfig infoConfig = (TransactionInfoConfig) info; + + if (DBG) { + Log.d(TAG, "onConfigFailed: request=" + infoConfig.mConfig); + } for (int i = 0; i < mClients.size(); ++i) { WifiNanClientState client = mClients.valueAt(i); - client.onConfigFailed(reason); + client.onConfigFailed(infoConfig.mConfig, reason); } } private void onNanDownLocal(int reason) { - if (VDBG) Log.v(TAG, "onNanDown: reason=" + reason); + if (VDBG) { + Log.v(TAG, "onNanDown: reason=" + reason); + } int interested = 0; for (int i = 0; i < mClients.size(); ++i) { @@ -786,29 +880,25 @@ public class WifiNanStateManager { } } - // events targeted to a single client+session - private TransactionInfo getAndRemovePendingResponseSession(short transactionId) { - TransactionInfo transInfo = mPendingResponses.get(transactionId); - if (transInfo != null) { - mPendingResponses.remove(transactionId); - } - - return transInfo; - } - private void onPublishSuccessLocal(short transactionId, int publishId) { if (VDBG) { Log.v(TAG, "onPublishSuccess: transactionId=" + transactionId + ", publishId=" + publishId); } - TransactionInfo transInfo = getAndRemovePendingResponseSession(transactionId); - if (transInfo == null) { + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { Log.e(TAG, "onPublishSuccess(): no info registered for transactionId=" + transactionId); return; } + if (!(info instanceof TransactionInfoSession)) { + Log.e(TAG, "onPublishSuccess: invalid info structure stored for transactionId=" + + transactionId); + return; + } + TransactionInfoSession infoSession = (TransactionInfoSession) info; - transInfo.mSession.onPublishSuccess(publishId); + infoSession.mSession.onPublishSuccess(publishId); } private void onPublishFailLocal(short transactionId, int status) { @@ -816,19 +906,27 @@ public class WifiNanStateManager { Log.v(TAG, "onPublishFail: transactionId=" + transactionId + ", status=" + status); } - TransactionInfo transInfo = getAndRemovePendingResponseSession(transactionId); - if (transInfo == null) { + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { Log.e(TAG, "onPublishFail(): no info registered for transactionId=" + transactionId); return; } + if (!(info instanceof TransactionInfoSession)) { + Log.e(TAG, "onPublishFail: invalid info structure stored for transactionId=" + + transactionId); + return; + } + TransactionInfoSession infoSession = (TransactionInfoSession) info; - transInfo.mSession.onPublishFail(status); + infoSession.mSession.onPublishFail(status); } private void onPublishTerminatedLocal(int publishId, int status) { - if (VDBG) Log.v(TAG, "onPublishTerminated: publishId=" + publishId + ", status=" + status); + if (VDBG) { + Log.v(TAG, "onPublishTerminated: publishId=" + publishId + ", status=" + status); + } - WifiNanSessionState session = WifiNanSessionState.getNanSessionStateForPubSubId(publishId); + WifiNanSessionState session = getNanSessionStateForPubSubId(publishId); if (session == null) { Log.e(TAG, "onPublishTerminated: no session found for publishId=" + publishId); return; @@ -843,14 +941,20 @@ public class WifiNanStateManager { + subscribeId); } - TransactionInfo transInfo = getAndRemovePendingResponseSession(transactionId); - if (transInfo == null) { + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { Log.e(TAG, "onSubscribeSuccess(): no info registered for transactionId=" + transactionId); return; } + if (!(info instanceof TransactionInfoSession)) { + Log.e(TAG, "onSubscribeSuccess: invalid info structure stored for transactionId=" + + transactionId); + return; + } + TransactionInfoSession infoSession = (TransactionInfoSession) info; - transInfo.mSession.onSubscribeSuccess(subscribeId); + infoSession.mSession.onSubscribeSuccess(subscribeId); } private void onSubscribeFailLocal(short transactionId, int status) { @@ -858,13 +962,19 @@ public class WifiNanStateManager { Log.v(TAG, "onSubscribeFail: transactionId=" + transactionId + ", status=" + status); } - TransactionInfo transInfo = getAndRemovePendingResponseSession(transactionId); - if (transInfo == null) { + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { Log.e(TAG, "onSubscribeFail(): no info registered for transactionId=" + transactionId); return; } + if (!(info instanceof TransactionInfoSession)) { + Log.e(TAG, "onSubscribeFail: invalid info structure stored for transactionId=" + + transactionId); + return; + } + TransactionInfoSession infoSession = (TransactionInfoSession) info; - transInfo.mSession.onSubscribeFail(status); + infoSession.mSession.onSubscribeFail(status); } private void onSubscribeTerminatedLocal(int subscribeId, int status) { @@ -872,8 +982,7 @@ public class WifiNanStateManager { Log.v(TAG, "onPublishTerminated: subscribeId=" + subscribeId + ", status=" + status); } - WifiNanSessionState session = WifiNanSessionState - .getNanSessionStateForPubSubId(subscribeId); + WifiNanSessionState session = getNanSessionStateForPubSubId(subscribeId); if (session == null) { Log.e(TAG, "onSubscribeTerminated: no session found for subscribeId=" + subscribeId); return; @@ -883,16 +992,24 @@ public class WifiNanStateManager { } private void onMessageSendSuccessLocal(short transactionId) { - if (VDBG) Log.v(TAG, "onMessageSendSuccess: transactionId=" + transactionId); + if (VDBG) { + Log.v(TAG, "onMessageSendSuccess: transactionId=" + transactionId); + } - TransactionInfo transInfo = getAndRemovePendingResponseSession(transactionId); - if (transInfo == null) { + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { Log.e(TAG, "onMessageSendSuccess(): no info registered for transactionId=" + transactionId); return; } + if (!(info instanceof TransactionInfoMessage)) { + Log.e(TAG, "onMessageSendSuccess: invalid info structure stored for transactionId=" + + transactionId); + return; + } + TransactionInfoMessage infoMessage = (TransactionInfoMessage) info; - transInfo.mSession.onMessageSendSuccess(transInfo.mMessageId); + infoMessage.mSession.onMessageSendSuccess(infoMessage.mMessageId); } private void onMessageSendFailLocal(short transactionId, int status) { @@ -900,22 +1017,28 @@ public class WifiNanStateManager { Log.v(TAG, "onMessageSendFail: transactionId=" + transactionId + ", status=" + status); } - TransactionInfo transInfo = getAndRemovePendingResponseSession(transactionId); - if (transInfo == null) { + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { Log.e(TAG, "onMessageSendFail(): no info registered for transactionId=" + transactionId); return; } + if (!(info instanceof TransactionInfoMessage)) { + Log.e(TAG, "onMessageSendFail: invalid info structure stored for transactionId=" + + transactionId); + return; + } + TransactionInfoMessage infoMessage = (TransactionInfoMessage) info; - transInfo.mSession.onMessageSendFail(transInfo.mMessageId, status); + infoMessage.mSession.onMessageSendFail(infoMessage.mMessageId, status); } private void onUnknownTransactionLocal(int responseType, short transactionId, int status) { Log.e(TAG, "onUnknownTransaction: responseType=" + responseType + ", transactionId=" + transactionId + ", status=" + status); - TransactionInfo transInfo = getAndRemovePendingResponseSession(transactionId); - if (transInfo == null) { + TransactionInfoBase info = getAndRemovePendingResponseTransactionInfo(transactionId); + if (info == null) { Log.e(TAG, "onUnknownTransaction(): no info registered for transactionId=" + transactionId); } @@ -932,7 +1055,7 @@ public class WifiNanStateManager { + ", matchFilterLength=" + matchFilterLength + ", matchFilter=" + matchFilter); } - WifiNanSessionState session = WifiNanSessionState.getNanSessionStateForPubSubId(pubSubId); + WifiNanSessionState session = getNanSessionStateForPubSubId(pubSubId); if (session == null) { Log.e(TAG, "onMatch: no session found for pubSubId=" + pubSubId); return; @@ -952,7 +1075,7 @@ public class WifiNanStateManager { + messageLength); } - WifiNanSessionState session = WifiNanSessionState.getNanSessionStateForPubSubId(pubSubId); + WifiNanSessionState session = getNanSessionStateForPubSubId(pubSubId); if (session == null) { Log.e(TAG, "onMessageReceived: no session found for pubSubId=" + pubSubId); return; @@ -962,7 +1085,9 @@ public class WifiNanStateManager { } private ConfigRequest mergeConfigRequests() { - if (VDBG) Log.v(TAG, "mergeConfigRequests(): mClients=[" + mClients + "]"); + if (VDBG) { + Log.v(TAG, "mergeConfigRequests(): mClients=[" + mClients + "]"); + } if (mClients.size() == 0) { Log.e(TAG, "mergeConfigRequests: invalid state - called with 0 clients registered!"); @@ -1014,11 +1139,9 @@ public class WifiNanStateManager { pw.println("NanStateManager:"); pw.println(" mClients: [" + mClients + "]"); pw.println(" mPendingResponses: [" + mPendingResponses + "]"); - pw.println(" mPendingConfigs: [" + mPendingConfigs + "]"); pw.println(" mNextTransactionId: " + mNextTransactionId); for (int i = 0; i < mClients.size(); ++i) { mClients.valueAt(i).dump(fd, pw, args); } - WifiNanSessionState.dumpS(fd, pw, args); } } diff --git a/tests/wifitests/jni/wifi_hal_mock.cpp b/tests/wifitests/jni/wifi_hal_mock.cpp index 38b2fa711..36b0bd39f 100644 --- a/tests/wifitests/jni/wifi_hal_mock.cpp +++ b/tests/wifitests/jni/wifi_hal_mock.cpp @@ -40,7 +40,7 @@ jobject mock_mObj; /* saved HalMock object (not class!) */ JavaVM* mock_mVM = NULL; /* saved JVM pointer */ /* Variable and function declared and defined in: - * com_android_servier_wifi_nan_WifiNanNative.cpp + * com_android_server_wifi_nan_WifiNanNative.cpp */ extern wifi_hal_fn hal_fn; extern "C" jint Java_com_android_server_wifi_WifiNative_registerNatives( @@ -180,7 +180,7 @@ int init_wifi_hal_func_table_mock(wifi_hal_fn *hal_fn) { return 0; } -extern "C" jint Java_wifitests_src_com_android_server_wifi_HalMockUtils_initHalMock( +extern "C" jint Java_com_android_server_wifi_HalMockUtils_initHalMock( JNIEnv* env, jclass clazz) { env->GetJavaVM(&mock_mVM); @@ -188,7 +188,7 @@ extern "C" jint Java_wifitests_src_com_android_server_wifi_HalMockUtils_initHalM return init_wifi_hal_func_table_mock(&hal_fn); } -extern "C" void Java_wifitests_src_com_android_server_wifi_HalMockUtils_setHalMockObject( +extern "C" void Java_com_android_server_wifi_HalMockUtils_setHalMockObject( JNIEnv* env, jclass clazz, jobject hal_mock_object) { mock_mObj = (jobject) env->NewGlobalRef(hal_mock_object); } diff --git a/tests/wifitests/src/com/android/server/wifi/HalMockUtils.java b/tests/wifitests/src/com/android/server/wifi/HalMockUtils.java index 52339356d..6e485f614 100644 --- a/tests/wifitests/src/com/android/server/wifi/HalMockUtils.java +++ b/tests/wifitests/src/com/android/server/wifi/HalMockUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package wifitests.src.com.android.server.wifi; +package com.android.server.wifi; import android.os.Bundle; import android.util.Log; diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalTest.java index e661fd280..e80ccd006 100644 --- a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalTest.java +++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanHalTest.java @@ -31,6 +31,7 @@ import android.net.wifi.nan.WifiNanSessionListener; import android.os.Bundle; import android.test.suitebuilder.annotation.SmallTest; +import com.android.server.wifi.HalMockUtils; import com.android.server.wifi.WifiNative; import libcore.util.HexEncoding; @@ -47,8 +48,6 @@ import org.mockito.MockitoAnnotations; import java.lang.reflect.Field; import java.util.Arrays; -import wifitests.src.com.android.server.wifi.HalMockUtils; - /** * Unit test harness for WifiNanNative + JNI code interfacing to the HAL. */ @@ -273,7 +272,8 @@ public class WifiNanHalTest { WifiNanHalMock.callNotifyResponse(transactionId, HalMockUtils.convertBundleToJson(args).toString()); - verify(mNanStateManager).onConfigFailed(WifiNanSessionListener.FAIL_REASON_INVALID_ARGS); + verify(mNanStateManager).onConfigFailed(transactionId, + WifiNanSessionListener.FAIL_REASON_INVALID_ARGS); } @Test @@ -524,10 +524,9 @@ public class WifiNanHalTest { private void testEnable(short transactionId, int clusterLow, int clusterHigh, int masterPref, boolean enable5g) throws JSONException { - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setClusterLow(clusterLow).setClusterHigh(clusterHigh) - .setMasterPreference(masterPref).setSupport5gBand(enable5g); - ConfigRequest configRequest = builder.build(); + ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow) + .setClusterHigh(clusterHigh).setMasterPreference(masterPref) + .setSupport5gBand(enable5g).build(); mDut.enableAndConfigure(transactionId, configRequest); @@ -582,15 +581,13 @@ public class WifiNanHalTest { String serviceName, String ssi, TlvBufferUtils.TlvConstructor tlvTx, TlvBufferUtils.TlvConstructor tlvRx, int publishCount, int publishTtl) throws JSONException { - PublishData.Builder builderD = new PublishData.Builder(); - builderD.setServiceName(serviceName).setServiceSpecificInfo(ssi) + PublishData publishData = new PublishData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi) .setTxFilter(tlvTx.getArray(), tlvTx.getActualLength()) - .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()); - PublishData publishData = builderD.build(); + .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()).build(); - PublishSettings.Builder builderS = new PublishSettings.Builder(); - builderS.setPublishType(publishType).setPublishCount(publishCount).setTtlSec(publishTtl); - PublishSettings publishSettings = builderS.build(); + PublishSettings publishSettings = new PublishSettings.Builder().setPublishType(publishType) + .setPublishCount(publishCount).setTtlSec(publishTtl).build(); mDut.publish(transactionId, publishId, publishData, publishSettings); @@ -632,16 +629,14 @@ public class WifiNanHalTest { String serviceName, String ssi, TlvBufferUtils.TlvConstructor tlvTx, TlvBufferUtils.TlvConstructor tlvRx, int subscribeCount, int subscribeTtl) throws JSONException { - SubscribeData.Builder builderD = new SubscribeData.Builder(); - builderD.setServiceName(serviceName).setServiceSpecificInfo(ssi) + SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi) .setTxFilter(tlvTx.getArray(), tlvTx.getActualLength()) - .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()); - SubscribeData subscribeData = builderD.build(); + .setRxFilter(tlvRx.getArray(), tlvRx.getActualLength()).build(); - SubscribeSettings.Builder builderS = new SubscribeSettings.Builder(); - builderS.setSubscribeType(subscribeType).setSubscribeCount(subscribeCount) - .setTtlSec(subscribeTtl); - SubscribeSettings subscribeSettings = builderS.build(); + SubscribeSettings subscribeSettings = new SubscribeSettings.Builder() + .setSubscribeType(subscribeType).setSubscribeCount(subscribeCount) + .setTtlSec(subscribeTtl).build(); mDut.subscribe(transactionId, subscribeId, subscribeData, subscribeSettings); @@ -691,7 +686,7 @@ public class WifiNanHalTest { private static void installMockNanStateManager(WifiNanStateManager nanStateManager) throws Exception { - Field field = WifiNanStateManager.class.getDeclaredField("sNanStatemanagerSingleton"); + Field field = WifiNanStateManager.class.getDeclaredField("sNanStateManagerSingleton"); field.setAccessible(true); field.set(null, nanStateManager); } diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanManagerTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanManagerTest.java index 28c0de717..bd4d43bd0 100644 --- a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanManagerTest.java @@ -54,12 +54,9 @@ public class WifiNanManagerTest { final int masterPreference = 55; final boolean supportBand5g = true; - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setClusterHigh(clusterHigh); - builder.setClusterLow(clusterLow); - builder.setMasterPreference(masterPreference); - builder.setSupport5gBand(supportBand5g); - ConfigRequest configRequest = builder.build(); + ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh) + .setClusterLow(clusterLow).setMasterPreference(masterPreference) + .setSupport5gBand(supportBand5g).build(); collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh)); collector.checkThat("mClusterLow", clusterLow, equalTo(configRequest.mClusterLow)); @@ -78,60 +75,50 @@ public class WifiNanManagerTest { @Test public void testConfigRequestBuilderMasterPrefReserved1() { thrown.expect(IllegalArgumentException.class); - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setMasterPreference(1); + new ConfigRequest.Builder().setMasterPreference(1); } @Test public void testConfigRequestBuilderMasterPrefReserved255() { thrown.expect(IllegalArgumentException.class); - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setMasterPreference(255); + new ConfigRequest.Builder().setMasterPreference(255); } @Test public void testConfigRequestBuilderMasterPrefTooLarge() { thrown.expect(IllegalArgumentException.class); - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setMasterPreference(256); + new ConfigRequest.Builder().setMasterPreference(256); } @Test public void testConfigRequestBuilderClusterLowNegative() { thrown.expect(IllegalArgumentException.class); - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setClusterLow(-1); + new ConfigRequest.Builder().setClusterLow(-1); } @Test public void testConfigRequestBuilderClusterHighNegative() { thrown.expect(IllegalArgumentException.class); - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setClusterHigh(-1); + new ConfigRequest.Builder().setClusterHigh(-1); } @Test public void testConfigRequestBuilderClusterLowAboveMax() { thrown.expect(IllegalArgumentException.class); - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setClusterLow(ConfigRequest.CLUSTER_ID_MAX + 1); + new ConfigRequest.Builder().setClusterLow(ConfigRequest.CLUSTER_ID_MAX + 1); } @Test public void testConfigRequestBuilderClusterHighAboveMax() { thrown.expect(IllegalArgumentException.class); - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setClusterHigh(ConfigRequest.CLUSTER_ID_MAX + 1); + new ConfigRequest.Builder().setClusterHigh(ConfigRequest.CLUSTER_ID_MAX + 1); } @Test public void testConfigRequestBuilderClusterLowLargerThanHigh() { thrown.expect(IllegalArgumentException.class); - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - - builder.setClusterLow(100); - builder.setClusterHigh(5); - ConfigRequest configRequest = builder.build(); + ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(100) + .setClusterHigh(5).build(); } @Test @@ -141,12 +128,9 @@ public class WifiNanManagerTest { final int masterPreference = 177; final boolean supportBand5g = true; - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - builder.setClusterHigh(clusterHigh); - builder.setClusterLow(clusterLow); - builder.setMasterPreference(masterPreference); - builder.setSupport5gBand(supportBand5g); - ConfigRequest configRequest = builder.build(); + ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh) + .setClusterLow(clusterLow).setMasterPreference(masterPreference) + .setSupport5gBand(supportBand5g).build(); Parcel parcelW = Parcel.obtain(); configRequest.writeToParcel(parcelW, 0); @@ -174,12 +158,9 @@ public class WifiNanManagerTest { final byte[] rxFilter = { 1, 127, 0, 1, -5, 1, 22 }; - SubscribeData.Builder builder = new SubscribeData.Builder(); - builder.setServiceName(serviceName); - builder.setServiceSpecificInfo(serviceSpecificInfo); - builder.setTxFilter(txFilter, txFilter.length); - builder.setRxFilter(rxFilter, rxFilter.length); - SubscribeData subscribeData = builder.build(); + SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length) + .setRxFilter(rxFilter, rxFilter.length).build(); collector.checkThat("mServiceName", serviceName, equalTo(subscribeData.mServiceName)); String mServiceSpecificInfo = new String(subscribeData.mServiceSpecificInfo, 0, @@ -204,12 +185,9 @@ public class WifiNanManagerTest { final byte[] rxFilter = { 1, 127, 0, 1, -5, 1, 22 }; - SubscribeData.Builder builder = new SubscribeData.Builder(); - builder.setServiceName(serviceName); - builder.setServiceSpecificInfo(serviceSpecificInfo); - builder.setTxFilter(txFilter, txFilter.length); - builder.setTxFilter(rxFilter, rxFilter.length); - SubscribeData subscribeData = builder.build(); + SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length) + .setTxFilter(rxFilter, rxFilter.length).build(); Parcel parcelW = Parcel.obtain(); subscribeData.writeToParcel(parcelW, 0); @@ -234,11 +212,9 @@ public class WifiNanManagerTest { final int subscribeCount = 10; final int subscribeTtl = 15; - SubscribeSettings.Builder builder = new SubscribeSettings.Builder(); - builder.setSubscribeType(subscribeType); - builder.setSubscribeCount(subscribeCount); - builder.setTtlSec(subscribeTtl); - SubscribeSettings subscribeSetting = builder.build(); + SubscribeSettings subscribeSetting = new SubscribeSettings.Builder() + .setSubscribeType(subscribeType).setSubscribeCount(subscribeCount) + .setTtlSec(subscribeTtl).build(); collector.checkThat("mSubscribeType", subscribeType, equalTo(subscribeSetting.mSubscribeType)); @@ -250,22 +226,19 @@ public class WifiNanManagerTest { @Test public void testSubscribeSettingsBuilderBadSubscribeType() { thrown.expect(IllegalArgumentException.class); - SubscribeSettings.Builder builder = new SubscribeSettings.Builder(); - builder.setSubscribeType(10); + new SubscribeSettings.Builder().setSubscribeType(10); } @Test public void testSubscribeSettingsBuilderNegativeCount() { thrown.expect(IllegalArgumentException.class); - SubscribeSettings.Builder builder = new SubscribeSettings.Builder(); - builder.setSubscribeCount(-1); + new SubscribeSettings.Builder().setSubscribeCount(-1); } @Test public void testSubscribeSettingsBuilderNegativeTtl() { thrown.expect(IllegalArgumentException.class); - SubscribeSettings.Builder builder = new SubscribeSettings.Builder(); - builder.setTtlSec(-100); + new SubscribeSettings.Builder().setTtlSec(-100); } @Test @@ -274,11 +247,9 @@ public class WifiNanManagerTest { final int subscribeCount = 10; final int subscribeTtl = 15; - SubscribeSettings.Builder builder = new SubscribeSettings.Builder(); - builder.setSubscribeType(subscribeType); - builder.setSubscribeCount(subscribeCount); - builder.setTtlSec(subscribeTtl); - SubscribeSettings subscribeSetting = builder.build(); + SubscribeSettings subscribeSetting = new SubscribeSettings.Builder() + .setSubscribeType(subscribeType).setSubscribeCount(subscribeCount) + .setTtlSec(subscribeTtl).build(); Parcel parcelW = Parcel.obtain(); subscribeSetting.writeToParcel(parcelW, 0); @@ -307,12 +278,9 @@ public class WifiNanManagerTest { final byte[] rxFilter = { 1, 127, 0, 1, -5, 1, 22 }; - PublishData.Builder builder = new PublishData.Builder(); - builder.setServiceName(serviceName); - builder.setServiceSpecificInfo(serviceSpecificInfo); - builder.setTxFilter(txFilter, txFilter.length); - builder.setRxFilter(rxFilter, rxFilter.length); - PublishData publishData = builder.build(); + PublishData publishData = new PublishData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length) + .setRxFilter(rxFilter, rxFilter.length).build(); collector.checkThat("mServiceName", serviceName, equalTo(publishData.mServiceName)); String mServiceSpecificInfo = new String(publishData.mServiceSpecificInfo, 0, @@ -336,12 +304,9 @@ public class WifiNanManagerTest { final byte[] rxFilter = { 1, 127, 0, 1, -5, 1, 22 }; - PublishData.Builder builder = new PublishData.Builder(); - builder.setServiceName(serviceName); - builder.setServiceSpecificInfo(serviceSpecificInfo); - builder.setTxFilter(txFilter, txFilter.length); - builder.setTxFilter(rxFilter, rxFilter.length); - PublishData publishData = builder.build(); + PublishData publishData = new PublishData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(serviceSpecificInfo).setTxFilter(txFilter, txFilter.length) + .setTxFilter(rxFilter, rxFilter.length).build(); Parcel parcelW = Parcel.obtain(); publishData.writeToParcel(parcelW, 0); @@ -366,11 +331,8 @@ public class WifiNanManagerTest { final int publishCount = 10; final int publishTtl = 15; - PublishSettings.Builder builder = new PublishSettings.Builder(); - builder.setPublishType(publishType); - builder.setPublishCount(publishCount); - builder.setTtlSec(publishTtl); - PublishSettings publishSetting = builder.build(); + PublishSettings publishSetting = new PublishSettings.Builder().setPublishType(publishType) + .setPublishCount(publishCount).setTtlSec(publishTtl).build(); collector.checkThat("mPublishType", publishType, equalTo(publishSetting.mPublishType)); collector.checkThat("mPublishCount", publishCount, equalTo(publishSetting.mPublishCount)); @@ -380,22 +342,19 @@ public class WifiNanManagerTest { @Test public void testPublishSettingsBuilderBadPublishType() { thrown.expect(IllegalArgumentException.class); - PublishSettings.Builder builder = new PublishSettings.Builder(); - builder.setPublishType(5); + new PublishSettings.Builder().setPublishType(5); } @Test public void testPublishSettingsBuilderNegativeCount() { thrown.expect(IllegalArgumentException.class); - PublishSettings.Builder builder = new PublishSettings.Builder(); - builder.setPublishCount(-4); + new PublishSettings.Builder().setPublishCount(-4); } @Test public void testPublishSettingsBuilderNegativeTtl() { thrown.expect(IllegalArgumentException.class); - PublishSettings.Builder builder = new PublishSettings.Builder(); - builder.setTtlSec(-10); + new PublishSettings.Builder().setTtlSec(-10); } @Test @@ -404,11 +363,8 @@ public class WifiNanManagerTest { final int publishCount = 10; final int publishTtl = 15; - PublishSettings.Builder builder = new PublishSettings.Builder(); - builder.setPublishType(publishType); - builder.setPublishCount(publishCount); - builder.setTtlSec(publishTtl); - PublishSettings configSetting = builder.build(); + PublishSettings configSetting = new PublishSettings.Builder().setPublishType(publishType) + .setPublishCount(publishCount).setTtlSec(publishTtl).build(); Parcel parcelW = Parcel.obtain(); configSetting.writeToParcel(parcelW, 0); diff --git a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanStateManagerTest.java index a3dd6dd80..49abd271d 100644 --- a/tests/wifitests/src/com/android/server/wifi/nan/WifiNanStateManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/nan/WifiNanStateManagerTest.java @@ -17,7 +17,8 @@ package com.android.server.wifi.nan; import static org.hamcrest.core.IsEqual.equalTo; -import static org.mockito.Matchers.any; +import static org.hamcrest.core.IsNull.nullValue; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyShort; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.inOrder; @@ -35,6 +36,7 @@ import android.net.wifi.nan.SubscribeSettings; import android.net.wifi.nan.WifiNanEventListener; import android.net.wifi.nan.WifiNanSessionListener; import android.test.suitebuilder.annotation.SmallTest; +import android.util.SparseArray; import com.android.server.wifi.MockLooper; @@ -70,7 +72,7 @@ public class WifiNanStateManagerTest { mMockLooper = new MockLooper(); - mDut = installNewNanStateManager(); + mDut = installNewNanStateManagerAndResetState(); mDut.start(mMockLooper.getLooper()); installMockWifiNanNative(mMockNative); @@ -78,54 +80,107 @@ public class WifiNanStateManagerTest { @Test public void testNanEventsDelivered() throws Exception { - final short transactionId = 1024; final int uid = 1005; + final int clusterLow1 = 5; + final int clusterHigh1 = 100; + final int masterPref1 = 111; + final int clusterLow2 = 7; + final int clusterHigh2 = 155; + final int masterPref2 = 0; final int reason = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES; final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false); + ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow1) + .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1).build(); + + ConfigRequest configRequest2 = new ConfigRequest.Builder().setClusterLow(clusterLow2) + .setClusterHigh(clusterHigh2).setMasterPreference(masterPref2).build(); + IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class); - InOrder inOrder = inOrder(mockListener); + ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); + InOrder inOrder = inOrder(mockListener, mMockNative); mDut.connect(uid, mockListener, WifiNanEventListener.LISTEN_CONFIG_COMPLETED | WifiNanEventListener.LISTEN_CONFIG_FAILED | WifiNanEventListener.LISTEN_IDENTITY_CHANGED | WifiNanEventListener.LISTEN_NAN_DOWN); + mDut.requestConfig(uid, configRequest1); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest1)); + short transactionId1 = transactionId.getValue(); + + mDut.requestConfig(uid, configRequest2); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest2)); + short transactionId2 = transactionId.getValue(); + mDut.onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, someMac); - mDut.onConfigCompleted(transactionId); - mDut.onConfigFailed(reason); + mDut.onConfigCompleted(transactionId1); + mDut.onConfigFailed(transactionId2, reason); mDut.onInterfaceAddressChange(someMac); mDut.onNanDown(reason); mMockLooper.dispatchAll(); inOrder.verify(mockListener).onIdentityChanged(); - inOrder.verify(mockListener).onConfigCompleted(any(ConfigRequest.class)); - inOrder.verify(mockListener).onConfigFailed(reason); + inOrder.verify(mockListener).onConfigCompleted(configRequest1); + inOrder.verify(mockListener).onConfigFailed(configRequest2, reason); inOrder.verify(mockListener).onIdentityChanged(); inOrder.verify(mockListener).onNanDown(reason); verifyNoMoreInteractions(mockListener); - verifyZeroInteractions(mMockNative); + + validateInternalTransactionInfoCleanedUp(transactionId1); + validateInternalTransactionInfoCleanedUp(transactionId2); } @Test public void testNanEventsNotDelivered() throws Exception { - final short transactionId = 1024; final int uid = 1005; + final int clusterLow1 = 5; + final int clusterHigh1 = 100; + final int masterPref1 = 111; + final int clusterLow2 = 7; + final int clusterHigh2 = 155; + final int masterPref2 = 0; final int reason = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES; final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false); + ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow1) + .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1).build(); + + ConfigRequest configRequest2 = new ConfigRequest.Builder().setClusterLow(clusterLow2) + .setClusterHigh(clusterHigh2).setMasterPreference(masterPref2).build(); + IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class); - InOrder inOrder = inOrder(mockListener); + ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); + InOrder inOrder = inOrder(mockListener, mMockNative); mDut.connect(uid, mockListener, 0); + mDut.requestConfig(uid, configRequest1); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest1)); + short transactionId1 = transactionId.getValue(); + + mDut.requestConfig(uid, configRequest2); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest2)); + short transactionId2 = transactionId.getValue(); + mDut.onClusterChange(WifiNanClientState.CLUSTER_CHANGE_EVENT_JOINED, someMac); - mDut.onConfigCompleted(transactionId); - mDut.onConfigFailed(reason); + mDut.onConfigCompleted(transactionId1); + mDut.onConfigFailed(transactionId2, reason); mDut.onInterfaceAddressChange(someMac); mDut.onNanDown(reason); mMockLooper.dispatchAll(); - verifyZeroInteractions(mockListener, mMockNative); + verifyZeroInteractions(mockListener); + + validateInternalTransactionInfoCleanedUp(transactionId1); + validateInternalTransactionInfoCleanedUp(transactionId2); } @Test @@ -137,16 +192,15 @@ public class WifiNanStateManagerTest { final int publishCount = 7; final int reasonFail = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES; final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE; - final int publishId = 15; + final int publishId1 = 15; + final int publishId2 = 22; - PublishData.Builder dataBuilder = new PublishData.Builder(); - dataBuilder.setServiceName(serviceName).setServiceSpecificInfo(ssi); - PublishData publishData = dataBuilder.build(); + PublishData publishData = new PublishData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi).build(); - PublishSettings.Builder settingsBuilder = new PublishSettings.Builder(); - settingsBuilder.setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED) - .setPublishCount(publishCount); - PublishSettings publishSettings = settingsBuilder.build(); + PublishSettings publishSettings = new PublishSettings.Builder() + .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED) + .setPublishCount(publishCount).build(); IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class); ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); @@ -175,6 +229,7 @@ public class WifiNanStateManagerTest { mMockLooper.dispatchAll(); inOrder.verify(mockListener).onPublishFail(reasonFail); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); // publish - success/terminate mDut.publish(uid, sessionId, publishData, publishSettings); @@ -183,11 +238,14 @@ public class WifiNanStateManagerTest { inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData), eq(publishSettings)); - mDut.onPublishSuccess(transactionId.getValue(), publishId); - mDut.onPublishTerminated(publishId, reasonTerminate); + mDut.onPublishSuccess(transactionId.getValue(), publishId1); + mMockLooper.dispatchAll(); + + mDut.onPublishTerminated(publishId1, reasonTerminate); mMockLooper.dispatchAll(); inOrder.verify(mockListener).onPublishTerminated(reasonTerminate); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); // re-publish mDut.publish(uid, sessionId, publishData, publishSettings); @@ -196,11 +254,12 @@ public class WifiNanStateManagerTest { inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData), eq(publishSettings)); - mDut.onPublishSuccess(transactionId.getValue(), publishId); + mDut.onPublishSuccess(transactionId.getValue(), publishId2); mDut.publish(uid, sessionId, publishData, publishSettings); mMockLooper.dispatchAll(); - inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId), + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); + inOrder.verify(mMockNative).publish(transactionId.capture(), eq(publishId2), eq(publishData), eq(publishSettings)); verifyNoMoreInteractions(mockListener, mMockNative); } @@ -216,14 +275,12 @@ public class WifiNanStateManagerTest { final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE; final int publishId = 15; - PublishData.Builder dataBuilder = new PublishData.Builder(); - dataBuilder.setServiceName(serviceName).setServiceSpecificInfo(ssi); - PublishData publishData = dataBuilder.build(); + PublishData publishData = new PublishData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi).build(); - PublishSettings.Builder settingsBuilder = new PublishSettings.Builder(); - settingsBuilder.setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED) - .setPublishCount(publishCount); - PublishSettings publishSettings = settingsBuilder.build(); + PublishSettings publishSettings = new PublishSettings.Builder() + .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED) + .setPublishCount(publishCount).build(); IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class); ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); @@ -253,6 +310,8 @@ public class WifiNanStateManagerTest { mDut.onPublishFail(transactionId.getValue(), reasonFail); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); + // publish - success/terminate mDut.publish(uid, sessionId, publishData, publishSettings); mMockLooper.dispatchAll(); @@ -261,9 +320,12 @@ public class WifiNanStateManagerTest { eq(publishSettings)); mDut.onPublishSuccess(transactionId.getValue(), publishId); + mMockLooper.dispatchAll(); + mDut.onPublishTerminated(publishId, reasonTerminate); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); verifyNoMoreInteractions(mockListener, mMockNative); } @@ -276,16 +338,15 @@ public class WifiNanStateManagerTest { final int subscribeCount = 7; final int reasonFail = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES; final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE; - final int subscribeId = 15; + final int subscribeId1 = 15; + final int subscribeId2 = 10; - SubscribeData.Builder dataBuilder = new SubscribeData.Builder(); - dataBuilder.setServiceName(serviceName).setServiceSpecificInfo(ssi); - SubscribeData subscribeData = dataBuilder.build(); + SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi).build(); - SubscribeSettings.Builder settingsBuilder = new SubscribeSettings.Builder(); - settingsBuilder.setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE) - .setSubscribeCount(subscribeCount); - SubscribeSettings subscribeSettings = settingsBuilder.build(); + SubscribeSettings subscribeSettings = new SubscribeSettings.Builder() + .setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE) + .setSubscribeCount(subscribeCount).build(); IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class); ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); @@ -313,6 +374,7 @@ public class WifiNanStateManagerTest { mDut.onSubscribeFail(transactionId.getValue(), reasonFail); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener).onSubscribeFail(reasonFail); // subscribe - success/terminate @@ -322,10 +384,13 @@ public class WifiNanStateManagerTest { inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData), eq(subscribeSettings)); - mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId); - mDut.onSubscribeTerminated(subscribeId, reasonTerminate); + mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId1); mMockLooper.dispatchAll(); + mDut.onSubscribeTerminated(subscribeId1, reasonTerminate); + mMockLooper.dispatchAll(); + + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener).onSubscribeTerminated(reasonTerminate); // re-subscribe @@ -335,11 +400,12 @@ public class WifiNanStateManagerTest { inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData), eq(subscribeSettings)); - mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId); + mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId2); mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings); mMockLooper.dispatchAll(); - inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId), + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); + inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(subscribeId2), eq(subscribeData), eq(subscribeSettings)); verifyNoMoreInteractions(mockListener, mMockNative); } @@ -355,14 +421,12 @@ public class WifiNanStateManagerTest { final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE; final int subscribeId = 15; - SubscribeData.Builder dataBuilder = new SubscribeData.Builder(); - dataBuilder.setServiceName(serviceName).setServiceSpecificInfo(ssi); - SubscribeData subscribeData = dataBuilder.build(); + SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi).build(); - SubscribeSettings.Builder settingsBuilder = new SubscribeSettings.Builder(); - settingsBuilder.setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE) - .setSubscribeCount(subscribeCount); - SubscribeSettings subscribeSettings = settingsBuilder.build(); + SubscribeSettings subscribeSettings = new SubscribeSettings.Builder() + .setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE) + .setSubscribeCount(subscribeCount).build(); IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class); ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); @@ -392,6 +456,8 @@ public class WifiNanStateManagerTest { mDut.onSubscribeFail(transactionId.getValue(), reasonFail); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); + // subscribe - success/terminate mDut.subscribe(uid, sessionId, subscribeData, subscribeSettings); mMockLooper.dispatchAll(); @@ -400,9 +466,12 @@ public class WifiNanStateManagerTest { eq(subscribeSettings)); mDut.onSubscribeSuccess(transactionId.getValue(), subscribeId); + mMockLooper.dispatchAll(); + mDut.onSubscribeTerminated(subscribeId, reasonTerminate); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); verifyNoMoreInteractions(mockListener, mMockNative); } @@ -414,7 +483,6 @@ public class WifiNanStateManagerTest { final String ssi = "some much longer and more arbitrary data"; final int subscribeCount = 7; final int reasonFail = WifiNanSessionListener.FAIL_REASON_NO_RESOURCES; - final int reasonTerminate = WifiNanSessionListener.TERMINATE_REASON_DONE; final int subscribeId = 15; final int requestorId = 22; final byte[] peerMac = HexEncoding.decode("060708090A0B".toCharArray(), false); @@ -423,14 +491,12 @@ public class WifiNanStateManagerTest { final String peerMsg = "some message from peer"; final int messageId = 6948; - SubscribeData.Builder dataBuilder = new SubscribeData.Builder(); - dataBuilder.setServiceName(serviceName).setServiceSpecificInfo(ssi); - SubscribeData subscribeData = dataBuilder.build(); + SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi).build(); - SubscribeSettings.Builder settingsBuilder = new SubscribeSettings.Builder(); - settingsBuilder.setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE) - .setSubscribeCount(subscribeCount); - SubscribeSettings subscribeSettings = settingsBuilder.build(); + SubscribeSettings subscribeSettings = new SubscribeSettings.Builder() + .setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE) + .setSubscribeCount(subscribeCount).build(); IWifiNanSessionListener mockListener = mock(IWifiNanSessionListener.class); ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); @@ -460,6 +526,7 @@ public class WifiNanStateManagerTest { peerMsg.length()); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener).onMatch(requestorId, peerSsi.getBytes(), peerSsi.length(), peerMatchFilter.getBytes(), peerMatchFilter.length()); inOrder.verify(mockListener).onMessageReceived(requestorId, peerMsg.getBytes(), @@ -474,6 +541,7 @@ public class WifiNanStateManagerTest { mDut.onMessageSendFail(transactionId.getValue(), reasonFail); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener).onMessageSendFail(messageId, reasonFail); mDut.sendMessage(uid, sessionId, requestorId, ssi.getBytes(), ssi.length(), messageId); @@ -485,11 +553,217 @@ public class WifiNanStateManagerTest { mDut.onMessageSendSuccess(transactionId.getValue()); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener).onMessageSendSuccess(messageId); verifyNoMoreInteractions(mockListener, mMockNative); } + /** + * Summary: in a single publish session interact with multiple peers + * (different MAC addresses). + */ + @Test + public void testMultipleMessageSources() throws Exception { + final int uid = 300; + final int clusterLow = 7; + final int clusterHigh = 7; + final int masterPref = 0; + final int sessionId = 26; + final String serviceName = "some-service-name"; + final int publishId = 88; + final int peerId1 = 568; + final int peerId2 = 873; + final byte[] peerMac1 = HexEncoding.decode("000102030405".toCharArray(), false); + final byte[] peerMac2 = HexEncoding.decode("060708090A0B".toCharArray(), false); + final String msgFromPeer1 = "hey from 000102..."; + final String msgFromPeer2 = "hey from 0607..."; + final String msgToPeer1 = "hey there 000102..."; + final String msgToPeer2 = "hey there 0506..."; + final int msgToPeerId1 = 546; + final int msgToPeerId2 = 9654; + final int reason = WifiNanSessionListener.FAIL_REASON_OTHER; + + ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow) + .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build(); + + PublishData publishData = new PublishData.Builder().setServiceName(serviceName).build(); + + PublishSettings publishSettings = new PublishSettings.Builder() + .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED).build(); + + ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); + IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class); + IWifiNanSessionListener mockSessionListener = mock(IWifiNanSessionListener.class); + InOrder inOrder = inOrder(mMockNative, mockListener, mockSessionListener); + + int allEvents = WifiNanEventListener.LISTEN_CONFIG_COMPLETED + | WifiNanEventListener.LISTEN_CONFIG_FAILED + | WifiNanEventListener.LISTEN_IDENTITY_CHANGED + | WifiNanEventListener.LISTEN_NAN_DOWN; + + int allSessionEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL + | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED + | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL + | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED + | WifiNanSessionListener.LISTEN_MATCH + | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS + | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL + | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED; + + mDut.connect(uid, mockListener, allEvents); + mDut.requestConfig(uid, configRequest); + mDut.createSession(uid, sessionId, mockSessionListener, allSessionEvents); + mDut.publish(uid, sessionId, publishData, publishSettings); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest)); + short transactionIdConfig = transactionId.getValue(); + + inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData), + eq(publishSettings)); + short transactionIdPublish = transactionId.getValue(); + + mDut.onConfigCompleted(transactionIdConfig); + mDut.onPublishSuccess(transactionIdPublish, publishId); + mDut.onMessageReceived(publishId, peerId1, peerMac1, msgFromPeer1.getBytes(), + msgFromPeer1.length()); + mDut.onMessageReceived(publishId, peerId2, peerMac2, msgFromPeer2.getBytes(), + msgFromPeer2.length()); + mDut.sendMessage(uid, sessionId, peerId2, msgToPeer2.getBytes(), msgToPeer2.length(), + msgToPeerId2); + mDut.sendMessage(uid, sessionId, peerId1, msgToPeer1.getBytes(), msgToPeer1.length(), + msgToPeerId1); + mMockLooper.dispatchAll(); + + validateInternalTransactionInfoCleanedUp(transactionIdConfig); + validateInternalTransactionInfoCleanedUp(transactionIdPublish); + inOrder.verify(mockListener).onConfigCompleted(configRequest); + inOrder.verify(mockSessionListener).onMessageReceived(peerId1, msgFromPeer1.getBytes(), + msgFromPeer1.length()); + inOrder.verify(mockSessionListener).onMessageReceived(peerId2, msgFromPeer2.getBytes(), + msgFromPeer2.length()); + inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId2), + eq(peerMac2), eq(msgToPeer2.getBytes()), eq(msgToPeer2.length())); + short transactionIdMsg2 = transactionId.getValue(); + inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId1), + eq(peerMac1), eq(msgToPeer1.getBytes()), eq(msgToPeer1.length())); + short transactionIdMsg1 = transactionId.getValue(); + + mDut.onMessageSendFail(transactionIdMsg1, reason); + mDut.onMessageSendSuccess(transactionIdMsg2); + mMockLooper.dispatchAll(); + + validateInternalTransactionInfoCleanedUp(transactionIdMsg1); + validateInternalTransactionInfoCleanedUp(transactionIdMsg2); + inOrder.verify(mockSessionListener).onMessageSendFail(msgToPeerId1, reason); + inOrder.verify(mockSessionListener).onMessageSendSuccess(msgToPeerId2); + verifyNoMoreInteractions(mMockNative, mockListener, mockSessionListener); + } + + /** + * Summary: interact with a peer which changed its identity (MAC address) + * but which keeps its requestor instance ID. Should be transparent. + */ + @Test + public void testMessageWhilePeerChangesIdentity() throws Exception { + final int uid = 300; + final int clusterLow = 7; + final int clusterHigh = 7; + final int masterPref = 0; + final int sessionId = 26; + final String serviceName = "some-service-name"; + final int publishId = 88; + final int peerId = 568; + final byte[] peerMacOrig = HexEncoding.decode("000102030405".toCharArray(), false); + final byte[] peerMacLater = HexEncoding.decode("060708090A0B".toCharArray(), false); + final String msgFromPeer1 = "hey from 000102..."; + final String msgFromPeer2 = "hey from 0607..."; + final String msgToPeer1 = "hey there 000102..."; + final String msgToPeer2 = "hey there 0506..."; + final int msgToPeerId1 = 546; + final int msgToPeerId2 = 9654; + ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow) + .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build(); + + PublishData publishData = new PublishData.Builder().setServiceName(serviceName).build(); + + PublishSettings publishSettings = new PublishSettings.Builder() + .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED).build(); + + ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); + IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class); + IWifiNanSessionListener mockSessionListener = mock(IWifiNanSessionListener.class); + InOrder inOrder = inOrder(mMockNative, mockListener, mockSessionListener); + + int allEvents = WifiNanEventListener.LISTEN_CONFIG_COMPLETED + | WifiNanEventListener.LISTEN_CONFIG_FAILED + | WifiNanEventListener.LISTEN_IDENTITY_CHANGED + | WifiNanEventListener.LISTEN_NAN_DOWN; + + int allSessionEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL + | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED + | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL + | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED + | WifiNanSessionListener.LISTEN_MATCH + | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS + | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL + | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED; + + mDut.connect(uid, mockListener, allEvents); + mDut.requestConfig(uid, configRequest); + mDut.createSession(uid, sessionId, mockSessionListener, allSessionEvents); + mDut.publish(uid, sessionId, publishData, publishSettings); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest)); + short transactionIdConfig = transactionId.getValue(); + + inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData), + eq(publishSettings)); + short transactionIdPublish = transactionId.getValue(); + + mDut.onConfigCompleted(transactionIdConfig); + mDut.onPublishSuccess(transactionIdPublish, publishId); + mDut.onMessageReceived(publishId, peerId, peerMacOrig, msgFromPeer1.getBytes(), + msgFromPeer1.length()); + mDut.sendMessage(uid, sessionId, peerId, msgToPeer1.getBytes(), msgToPeer1.length(), + msgToPeerId1); + mMockLooper.dispatchAll(); + + validateInternalTransactionInfoCleanedUp(transactionIdConfig); + validateInternalTransactionInfoCleanedUp(transactionIdPublish); + inOrder.verify(mockListener).onConfigCompleted(configRequest); + inOrder.verify(mockSessionListener).onMessageReceived(peerId, msgFromPeer1.getBytes(), + msgFromPeer1.length()); + inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId), + eq(peerMacOrig), eq(msgToPeer1.getBytes()), eq(msgToPeer1.length())); + short transactionIdMsg = transactionId.getValue(); + + mDut.onMessageSendSuccess(transactionIdMsg); + mDut.onMessageReceived(publishId, peerId, peerMacLater, msgFromPeer2.getBytes(), + msgFromPeer2.length()); + mDut.sendMessage(uid, sessionId, peerId, msgToPeer2.getBytes(), msgToPeer2.length(), + msgToPeerId2); + mMockLooper.dispatchAll(); + + validateInternalTransactionInfoCleanedUp(transactionIdMsg); + inOrder.verify(mockSessionListener).onMessageSendSuccess(msgToPeerId1); + inOrder.verify(mockSessionListener).onMessageReceived(peerId, msgFromPeer2.getBytes(), + msgFromPeer2.length()); + inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(publishId), eq(peerId), + eq(peerMacLater), eq(msgToPeer2.getBytes()), eq(msgToPeer2.length())); + transactionIdMsg = transactionId.getValue(); + + mDut.onMessageSendSuccess(transactionIdMsg); + mMockLooper.dispatchAll(); + + validateInternalTransactionInfoCleanedUp(transactionIdMsg); + inOrder.verify(mockSessionListener).onMessageSendSuccess(msgToPeerId2); + + verifyNoMoreInteractions(mMockNative, mockListener, mockSessionListener); + } + @Test public void testConfigs() throws Exception { final int uid1 = 9999; @@ -506,18 +780,14 @@ public class WifiNanStateManagerTest { ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); ArgumentCaptor<ConfigRequest> crCapture = ArgumentCaptor.forClass(ConfigRequest.class); - ConfigRequest.Builder builder1 = new ConfigRequest.Builder(); - builder1.setClusterLow(clusterLow1).setClusterHigh(clusterHigh1) - .setMasterPreference(masterPref1); - ConfigRequest configRequest1 = builder1.build(); + ConfigRequest configRequest1 = new ConfigRequest.Builder().setClusterLow(clusterLow1) + .setClusterHigh(clusterHigh1).setMasterPreference(masterPref1).build(); - ConfigRequest.Builder builder2 = new ConfigRequest.Builder(); - builder2.setSupport5gBand(support5g2).setClusterLow(clusterLow2) - .setClusterHigh(clusterHigh2).setMasterPreference(masterPref2); - ConfigRequest configRequest2 = builder2.build(); + ConfigRequest configRequest2 = new ConfigRequest.Builder().setSupport5gBand(support5g2) + .setClusterLow(clusterLow2).setClusterHigh(clusterHigh2) + .setMasterPreference(masterPref2).build(); - ConfigRequest.Builder builder3 = new ConfigRequest.Builder(); - ConfigRequest configRequest3 = builder3.build(); + ConfigRequest configRequest3 = new ConfigRequest.Builder().build(); IWifiNanEventListener mockListener1 = mock(IWifiNanEventListener.class); IWifiNanEventListener mockListener2 = mock(IWifiNanEventListener.class); @@ -536,6 +806,7 @@ public class WifiNanStateManagerTest { mDut.onConfigCompleted(transactionId.getValue()); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener1).onConfigCompleted(configRequest1); mDut.connect(uid2, mockListener2, WifiNanEventListener.LISTEN_CONFIG_COMPLETED); @@ -556,6 +827,7 @@ public class WifiNanStateManagerTest { mDut.onConfigCompleted(transactionId.getValue()); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener1).onConfigCompleted(crCapture.getValue()); mDut.connect(uid3, mockListener3, WifiNanEventListener.LISTEN_CONFIG_COMPLETED); @@ -576,11 +848,13 @@ public class WifiNanStateManagerTest { mDut.onConfigCompleted(transactionId.getValue()); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener1).onConfigCompleted(crCapture.getValue()); mDut.disconnect(uid2); mMockLooper.dispatchAll(); + validateInternalClientInfoCleanedUp(uid2); inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), crCapture.capture()); collector.checkThat("merge: stage 3", configRequest1, equalTo(crCapture.getValue())); @@ -588,11 +862,13 @@ public class WifiNanStateManagerTest { mDut.onConfigCompleted(transactionId.getValue()); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener1).onConfigCompleted(crCapture.getValue()); mDut.disconnect(uid1); mMockLooper.dispatchAll(); + validateInternalClientInfoCleanedUp(uid2); inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), crCapture.capture()); collector.checkThat("merge: stage 4", configRequest3, equalTo(crCapture.getValue())); @@ -600,26 +876,242 @@ public class WifiNanStateManagerTest { mDut.onConfigCompleted(transactionId.getValue()); mMockLooper.dispatchAll(); + validateInternalTransactionInfoCleanedUp(transactionId.getValue()); inOrder.verify(mockListener3).onConfigCompleted(crCapture.getValue()); mDut.disconnect(uid3); mMockLooper.dispatchAll(); + validateInternalClientInfoCleanedUp(uid2); inOrder.verify(mMockNative).disable(anyShort()); verifyNoMoreInteractions(mMockNative); } + /** + * Summary: disconnect a client while there are pending transactions. + * Validate that no callbacks are called and that internal state is + * cleaned-up. + */ + @Test + public void testDisconnectWithPendingTransactions() throws Exception { + final int uid = 125; + final int clusterLow = 5; + final int clusterHigh = 100; + final int masterPref = 111; + final int sessionId = 20; + final String serviceName = "some-service-name"; + final String ssi = "some much longer and more arbitrary data"; + final int publishCount = 7; + final int reason = WifiNanSessionListener.TERMINATE_REASON_DONE; + final int publishId = 22; + + ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow) + .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build(); + + PublishData publishData = new PublishData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi).build(); + + PublishSettings publishSettings = new PublishSettings.Builder() + .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED) + .setPublishCount(publishCount).build(); + + ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); + IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class); + IWifiNanSessionListener mockSessionListener = mock(IWifiNanSessionListener.class); + InOrder inOrder = inOrder(mMockNative, mockListener, mockSessionListener); + + int allEvents = WifiNanEventListener.LISTEN_CONFIG_COMPLETED + | WifiNanEventListener.LISTEN_CONFIG_FAILED + | WifiNanEventListener.LISTEN_IDENTITY_CHANGED + | WifiNanEventListener.LISTEN_NAN_DOWN; + + int allSessionEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL + | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED + | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL + | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED + | WifiNanSessionListener.LISTEN_MATCH + | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS + | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL + | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED; + + mDut.connect(uid, mockListener, allEvents); + mDut.createSession(uid, sessionId, mockSessionListener, allSessionEvents); + mDut.requestConfig(uid, configRequest); + mDut.publish(uid, sessionId, publishData, publishSettings); + mDut.disconnect(uid); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest)); + short transactionIdConfig = transactionId.getValue(); + + inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData), + eq(publishSettings)); + short transactionIdPublish = transactionId.getValue(); + + validateInternalClientInfoCleanedUp(uid); + validateInternalTransactionInfoCleanedUp(transactionIdPublish); + + mDut.onConfigCompleted(transactionIdConfig); + mDut.onPublishSuccess(transactionIdPublish, publishId); + mMockLooper.dispatchAll(); + + mDut.onPublishTerminated(publishId, reason); + mMockLooper.dispatchAll(); + + verifyZeroInteractions(mockListener, mockSessionListener); + } + + /** + * Summary: destroy a session while there are pending transactions. Validate + * that no callbacks are called and that internal state is cleaned-up. + */ + @Test + public void testDestroySessionWithPendingTransactions() throws Exception { + final int uid = 128; + final int clusterLow = 15; + final int clusterHigh = 192; + final int masterPref = 234; + final int publishSessionId = 19; + final int subscribeSessionId = 24; + final String serviceName = "some-service-name"; + final String ssi = "some much longer and more arbitrary data"; + final int publishCount = 15; + final int subscribeCount = 22; + final int reason = WifiNanSessionListener.TERMINATE_REASON_DONE; + final int publishId = 23; + final int subscribeId = 55; + + ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow) + .setClusterHigh(clusterHigh).setMasterPreference(masterPref).build(); + + PublishData publishData = new PublishData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi).build(); + + PublishSettings publishSettings = new PublishSettings.Builder() + .setPublishType(PublishSettings.PUBLISH_TYPE_UNSOLICITED) + .setPublishCount(publishCount).build(); + + SubscribeData subscribeData = new SubscribeData.Builder().setServiceName(serviceName) + .setServiceSpecificInfo(ssi).build(); + + SubscribeSettings subscribeSettings = new SubscribeSettings.Builder() + .setSubscribeType(SubscribeSettings.SUBSCRIBE_TYPE_PASSIVE) + .setSubscribeCount(subscribeCount).build(); + + ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); + IWifiNanEventListener mockListener = mock(IWifiNanEventListener.class); + IWifiNanSessionListener mockPublishSessionListener = mock(IWifiNanSessionListener.class); + IWifiNanSessionListener mockSubscribeSessionListener = mock(IWifiNanSessionListener.class); + InOrder inOrder = inOrder(mMockNative, mockListener, mockPublishSessionListener, + mockSubscribeSessionListener); + + int allEvents = WifiNanEventListener.LISTEN_CONFIG_COMPLETED + | WifiNanEventListener.LISTEN_CONFIG_FAILED + | WifiNanEventListener.LISTEN_IDENTITY_CHANGED + | WifiNanEventListener.LISTEN_NAN_DOWN; + + int allSessionEvents = WifiNanSessionListener.LISTEN_PUBLISH_FAIL + | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED + | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL + | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED + | WifiNanSessionListener.LISTEN_MATCH + | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS + | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL + | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED; + + mDut.connect(uid, mockListener, allEvents); + mDut.requestConfig(uid, configRequest); + mDut.createSession(uid, publishSessionId, mockPublishSessionListener, allSessionEvents); + mDut.publish(uid, publishSessionId, publishData, publishSettings); + mDut.createSession(uid, subscribeSessionId, mockSubscribeSessionListener, allSessionEvents); + mDut.subscribe(uid, subscribeSessionId, subscribeData, subscribeSettings); + mDut.destroySession(uid, publishSessionId); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest)); + short transactionIdConfig = transactionId.getValue(); + + inOrder.verify(mMockNative).publish(transactionId.capture(), eq(0), eq(publishData), + eq(publishSettings)); + short transactionIdPublish = transactionId.getValue(); + + inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq(0), eq(subscribeData), + eq(subscribeSettings)); + short transactionIdSubscribe = transactionId.getValue(); + + validateInternalTransactionInfoCleanedUp(transactionIdPublish); + + mDut.onConfigCompleted(transactionIdConfig); + mDut.onPublishSuccess(transactionIdPublish, publishId); + mDut.onSubscribeSuccess(transactionIdSubscribe, subscribeId); + mMockLooper.dispatchAll(); + + mDut.onPublishTerminated(publishId, reason); + mDut.destroySession(uid, subscribeSessionId); + mMockLooper.dispatchAll(); + + inOrder.verify(mockListener).onConfigCompleted(configRequest); + verifyZeroInteractions(mockPublishSessionListener); + verifyNoMoreInteractions(mockSubscribeSessionListener); + } + + @Test + public void testTransactionIdIncrement() { + int loopCount = 100; + + short prevId = 0; + for (int i = 0; i < loopCount; ++i) { + short id = mDut.createNextTransactionId(); + if (i != 0) { + assertTrue("Transaction ID incrementing", id > prevId); + } + prevId = id; + } + } + + /* + * Tests of internal state of WifiNanStateManager: very limited (not usually + * a good idea). However, these test that the internal state is cleaned-up + * appropriately. Alternatively would cause issues with memory leaks or + * information leak between sessions. + */ + + /** + * Utility routine used to validate that the internal state is cleaned-up + * after the specific transaction ID. To be used in every test which + * involves a transaction. + * + * @param transactionId The transaction ID whose state should be erased. + */ + public void validateInternalTransactionInfoCleanedUp(short transactionId) throws Exception { + Object info = getInternalPendingTransactionInfo(mDut, transactionId); + collector.checkThat("Transaction record not cleared up for transactionId=" + transactionId, + info, nullValue()); + } + + /** + * Utility routine used to validate that the internal state is cleaned-up + * after a client is disconnected. To be used in every test which terminates + * a client. + * + * @param uid The ID of the client which should be deleted. + */ + public void validateInternalClientInfoCleanedUp(int uid) throws Exception { + WifiNanClientState client = getInternalClientState(mDut, uid); + collector.checkThat("Client record not cleared up for uid=" + uid, client, nullValue()); + } + /* * Utilities */ - private static WifiNanStateManager installNewNanStateManager() throws Exception { + private static WifiNanStateManager installNewNanStateManagerAndResetState() throws Exception { Constructor<WifiNanStateManager> ctr = WifiNanStateManager.class.getDeclaredConstructor(); ctr.setAccessible(true); WifiNanStateManager nanStateManager = ctr.newInstance(); - Field field = WifiNanStateManager.class.getDeclaredField("sNanStatemanagerSingleton"); + Field field = WifiNanStateManager.class.getDeclaredField("sNanStateManagerSingleton"); field.setAccessible(true); field.set(null, nanStateManager); @@ -631,4 +1123,25 @@ public class WifiNanStateManagerTest { field.setAccessible(true); field.set(null, obj); } + + private static Object getInternalPendingTransactionInfo(WifiNanStateManager dut, + short transactionId) throws Exception { + Field field = WifiNanStateManager.class.getDeclaredField("mPendingResponses"); + field.setAccessible(true); + @SuppressWarnings("unchecked") + SparseArray<Object> pendingResponses = (SparseArray<Object>) field.get(dut); + + return pendingResponses.get(transactionId); + } + + private static WifiNanClientState getInternalClientState(WifiNanStateManager dut, + int uid) throws Exception { + Field field = WifiNanStateManager.class.getDeclaredField("mClients"); + field.setAccessible(true); + @SuppressWarnings("unchecked") + SparseArray<WifiNanClientState> clients = (SparseArray<WifiNanClientState>) field.get(dut); + + return clients.get(uid); + } } + |