diff options
-rw-r--r-- | service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java | 208 | ||||
-rw-r--r-- | tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java | 226 |
2 files changed, 360 insertions, 74 deletions
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java index ead0c5f5e..b20445ae1 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java @@ -33,6 +33,7 @@ import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.NetworkSpecifier; import android.net.RouteInfo; +import android.net.wifi.aware.WifiAwareAgentNetworkSpecifier; import android.net.wifi.aware.WifiAwareManager; import android.net.wifi.aware.WifiAwareNetworkSpecifier; import android.net.wifi.aware.WifiAwareUtils; @@ -61,6 +62,7 @@ import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Map; +import java.util.Objects; import java.util.Set; /** @@ -86,7 +88,7 @@ public class WifiAwareDataPathStateManager { private final WifiAwareStateManager mMgr; public NetworkInterfaceWrapper mNiWrapper = new NetworkInterfaceWrapper(); - private final NetworkCapabilities mNetworkCapabilitiesFilter = new NetworkCapabilities(); + private static final NetworkCapabilities sNetworkCapabilitiesFilter = new NetworkCapabilities(); private final Set<String> mInterfaces = new HashSet<>(); private final Map<WifiAwareNetworkSpecifier, AwareNetworkRequestInformation> mNetworkRequestsCache = new ArrayMap<>(); @@ -114,19 +116,19 @@ public class WifiAwareDataPathStateManager { mPermissionsWrapper = permissionsWrapper; mLooper = looper; - mNetworkCapabilitiesFilter.clearAll(); - mNetworkCapabilitiesFilter.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE); - mNetworkCapabilitiesFilter + sNetworkCapabilitiesFilter.clearAll(); + sNetworkCapabilitiesFilter.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE); + sNetworkCapabilitiesFilter .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED); - mNetworkCapabilitiesFilter.setNetworkSpecifier(new MatchAllNetworkSpecifier()); - mNetworkCapabilitiesFilter.setLinkUpstreamBandwidthKbps(NETWORK_FACTORY_BANDWIDTH_AVAIL); - mNetworkCapabilitiesFilter.setLinkDownstreamBandwidthKbps(NETWORK_FACTORY_BANDWIDTH_AVAIL); - mNetworkCapabilitiesFilter.setSignalStrength(NETWORK_FACTORY_SIGNAL_STRENGTH_AVAIL); + sNetworkCapabilitiesFilter.setNetworkSpecifier(new MatchAllNetworkSpecifier()); + sNetworkCapabilitiesFilter.setLinkUpstreamBandwidthKbps(NETWORK_FACTORY_BANDWIDTH_AVAIL); + sNetworkCapabilitiesFilter.setLinkDownstreamBandwidthKbps(NETWORK_FACTORY_BANDWIDTH_AVAIL); + sNetworkCapabilitiesFilter.setSignalStrength(NETWORK_FACTORY_SIGNAL_STRENGTH_AVAIL); - mNetworkFactory = new WifiAwareNetworkFactory(looper, context, mNetworkCapabilitiesFilter); + mNetworkFactory = new WifiAwareNetworkFactory(looper, context, sNetworkCapabilitiesFilter); mNetworkFactory.setScoreFilter(NETWORK_FACTORY_SCORE_AVAIL); mNetworkFactory.register(); @@ -146,6 +148,18 @@ public class WifiAwareDataPathStateManager { return null; } + private Map.Entry<WifiAwareNetworkSpecifier, AwareNetworkRequestInformation> + getNetworkRequestByCanonicalDescriptor(CanonicalConnectionInfo cci) { + for (Map.Entry<WifiAwareNetworkSpecifier, AwareNetworkRequestInformation> entry : + mNetworkRequestsCache.entrySet()) { + if (entry.getValue().getCanonicalDescriptor().equals(cci)) { + return entry; + } + } + + return null; + } + /** * Create all Aware data-path interfaces which are possible on the device - based on the * capabilities of the firmware. @@ -468,7 +482,7 @@ public class WifiAwareDataPathStateManager { NetworkInfo networkInfo = new NetworkInfo(ConnectivityManager.TYPE_NONE, 0, NETWORK_TAG, ""); NetworkCapabilities networkCapabilities = new NetworkCapabilities( - mNetworkCapabilitiesFilter); + sNetworkCapabilitiesFilter); LinkProperties linkProperties = new LinkProperties(); boolean interfaceUsedByAnotherNdp = isInterfaceUpAndUsedByAnotherNdp(nnri); @@ -481,6 +495,7 @@ public class WifiAwareDataPathStateManager { + ": can't configure network - " + e); mMgr.endDataPath(ndpId); + nnri.state = AwareNetworkRequestInformation.STATE_TERMINATING; return networkSpecifier; } } else { @@ -490,8 +505,8 @@ public class WifiAwareDataPathStateManager { } } - if (!mNiWrapper.configureAgentProperties(nnri, networkSpecifier, ndpId, networkInfo, - networkCapabilities, linkProperties)) { + if (!mNiWrapper.configureAgentProperties(nnri, nnri.equivalentSpecifiers, ndpId, + networkInfo, networkCapabilities, linkProperties)) { return networkSpecifier; } @@ -578,6 +593,7 @@ public class WifiAwareDataPathStateManager { nnri.networkSpecifier.isOutOfBand(), nnri.startTimestamp); mMgr.endDataPath(nnri.ndpId); + nnri.state = AwareNetworkRequestInformation.STATE_TERMINATING; } private class WifiAwareNetworkFactory extends NetworkFactory { @@ -638,6 +654,18 @@ public class WifiAwareDataPathStateManager { return false; } + // check to see if a canonical version exists + Map.Entry<WifiAwareNetworkSpecifier, AwareNetworkRequestInformation> primaryRequest = + getNetworkRequestByCanonicalDescriptor(nnri.getCanonicalDescriptor()); + if (primaryRequest != null) { + if (VDBG) { + Log.v(TAG, "WifiAwareNetworkFactory.acceptRequest: request=" + request + + ", already has a primary request=" + primaryRequest.getKey()); + } + primaryRequest.getValue().updateToSupportNewRequest(networkSpecifier); + return false; + } + mNetworkRequestsCache.put(networkSpecifier, nnri); return true; @@ -725,19 +753,28 @@ public class WifiAwareDataPathStateManager { return; } - if (nnri.networkSpecifier.role == WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR - && nnri.state - > AwareNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE) { - mMgr.endDataPath(nnri.ndpId); - } - if (nnri.networkSpecifier.role == WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER - && nnri.state - > AwareNetworkRequestInformation.STATE_RESPONDER_WAIT_FOR_REQUEST) { - mMgr.endDataPath(nnri.ndpId); + /* + * Since there's no agent it means we're in the process of setting up the NDP. + * However, it is possible that there were other equivalent requests for this NDP. We + * should keep going in that case. + */ + nnri.removeSupportForRequest(networkSpecifier); + if (nnri.equivalentSpecifiers.isEmpty()) { + if (VDBG) { + Log.v(TAG, "releaseNetworkFor: there are no further requests, networkRequest=" + + networkRequest); + } + if (nnri.ndpId != 0) { // 0 is never a valid ID! + if (VDBG) Log.v(TAG, "releaseNetworkFor: in progress NDP being terminated"); + mMgr.endDataPath(nnri.ndpId); + nnri.state = AwareNetworkRequestInformation.STATE_TERMINATING; + } + } else { + if (VDBG) { + Log.v(TAG, "releaseNetworkFor: equivalent requests exist - not terminating " + + "networkRequest=" + networkRequest); + } } - - // Will get a callback (on both initiator and responder) when data-path actually - // terminated. At that point will inform the agent and will clear the cache. } } @@ -858,6 +895,7 @@ public class WifiAwareDataPathStateManager { static final int STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE = 103; static final int STATE_RESPONDER_WAIT_FOR_REQUEST = 104; static final int STATE_RESPONDER_WAIT_FOR_RESPOND_RESPONSE = 105; + static final int STATE_TERMINATING = 106; public int state; @@ -866,13 +904,55 @@ public class WifiAwareDataPathStateManager { public int pubSubId = 0; public int peerInstanceId = 0; public byte[] peerDiscoveryMac = null; - public int ndpId; + public int ndpId = 0; // 0 is never a valid ID! public byte[] peerDataMac; public WifiAwareNetworkSpecifier networkSpecifier; public long startTimestamp = 0; // request is made (initiator) / get request (responder) public WifiAwareNetworkAgent networkAgent; + /* A collection of specifiers which are equivalent to the current request and are + * supported by it's agent. This list DOES include the original (first) network specifier + * (which is stored separately above). + */ + public Set<WifiAwareNetworkSpecifier> equivalentSpecifiers = new HashSet<>(); + + void updateToSupportNewRequest(WifiAwareNetworkSpecifier ns) { + if (VDBG) Log.v(TAG, "updateToSupportNewRequest: ns=" + ns); + if (equivalentSpecifiers.add(ns) && state == STATE_CONFIRMED) { + if (networkAgent == null) { + Log.wtf(TAG, "updateToSupportNewRequest: null agent in CONFIRMED state!?"); + return; + } + + networkAgent.sendNetworkCapabilities(getNetworkCapabilities()); + } + } + + void removeSupportForRequest(WifiAwareNetworkSpecifier ns) { + if (VDBG) Log.v(TAG, "removeSupportForRequest: ns=" + ns); + equivalentSpecifiers.remove(ns); + + // we will not update the agent: + // 1. this will only get called before the agent is created + // 2. connectivity service does not allow (WTF) updates with reduced capabilities + } + + private NetworkCapabilities getNetworkCapabilities() { + NetworkCapabilities nc = new NetworkCapabilities(sNetworkCapabilitiesFilter); + nc.setNetworkSpecifier(new WifiAwareAgentNetworkSpecifier(equivalentSpecifiers.toArray( + new WifiAwareNetworkSpecifier[equivalentSpecifiers.size()]))); + return nc; + } + + /** + * Returns a canonical descriptor for the network request. + */ + CanonicalConnectionInfo getCanonicalDescriptor() { + return new CanonicalConnectionInfo(peerDiscoveryMac, networkSpecifier.pmk, + networkSpecifier.sessionId, networkSpecifier.passphrase); + } + static AwareNetworkRequestInformation processNetworkSpecifier(WifiAwareNetworkSpecifier ns, WifiAwareStateManager mgr, WifiPermissionsWrapper permissionWrapper) { int uid, pubSubId = 0; @@ -1002,6 +1082,7 @@ public class WifiAwareDataPathStateManager { nnri.peerInstanceId = peerInstanceId; nnri.peerDiscoveryMac = peerMac; nnri.networkSpecifier = ns; + nnri.equivalentSpecifiers.add(ns); return nnri; } @@ -1018,7 +1099,69 @@ public class WifiAwareDataPathStateManager { ", ndpId=").append(ndpId).append(", peerDataMac=").append( peerDataMac == null ? "" : String.valueOf(HexEncoding.encode(peerDataMac))).append( - ", startTimestamp=").append(startTimestamp); + ", startTimestamp=").append(startTimestamp).append(", equivalentSpecifiers=["); + for (WifiAwareNetworkSpecifier ns: equivalentSpecifiers) { + sb.append(ns.toString()).append(", "); + } + return sb.append("]").toString(); + } + } + + /** + * A canonical (unique) descriptor of the peer connection. + */ + static class CanonicalConnectionInfo { + CanonicalConnectionInfo(byte[] peerDiscoveryMac, byte[] pmk, int sessionId, + String passphrase) { + this.peerDiscoveryMac = peerDiscoveryMac; + this.pmk = pmk; + this.sessionId = sessionId; + this.passphrase = passphrase; + } + + public final byte[] peerDiscoveryMac; + + /* + * Security configuration matching: + * - open: pmk/passphrase = null + * - pmk: pmk != null, passphrase = null + * - passphrase: passphrase != null, sessionId used (==0 for OOB), pmk=null + */ + public final byte[] pmk; + + public final int sessionId; + public final String passphrase; + + @Override + public int hashCode() { + return Objects.hash(Arrays.hashCode(peerDiscoveryMac), Arrays.hashCode(pmk), sessionId, + passphrase); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof CanonicalConnectionInfo)) { + return false; + } + + CanonicalConnectionInfo lhs = (CanonicalConnectionInfo) obj; + + return Arrays.equals(peerDiscoveryMac, lhs.peerDiscoveryMac) && Arrays.equals(pmk, + lhs.pmk) && TextUtils.equals(passphrase, lhs.passphrase) + && sessionId == lhs.sessionId; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CanonicalConnectionInfo: ["); + sb.append("peerDiscoveryMac=").append(peerDiscoveryMac == null ? "" + : String.valueOf(HexEncoding.encode(peerDiscoveryMac))).append("pmk=").append( + pmk == null ? "" : "*").append("sessionId=").append(sessionId).append( + "passphrase=").append(passphrase == null ? "" : "*").append("]"); return sb.toString(); } } @@ -1033,8 +1176,9 @@ public class WifiAwareDataPathStateManager { * name. Delegated to enable mocking. */ public boolean configureAgentProperties(AwareNetworkRequestInformation nnri, - WifiAwareNetworkSpecifier networkSpecifier, int ndpId, NetworkInfo networkInfo, - NetworkCapabilities networkCapabilities, LinkProperties linkProperties) { + Set<WifiAwareNetworkSpecifier> networkSpecifiers, int ndpId, + NetworkInfo networkInfo, NetworkCapabilities networkCapabilities, + LinkProperties linkProperties) { // find link-local address InetAddress linkLocal = null; NetworkInterface ni; @@ -1044,12 +1188,14 @@ public class WifiAwareDataPathStateManager { Log.e(TAG, "onDataPathConfirm: ACCEPT nnri=" + nnri + ": can't get network interface - " + e); mMgr.endDataPath(ndpId); + nnri.state = AwareNetworkRequestInformation.STATE_TERMINATING; return false; } if (ni == null) { Log.e(TAG, "onDataPathConfirm: ACCEPT nnri=" + nnri + ": can't get network interface (null)"); mMgr.endDataPath(ndpId); + nnri.state = AwareNetworkRequestInformation.STATE_TERMINATING; return false; } Enumeration<InetAddress> addresses = ni.getInetAddresses(); @@ -1064,6 +1210,7 @@ public class WifiAwareDataPathStateManager { if (linkLocal == null) { Log.e(TAG, "onDataPathConfirm: ACCEPT nnri=" + nnri + ": no link local addresses"); mMgr.endDataPath(ndpId); + nnri.state = AwareNetworkRequestInformation.STATE_TERMINATING; return false; } @@ -1071,7 +1218,8 @@ public class WifiAwareDataPathStateManager { networkInfo.setIsAvailable(true); networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null); - networkCapabilities.setNetworkSpecifier(networkSpecifier); + networkCapabilities.setNetworkSpecifier(new WifiAwareAgentNetworkSpecifier( + networkSpecifiers.toArray(new WifiAwareNetworkSpecifier[0]))); linkProperties.setInterfaceName(nnri.interfaceName); linkProperties.addLinkAddress(new LinkAddress(linkLocal, 64)); @@ -1088,7 +1236,7 @@ public class WifiAwareDataPathStateManager { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("WifiAwareDataPathStateManager:"); pw.println(" mInterfaces: " + mInterfaces); - pw.println(" mNetworkCapabilitiesFilter: " + mNetworkCapabilitiesFilter); + pw.println(" sNetworkCapabilitiesFilter: " + sNetworkCapabilitiesFilter); pw.println(" mNetworkRequestsCache: " + mNetworkRequestsCache); pw.println(" mNetworkFactory:"); mNetworkFactory.dump(fd, pw, args); diff --git a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java index 37af1ba6f..227a196a8 100644 --- a/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareDataPathStateManagerTest.java @@ -452,6 +452,124 @@ public class WifiAwareDataPathStateManagerTest { verifyNoMoreInteractions(mMockNative, mMockCm, mAwareMetricsMock, mMockNwMgt); } + /** + * Validate that multiple NDP requests which resolve to the same canonical request are treated + * as one. + */ + @Test + public void testMultipleIdenticalRequests() throws Exception { + final int numRequestsPre = 6; + final int numRequestsPost = 5; + final int clientId = 123; + final int ndpId = 5; + final byte[] peerDiscoveryMac = HexEncoding.decode("000102030405".toCharArray(), false); + final byte[] peerDataPathMac = HexEncoding.decode("0A0B0C0D0E0F".toCharArray(), false); + NetworkRequest[] nrs = new NetworkRequest[numRequestsPre + numRequestsPost]; + + ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); + ArgumentCaptor<Messenger> agentMessengerCaptor = ArgumentCaptor.forClass(Messenger.class); + + InOrder inOrder = inOrder(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, + mMockNwMgt); + InOrder inOrderM = inOrder(mAwareMetricsMock); + + // (1) initialize all clients + Messenger messenger = initOobDataPathEndPoint(true, clientId, inOrder, inOrderM); + for (int i = 1; i < numRequestsPre + numRequestsPost; ++i) { + initOobDataPathEndPoint(false, clientId + i, inOrder, inOrderM); + } + + // (2) make 3 network requests (all identical under the hood) + for (int i = 0; i < numRequestsPre; ++i) { + nrs[i] = getDirectNetworkRequest(clientId + i, + WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null, + null); + + Message reqNetworkMsg = Message.obtain(); + reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK; + reqNetworkMsg.obj = nrs[i]; + reqNetworkMsg.arg1 = 0; + messenger.send(reqNetworkMsg); + } + mMockLooper.dispatchAll(); + + // (3) verify the start NDP HAL request + inOrder.verify(mMockNative).initiateDataPath(transactionId.capture(), eq(0), + eq(CHANNEL_NOT_REQUESTED), anyInt(), eq(peerDiscoveryMac), + eq(sAwareInterfacePrefix + "0"), eq(null), eq(null), eq(true), any()); + + // (4) unregister request #0 (the primary) + Message endNetworkReqMsg = Message.obtain(); + endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; + endNetworkReqMsg.obj = nrs[0]; + messenger.send(endNetworkReqMsg); + mMockLooper.dispatchAll(); + + // (5) respond to the registration request + mDut.onInitiateDataPathResponseSuccess(transactionId.getValue(), ndpId); + mMockLooper.dispatchAll(); + + // (6) unregister request #1 + endNetworkReqMsg = Message.obtain(); + endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; + endNetworkReqMsg.obj = nrs[1]; + messenger.send(endNetworkReqMsg); + mMockLooper.dispatchAll(); + + // (7) confirm the NDP creation + mDut.onDataPathConfirmNotification(ndpId, peerDataPathMac, true, 0, null); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNwMgt).setInterfaceUp(anyString()); + inOrder.verify(mMockNwMgt).enableIpv6(anyString()); + inOrder.verify(mMockCm).registerNetworkAgent(agentMessengerCaptor.capture(), any(), any(), + any(), anyInt(), any()); + inOrderM.verify(mAwareMetricsMock).recordNdpStatus(eq(NanStatusType.SUCCESS), + eq(true), anyLong()); + inOrderM.verify(mAwareMetricsMock).recordNdpCreation(anyInt(), any()); + + // (8) execute 'post' requests + for (int i = numRequestsPre; i < numRequestsPre + numRequestsPost; ++i) { + nrs[i] = getDirectNetworkRequest(clientId + i, + WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, peerDiscoveryMac, null, + null); + + Message reqNetworkMsg = Message.obtain(); + reqNetworkMsg.what = NetworkFactory.CMD_REQUEST_NETWORK; + reqNetworkMsg.obj = nrs[i]; + reqNetworkMsg.arg1 = 0; + messenger.send(reqNetworkMsg); + } + mMockLooper.dispatchAll(); + + // (9) unregister all requests + for (int i = 2; i < numRequestsPre + numRequestsPost; ++i) { + endNetworkReqMsg = Message.obtain(); + endNetworkReqMsg.what = NetworkFactory.CMD_CANCEL_REQUEST; + endNetworkReqMsg.obj = nrs[i]; + messenger.send(endNetworkReqMsg); + mMockLooper.dispatchAll(); + } + + Message endNetworkUsageMsg = Message.obtain(); + endNetworkUsageMsg.what = AsyncChannel.CMD_CHANNEL_DISCONNECTED; + agentMessengerCaptor.getValue().send(endNetworkUsageMsg); + mMockLooper.dispatchAll(); + + // (10) verify that NDP torn down + inOrder.verify(mMockNative).endDataPath(transactionId.capture(), eq(ndpId)); + + mDut.onEndDataPathResponse(transactionId.getValue(), true, 0); + mDut.onDataPathEndNotification(ndpId); + mMockLooper.dispatchAll(); + + inOrder.verify(mMockNwMgt).setInterfaceDown(anyString()); + inOrderM.verify(mAwareMetricsMock).recordNdpSessionDuration(anyLong()); + + verifyNoMoreInteractions(mMockNative, mMockCm, mMockCallback, mMockSessionCallback, + mAwareMetricsMock, mMockNwMgt); + } + /* * Initiator tests */ @@ -1109,23 +1227,64 @@ public class WifiAwareDataPathStateManagerTest { byte pubSubId, int requestorId, byte[] peerDiscoveryMac, InOrder inOrder, InOrder inOrderM, boolean doPublish) throws Exception { - final int pid = 2000; - final String callingPackage = "com.android.somePackage"; final String someMsg = "some arbitrary message from peer"; - final ConfigRequest configRequest = new ConfigRequest.Builder().build(); final PublishConfig publishConfig = new PublishConfig.Builder().build(); final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build(); - Capabilities capabilities = new Capabilities(); - capabilities.maxNdiInterfaces = 1; - ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); ArgumentCaptor<Integer> sessionId = ArgumentCaptor.forClass(Integer.class); ArgumentCaptor<Integer> peerIdCaptor = ArgumentCaptor.forClass(Integer.class); + + Messenger messenger = null; + if (isFirstIteration) { + messenger = initOobDataPathEndPoint(true, clientId, inOrder, inOrderM); + } + + if (doPublish) { + mDut.publish(clientId, publishConfig, mMockSessionCallback); + } else { + mDut.subscribe(clientId, subscribeConfig, mMockSessionCallback); + } + mMockLooper.dispatchAll(); + if (doPublish) { + inOrder.verify(mMockNative).publish(transactionId.capture(), eq((byte) 0), + eq(publishConfig)); + } else { + inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq((byte) 0), + eq(subscribeConfig)); + } + mDut.onSessionConfigSuccessResponse(transactionId.getValue(), doPublish, pubSubId); + mMockLooper.dispatchAll(); + inOrder.verify(mMockSessionCallback).onSessionStarted(sessionId.capture()); + inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(Process.myUid()), + eq(doPublish), any()); + inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(Process.myUid(), + NanStatusType.SUCCESS, doPublish); + + mDut.onMessageReceivedNotification(pubSubId, requestorId, peerDiscoveryMac, + someMsg.getBytes()); + mMockLooper.dispatchAll(); + inOrder.verify(mMockSessionCallback).onMessageReceived(peerIdCaptor.capture(), + eq(someMsg.getBytes())); + + return new DataPathEndPointInfo(sessionId.getValue(), peerIdCaptor.getValue(), + isFirstIteration ? messenger : null); + } + + private Messenger initOobDataPathEndPoint(boolean startUpSequence, int clientId, + InOrder inOrder, InOrder inOrderM) throws Exception { + final int pid = 2000; + final String callingPackage = "com.android.somePackage"; + final ConfigRequest configRequest = new ConfigRequest.Builder().build(); + + ArgumentCaptor<Short> transactionId = ArgumentCaptor.forClass(Short.class); ArgumentCaptor<Messenger> messengerCaptor = ArgumentCaptor.forClass(Messenger.class); ArgumentCaptor<String> strCaptor = ArgumentCaptor.forClass(String.class); - if (isFirstIteration) { + Capabilities capabilities = new Capabilities(); + capabilities.maxNdiInterfaces = 1; + + if (startUpSequence) { // (0) start/registrations inOrder.verify(mMockCm).registerNetworkFactory(messengerCaptor.capture(), strCaptor.capture()); @@ -1143,57 +1302,36 @@ public class WifiAwareDataPathStateManagerTest { mDut.enableUsage(); mMockLooper.dispatchAll(); inOrderM.verify(mAwareMetricsMock).recordEnableUsage(); + } - // (3) create client & session & rx message - mDut.connect(clientId, Process.myUid(), pid, callingPackage, mMockCallback, - configRequest, - false); - mMockLooper.dispatchAll(); + // (3) create client + mDut.connect(clientId, Process.myUid(), pid, callingPackage, mMockCallback, + configRequest, + false); + mMockLooper.dispatchAll(); + + if (startUpSequence) { inOrder.verify(mMockNative).enableAndConfigure(transactionId.capture(), eq(configRequest), eq(false), eq(true), eq(true), eq(false)); mDut.onConfigSuccessResponse(transactionId.getValue()); mMockLooper.dispatchAll(); - inOrder.verify(mMockCallback).onConnectSuccess(clientId); - inOrderM.verify(mAwareMetricsMock).recordAttachSession(eq(Process.myUid()), eq(false), - any()); + } + + inOrder.verify(mMockCallback).onConnectSuccess(clientId); + inOrderM.verify(mAwareMetricsMock).recordAttachSession(eq(Process.myUid()), eq(false), + any()); + if (startUpSequence) { inOrder.verify(mMockNative).createAwareNetworkInterface(transactionId.capture(), strCaptor.capture()); collector.checkThat("interface created -- 0", sAwareInterfacePrefix + 0, equalTo(strCaptor.getValue())); mDut.onCreateDataPathInterfaceResponse(transactionId.getValue(), true, 0); mMockLooper.dispatchAll(); + return messengerCaptor.getValue(); } - if (doPublish) { - mDut.publish(clientId, publishConfig, mMockSessionCallback); - } else { - mDut.subscribe(clientId, subscribeConfig, mMockSessionCallback); - } - mMockLooper.dispatchAll(); - if (doPublish) { - inOrder.verify(mMockNative).publish(transactionId.capture(), eq((byte) 0), - eq(publishConfig)); - } else { - inOrder.verify(mMockNative).subscribe(transactionId.capture(), eq((byte) 0), - eq(subscribeConfig)); - } - mDut.onSessionConfigSuccessResponse(transactionId.getValue(), doPublish, pubSubId); - mMockLooper.dispatchAll(); - inOrder.verify(mMockSessionCallback).onSessionStarted(sessionId.capture()); - inOrderM.verify(mAwareMetricsMock).recordDiscoverySession(eq(Process.myUid()), - eq(doPublish), any()); - inOrderM.verify(mAwareMetricsMock).recordDiscoveryStatus(Process.myUid(), - NanStatusType.SUCCESS, doPublish); - - mDut.onMessageReceivedNotification(pubSubId, requestorId, peerDiscoveryMac, - someMsg.getBytes()); - mMockLooper.dispatchAll(); - inOrder.verify(mMockSessionCallback).onMessageReceived(peerIdCaptor.capture(), - eq(someMsg.getBytes())); - - return new DataPathEndPointInfo(sessionId.getValue(), peerIdCaptor.getValue(), - isFirstIteration ? messengerCaptor.getValue() : null); + return null; } private static class DataPathEndPointInfo { |