Merge "p2p: add cts coverage for new WifiP2pManager API"
diff --git a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
index 5e91366..c80e372 100644
--- a/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/ConcurrencyTest.java
@@ -16,36 +16,66 @@
package android.net.wifi.cts;
+import static org.junit.Assert.assertNotEquals;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.Network;
import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager;
-import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_DISABLED;
-import static android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED;
+import android.provider.Settings;
import android.test.AndroidTestCase;
+import android.util.Log;
import com.android.compatibility.common.util.SystemUtil;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.LinkedList;
+import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
public class ConcurrencyTest extends AndroidTestCase {
private class MySync {
- int expectedWifiState;
- int expectedP2pState;
+ static final int WIFI_STATE = 0;
+ static final int P2P_STATE = 1;
+ static final int DISCOVERY_STATE = 2;
+ static final int NETWORK_INFO = 3;
+
+ public BitSet pendingSync = new BitSet();
+
+ public int expectedWifiState;
+ public int expectedP2pState;
+ public int expectedDiscoveryState;
+ public NetworkInfo expectedNetworkInfo;
+ }
+
+ private class MyResponse {
+ public boolean valid = false;
+
+ public boolean success;
+ public int p2pState;
+ public int discoveryState;
+ public NetworkInfo networkInfo;
}
private WifiManager mWifiManager;
+ private WifiP2pManager mWifiP2pManager;
+ private WifiP2pManager.Channel mWifiP2pChannel;
private MySync mMySync = new MySync();
+ private MyResponse mMyResponse = new MyResponse();
- private static final String TAG = "WifiInfoTest";
+ private static final String TAG = "ConcurrencyTest";
private static final int TIMEOUT_MSEC = 6000;
private static final int WAIT_MSEC = 60;
private static final int DURATION = 10000;
@@ -56,16 +86,33 @@
final String action = intent.getAction();
if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
synchronized (mMySync) {
+ mMySync.pendingSync.set(MySync.WIFI_STATE);
mMySync.expectedWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_DISABLED);
mMySync.notify();
}
} else if(action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) {
synchronized (mMySync) {
+ mMySync.pendingSync.set(MySync.P2P_STATE);
mMySync.expectedP2pState = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,
WifiP2pManager.WIFI_P2P_STATE_DISABLED);
mMySync.notify();
}
+ } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) {
+ synchronized (mMySync) {
+ mMySync.pendingSync.set(MySync.DISCOVERY_STATE);
+ mMySync.expectedDiscoveryState = intent.getIntExtra(
+ WifiP2pManager.EXTRA_DISCOVERY_STATE,
+ WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
+ mMySync.notify();
+ }
+ } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
+ synchronized (mMySync) {
+ mMySync.pendingSync.set(MySync.NETWORK_INFO);
+ mMySync.expectedNetworkInfo = (NetworkInfo) intent.getExtra(
+ WifiP2pManager.EXTRA_NETWORK_INFO, null);
+ mMySync.notify();
+ }
}
}
};
@@ -81,6 +128,8 @@
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
+ mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mContext.registerReceiver(mReceiver, mIntentFilter);
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
@@ -92,6 +141,8 @@
assertTrue(!mWifiManager.isWifiEnabled());
mMySync.expectedWifiState = WifiManager.WIFI_STATE_DISABLED;
mMySync.expectedP2pState = WifiP2pManager.WIFI_P2P_STATE_DISABLED;
+ mMySync.expectedDiscoveryState = WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED;
+ mMySync.expectedNetworkInfo = null;
}
@Override
@@ -108,16 +159,66 @@
super.tearDown();
}
- private void waitForBroadcasts() {
+ private boolean waitForBroadcasts(List<Integer> waitSyncList) {
synchronized (mMySync) {
long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
- while (System.currentTimeMillis() < timeout
- && (mMySync.expectedWifiState != WifiManager.WIFI_STATE_ENABLED ||
- mMySync.expectedP2pState != WifiP2pManager.WIFI_P2P_STATE_ENABLED)) {
+ while (System.currentTimeMillis() < timeout) {
+ List<Integer> handledSyncList = waitSyncList.stream()
+ .filter(w -> mMySync.pendingSync.get(w))
+ .collect(Collectors.toList());
+ handledSyncList.forEach(w -> mMySync.pendingSync.clear(w));
+ waitSyncList.removeAll(handledSyncList);
+ if (waitSyncList.isEmpty()) {
+ break;
+ }
try {
mMySync.wait(WAIT_MSEC);
} catch (InterruptedException e) { }
}
+ if (!waitSyncList.isEmpty()) {
+ Log.i(TAG, "Missing broadcast: " + waitSyncList);
+ }
+ return waitSyncList.isEmpty();
+ }
+ }
+
+ private boolean waitForBroadcasts(int waitSingleSync) {
+ return waitForBroadcasts(
+ new LinkedList<Integer>(Arrays.asList(waitSingleSync)));
+ }
+
+ private boolean waitForServiceResponse(MyResponse waitResponse) {
+ synchronized (waitResponse) {
+ long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+ while (System.currentTimeMillis() < timeout) {
+ try {
+ waitResponse.wait(WAIT_MSEC);
+ } catch (InterruptedException e) { }
+
+ if (waitResponse.valid) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ // Return true if location is enabled.
+ private boolean isLocationEnabled() {
+ return Settings.Secure.getInt(getContext().getContentResolver(),
+ Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF)
+ != Settings.Secure.LOCATION_MODE_OFF;
+ }
+
+ // Returns true if the device has location feature.
+ private boolean hasLocationFeature() {
+ return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION);
+ }
+
+ private void resetResponse(MyResponse responseObj) {
+ synchronized (responseObj) {
+ responseObj.valid = false;
+ responseObj.networkInfo = null;
}
}
@@ -148,25 +249,212 @@
cm.unregisterNetworkCallback(networkCallback);
}
- public void testConcurrency() {
+ private boolean setupWifiP2p() {
// Cannot support p2p alone
if (!WifiFeature.isWifiSupported(getContext())) {
assertTrue(!WifiFeature.isP2pSupported(getContext()));
- return;
+ return false;
}
if (!WifiFeature.isP2pSupported(getContext())) {
// skip the test if p2p is not supported
+ return false;
+ }
+
+ if (!hasLocationFeature()) {
+ Log.d(TAG, "Skipping test as location is not supported");
+ return false;
+ }
+ if (!isLocationEnabled()) {
+ fail("Please enable location for this test - since P-release WiFi Direct"
+ + " needs Location enabled.");
+ }
+
+ long timeout = System.currentTimeMillis() + TIMEOUT_MSEC;
+ while (!mWifiManager.isWifiEnabled() && System.currentTimeMillis() < timeout) {
+ try {
+ enableWifi();
+ } catch (InterruptedException e) { }
+ }
+
+ assertTrue(mWifiManager.isWifiEnabled());
+
+ assertTrue(waitForBroadcasts(
+ new LinkedList<Integer>(
+ Arrays.asList(MySync.WIFI_STATE, MySync.P2P_STATE))));
+
+ assertEquals(WifiManager.WIFI_STATE_ENABLED, mMySync.expectedWifiState);
+ assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMySync.expectedP2pState);
+
+ mWifiP2pManager =
+ (WifiP2pManager) getContext().getSystemService(Context.WIFI_P2P_SERVICE);
+ mWifiP2pChannel = mWifiP2pManager.initialize(
+ getContext(), getContext().getMainLooper(), null);
+
+ assertNotNull(mWifiP2pManager);
+ assertNotNull(mWifiP2pChannel);
+
+ assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+ // wait for changing to EnabledState
+ assertNotNull(mMySync.expectedNetworkInfo);
+ assertTrue(mMySync.expectedNetworkInfo.isAvailable());
+
+ return true;
+ }
+
+ public void testConcurrency() {
+ if (!setupWifiP2p()) {
return;
}
- // Enable wifi
- SystemUtil.runShellCommand("svc wifi enable");
+ resetResponse(mMyResponse);
+ mWifiP2pManager.requestP2pState(mWifiP2pChannel, new WifiP2pManager.P2pStateListener() {
+ @Override
+ public void onP2pStateAvailable(int state) {
+ synchronized (mMyResponse) {
+ mMyResponse.valid = true;
+ mMyResponse.p2pState = state;
+ mMyResponse.notify();
+ }
+ }
+ });
+ assertTrue(waitForServiceResponse(mMyResponse));
+ assertEquals(WifiP2pManager.WIFI_P2P_STATE_ENABLED, mMyResponse.p2pState);
+ }
- waitForBroadcasts();
+ public void testRequestDiscoveryState() {
+ if (!setupWifiP2p()) {
+ return;
+ }
- assertTrue(mMySync.expectedWifiState == WifiManager.WIFI_STATE_ENABLED);
- assertTrue(mMySync.expectedP2pState == WifiP2pManager.WIFI_P2P_STATE_ENABLED);
+ resetResponse(mMyResponse);
+ mWifiP2pManager.requestDiscoveryState(
+ mWifiP2pChannel, new WifiP2pManager.DiscoveryStateListener() {
+ @Override
+ public void onDiscoveryStateAvailable(int state) {
+ synchronized (mMyResponse) {
+ mMyResponse.valid = true;
+ mMyResponse.discoveryState = state;
+ mMyResponse.notify();
+ }
+ }
+ });
+ assertTrue(waitForServiceResponse(mMyResponse));
+ assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED, mMyResponse.discoveryState);
+
+ resetResponse(mMyResponse);
+ mWifiP2pManager.discoverPeers(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
+ @Override
+ public void onSuccess() {
+ synchronized (mMyResponse) {
+ mMyResponse.valid = true;
+ mMyResponse.success = true;
+ mMyResponse.notify();
+ }
+ }
+
+ @Override
+ public void onFailure(int reason) {
+ synchronized (mMyResponse) {
+ Log.d(TAG, "discoveryPeers failure reason: " + reason);
+ mMyResponse.valid = true;
+ mMyResponse.success = false;
+ mMyResponse.notify();
+ }
+ }
+ });
+ assertTrue(waitForServiceResponse(mMyResponse));
+ assertTrue(mMyResponse.success);
+ assertTrue(waitForBroadcasts(MySync.DISCOVERY_STATE));
+
+ resetResponse(mMyResponse);
+ mWifiP2pManager.requestDiscoveryState(mWifiP2pChannel,
+ new WifiP2pManager.DiscoveryStateListener() {
+ @Override
+ public void onDiscoveryStateAvailable(int state) {
+ synchronized (mMyResponse) {
+ mMyResponse.valid = true;
+ mMyResponse.discoveryState = state;
+ mMyResponse.notify();
+ }
+ }
+ });
+ assertTrue(waitForServiceResponse(mMyResponse));
+ assertEquals(WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED, mMyResponse.discoveryState);
+
+ mWifiP2pManager.stopPeerDiscovery(mWifiP2pChannel, null);
+ }
+
+ public void testRequestNetworkInfo() {
+ if (!setupWifiP2p()) {
+ return;
+ }
+
+ resetResponse(mMyResponse);
+ mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel,
+ new WifiP2pManager.NetworkInfoListener() {
+ @Override
+ public void onNetworkInfoAvailable(NetworkInfo info) {
+ synchronized (mMyResponse) {
+ mMyResponse.valid = true;
+ mMyResponse.networkInfo = info;
+ mMyResponse.notify();
+ }
+ }
+ });
+ assertTrue(waitForServiceResponse(mMyResponse));
+ assertNotNull(mMyResponse.networkInfo);
+ // The state might be IDLE, DISCONNECTED, FAILED before a connection establishment.
+ // Just ensure the state is NOT CONNECTED.
+ assertNotEquals(NetworkInfo.DetailedState.CONNECTED,
+ mMySync.expectedNetworkInfo.getDetailedState());
+
+ resetResponse(mMyResponse);
+ mWifiP2pManager.createGroup(mWifiP2pChannel, new WifiP2pManager.ActionListener() {
+ @Override
+ public void onSuccess() {
+ synchronized (mMyResponse) {
+ mMyResponse.valid = true;
+ mMyResponse.success = true;
+ mMyResponse.notify();
+ }
+ }
+
+ @Override
+ public void onFailure(int reason) {
+ synchronized (mMyResponse) {
+ Log.d(TAG, "createGroup failure reason: " + reason);
+ mMyResponse.valid = true;
+ mMyResponse.success = false;
+ mMyResponse.notify();
+ }
+ }
+ });
+ assertTrue(waitForServiceResponse(mMyResponse));
+ assertTrue(mMyResponse.success);
+ assertTrue(waitForBroadcasts(MySync.NETWORK_INFO));
+ assertNotNull(mMySync.expectedNetworkInfo);
+ assertEquals(NetworkInfo.DetailedState.CONNECTED,
+ mMySync.expectedNetworkInfo.getDetailedState());
+
+ resetResponse(mMyResponse);
+ mWifiP2pManager.requestNetworkInfo(mWifiP2pChannel,
+ new WifiP2pManager.NetworkInfoListener() {
+ @Override
+ public void onNetworkInfoAvailable(NetworkInfo info) {
+ synchronized (mMyResponse) {
+ mMyResponse.valid = true;
+ mMyResponse.networkInfo = info;
+ mMyResponse.notify();
+ }
+ }
+ });
+ assertTrue(waitForServiceResponse(mMyResponse));
+ assertNotNull(mMyResponse.networkInfo);
+ assertEquals(NetworkInfo.DetailedState.CONNECTED,
+ mMyResponse.networkInfo.getDetailedState());
+
+ mWifiP2pManager.removeGroup(mWifiP2pChannel, null);
}
}