blob: 0f0c739f64d9ea07acc1e4cd51f5c42a4b6aed74 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.wifi.aware.cts;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.MacAddress;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.net.wifi.aware.AttachCallback;
import android.net.wifi.aware.AwareParams;
import android.net.wifi.aware.AwareResources;
import android.net.wifi.aware.Characteristics;
import android.net.wifi.aware.DiscoverySession;
import android.net.wifi.aware.DiscoverySessionCallback;
import android.net.wifi.aware.IdentityChangedListener;
import android.net.wifi.aware.ParcelablePeerHandle;
import android.net.wifi.aware.PeerHandle;
import android.net.wifi.aware.PublishConfig;
import android.net.wifi.aware.PublishDiscoverySession;
import android.net.wifi.aware.ServiceDiscoveryInfo;
import android.net.wifi.aware.SubscribeConfig;
import android.net.wifi.aware.SubscribeDiscoverySession;
import android.net.wifi.aware.WifiAwareDataPathSecurityConfig;
import android.net.wifi.aware.WifiAwareManager;
import android.net.wifi.aware.WifiAwareNetworkSpecifier;
import android.net.wifi.aware.WifiAwareSession;
import android.net.wifi.cts.WifiBuildCompat;
import android.net.wifi.cts.WifiJUnit3TestBase;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Parcel;
import android.platform.test.annotations.AppModeFull;
import androidx.test.filters.SdkSuppress;
import com.android.compatibility.common.util.ApiLevelUtil;
import com.android.compatibility.common.util.ShellIdentityUtils;
import com.android.compatibility.common.util.SystemUtil;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single
* device to validate Wi-Fi Aware.
*/
@AppModeFull(reason = "Cannot get WifiAwareManager in instant app mode")
public class SingleDeviceTest extends WifiJUnit3TestBase {
private static final String TAG = "WifiAwareCtsTests";
// wait for Wi-Fi Aware state changes & network requests callbacks
private static final int WAIT_FOR_AWARE_CHANGE_SECS = 15; // 15 seconds
private static final int WAIT_FOR_NETWORK_STATE_CHANGE_SECS = 25; // 25 seconds
private static final int INTERVAL_BETWEEN_TESTS_SECS = 3; // 3 seconds
private static final int WAIT_FOR_AWARE_INTERFACE_CREATION_SEC = 3; // 3 seconds
private static final int MIN_DISTANCE_MM = 1 * 1000;
private static final int MAX_DISTANCE_MM = 3 * 1000;
private static final byte[] PMK_VALID = "01234567890123456789012345678901".getBytes();
private static final int AVAILABLE_DATA_PATH_COUNT = 2;
private static final int AVAILABLE_PUBLISH_SESSION_COUNT = 8;
private static final int AVAILABLE_SUBSCRIBE_SESSION_COUNT = 8;
private final Object mLock = new Object();
private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest");
private final Handler mHandler;
private Boolean mWasVerboseLoggingEnabled;
{
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
}
private WifiAwareManager mWifiAwareManager;
private WifiManager mWifiManager;
private WifiManager.WifiLock mWifiLock;
private ConnectivityManager mConnectivityManager;
// used to store any WifiAwareSession allocated during tests - will clean-up after tests
private List<WifiAwareSession> mSessions = new ArrayList<>();
private class WifiAwareStateBroadcastReceiver extends BroadcastReceiver {
private final Object mLock = new Object();
private CountDownLatch mBlocker = new CountDownLatch(1);
private int mCountNumber = 0;
@Override
public void onReceive(Context context, Intent intent) {
if (WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED.equals(intent.getAction())) {
synchronized(mLock) {
mCountNumber += 1;
mBlocker.countDown();
mBlocker = new CountDownLatch(1);
}
}
}
boolean waitForStateChange() throws InterruptedException {
CountDownLatch blocker;
synchronized (mLock) {
mCountNumber--;
if (mCountNumber >= 0) {
return true;
}
blocker = mBlocker;
}
return blocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
}
}
private class WifiAwareResourcesBroadcastReceiver extends BroadcastReceiver {
private final Object mLock = new Object();
private CountDownLatch mBlocker = new CountDownLatch(1);
private int mCountNumber = 0;
private AwareResources mResources = null;
@Override
public void onReceive(Context context, Intent intent) {
if (WifiAwareManager.ACTION_WIFI_AWARE_RESOURCE_CHANGED.equals(intent.getAction())) {
synchronized (mLock) {
mCountNumber += 1;
mBlocker.countDown();
mBlocker = new CountDownLatch(1);
mResources = intent.getParcelableExtra(WifiAwareManager.EXTRA_AWARE_RESOURCES);
}
}
}
boolean waitForStateChange() throws InterruptedException {
CountDownLatch blocker;
synchronized (mLock) {
mCountNumber--;
if (mCountNumber >= 0) {
return true;
}
blocker = mBlocker;
}
return blocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
}
public AwareResources getResources() {
return mResources;
}
}
private class AttachCallbackTest extends AttachCallback {
static final int ATTACHED = 0;
static final int ATTACH_FAILED = 1;
static final int ERROR = 2; // no callback: timeout, interruption
private CountDownLatch mBlocker = new CountDownLatch(1);
private int mCallbackCalled = ERROR; // garbage init
private WifiAwareSession mSession = null;
@Override
public void onAttached(WifiAwareSession session) {
mCallbackCalled = ATTACHED;
mSession = session;
synchronized (mLock) {
mSessions.add(session);
}
mBlocker.countDown();
}
@Override
public void onAttachFailed() {
mCallbackCalled = ATTACH_FAILED;
mBlocker.countDown();
}
@Override
public void onAwareSessionTerminated() {
synchronized (mLock) {
mSessions.remove(mSession);
}
mSession = null;
}
/**
* Waits for any of the callbacks to be called - or an error (timeout, interruption).
* Returns one of the ATTACHED, ATTACH_FAILED, or ERROR values.
*/
int waitForAnyCallback() {
try {
boolean noTimeout = mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
mBlocker = new CountDownLatch(1);
if (noTimeout) {
return mCallbackCalled;
} else {
return ERROR;
}
} catch (InterruptedException e) {
return ERROR;
}
}
/**
* Access the session created by a callback. Only useful to be called after calling
* waitForAnyCallback() and getting the ATTACHED code back.
*/
WifiAwareSession getSession() {
return mSession;
}
}
private class IdentityChangedListenerTest extends IdentityChangedListener {
private CountDownLatch mBlocker = new CountDownLatch(1);
private byte[] mMac = null;
@Override
public void onIdentityChanged(byte[] mac) {
mMac = mac;
mBlocker.countDown();
}
/**
* Waits for the listener callback to be called - or an error (timeout, interruption).
* Returns true on callback called, false on error (timeout, interruption).
*/
boolean waitForListener() {
try {
return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
} catch (InterruptedException e) {
return false;
}
}
/**
* Returns the MAC address of the discovery interface supplied to the triggered callback.
*/
byte[] getMac() {
return mMac;
}
}
private class DiscoverySessionCallbackTest extends DiscoverySessionCallback {
static final int ON_PUBLISH_STARTED = 0;
static final int ON_SUBSCRIBE_STARTED = 1;
static final int ON_SESSION_CONFIG_UPDATED = 2;
static final int ON_SESSION_CONFIG_FAILED = 3;
static final int ON_SESSION_TERMINATED = 4;
static final int ON_SERVICE_DISCOVERED = 5;
static final int ON_MESSAGE_SEND_SUCCEEDED = 6;
static final int ON_MESSAGE_SEND_FAILED = 7;
static final int ON_MESSAGE_RECEIVED = 8;
static final int ON_SESSION_DISCOVERED_LOST = 9;
private final Object mLocalLock = new Object();
private CountDownLatch mBlocker;
private int mCurrentWaitForCallback;
private ArrayDeque<Integer> mCallbackQueue = new ArrayDeque<>();
private PublishDiscoverySession mPublishDiscoverySession;
private SubscribeDiscoverySession mSubscribeDiscoverySession;
private void processCallback(int callback) {
synchronized (mLocalLock) {
if (mBlocker != null && mCurrentWaitForCallback == callback) {
mBlocker.countDown();
} else {
mCallbackQueue.addLast(callback);
}
}
}
@Override
public void onPublishStarted(PublishDiscoverySession session) {
mPublishDiscoverySession = session;
processCallback(ON_PUBLISH_STARTED);
}
@Override
public void onSubscribeStarted(SubscribeDiscoverySession session) {
mSubscribeDiscoverySession = session;
processCallback(ON_SUBSCRIBE_STARTED);
}
@Override
public void onSessionConfigUpdated() {
processCallback(ON_SESSION_CONFIG_UPDATED);
}
@Override
public void onSessionConfigFailed() {
processCallback(ON_SESSION_CONFIG_FAILED);
}
@Override
public void onSessionTerminated() {
processCallback(ON_SESSION_TERMINATED);
}
@Override
public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo,
List<byte[]> matchFilter) {
processCallback(ON_SERVICE_DISCOVERED);
}
@Override
public void onServiceDiscovered(ServiceDiscoveryInfo info) {
processCallback(ON_SERVICE_DISCOVERED);
}
@Override
public void onMessageSendSucceeded(int messageId) {
processCallback(ON_MESSAGE_SEND_SUCCEEDED);
}
@Override
public void onMessageSendFailed(int messageId) {
processCallback(ON_MESSAGE_SEND_FAILED);
}
@Override
public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
processCallback(ON_MESSAGE_RECEIVED);
}
@Override
public void onServiceLost(PeerHandle peerHandle, int reason) {
processCallback(ON_SESSION_DISCOVERED_LOST);
}
/**
* Wait for the specified callback - any of the ON_* constants. Returns a true
* on success (specified callback triggered) or false on failure (timed-out or
* interrupted while waiting for the requested callback).
*
* Note: other callbacks happening while while waiting for the specified callback will
* be queued.
*/
boolean waitForCallback(int callback) {
return waitForCallback(callback, WAIT_FOR_AWARE_CHANGE_SECS);
}
/**
* Wait for the specified callback - any of the ON_* constants. Returns a true
* on success (specified callback triggered) or false on failure (timed-out or
* interrupted while waiting for the requested callback).
*
* Same as waitForCallback(int callback) execpt that allows specifying a custom timeout.
* The default timeout is a short value expected to be sufficient for all behaviors which
* should happen relatively quickly. Specifying a custom timeout should only be done for
* those cases which are known to take a specific longer period of time.
*
* Note: other callbacks happening while while waiting for the specified callback will
* be queued.
*/
boolean waitForCallback(int callback, int timeoutSec) {
synchronized (mLocalLock) {
boolean found = mCallbackQueue.remove(callback);
if (found) {
return true;
}
mCurrentWaitForCallback = callback;
mBlocker = new CountDownLatch(1);
}
try {
return mBlocker.await(timeoutSec, TimeUnit.SECONDS);
} catch (InterruptedException e) {
return false;
}
}
/**
* Indicates whether the specified callback (any of the ON_* constants) has already
* happened and in the queue. Useful when the order of events is important.
*/
boolean hasCallbackAlreadyHappened(int callback) {
synchronized (mLocalLock) {
return mCallbackQueue.contains(callback);
}
}
/**
* Returns the last created publish discovery session.
*/
PublishDiscoverySession getPublishDiscoverySession() {
PublishDiscoverySession session = mPublishDiscoverySession;
mPublishDiscoverySession = null;
return session;
}
/**
* Returns the last created subscribe discovery session.
*/
SubscribeDiscoverySession getSubscribeDiscoverySession() {
SubscribeDiscoverySession session = mSubscribeDiscoverySession;
mSubscribeDiscoverySession = null;
return session;
}
}
private class NetworkCallbackTest extends ConnectivityManager.NetworkCallback {
private CountDownLatch mBlocker = new CountDownLatch(1);
@Override
public void onUnavailable() {
mBlocker.countDown();
}
/**
* Wait for the onUnavailable() callback to be triggered. Returns true if triggered,
* otherwise (timed-out, interrupted) returns false.
*/
boolean waitForOnUnavailable() {
try {
return mBlocker.await(WAIT_FOR_NETWORK_STATE_CHANGE_SECS, TimeUnit.SECONDS);
} catch (InterruptedException e) {
return false;
}
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
assertTrue("Wi-Fi Aware requires Location to be Enabled",
((LocationManager) getContext().getSystemService(
Context.LOCATION_SERVICE)).isLocationEnabled());
mWifiAwareManager = (WifiAwareManager) getContext().getSystemService(
Context.WIFI_AWARE_SERVICE);
assertNotNull("Wi-Fi Aware Manager", mWifiAwareManager);
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
assertNotNull("Wi-Fi Manager", mWifiManager);
// turn on verbose logging for tests
mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.isVerboseLoggingEnabled());
ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.setVerboseLoggingEnabled(true));
// Turn on Wi-Fi
mWifiLock = mWifiManager.createWifiLock(TAG);
mWifiLock.acquire();
if (!mWifiManager.isWifiEnabled()) {
SystemUtil.runShellCommand("svc wifi enable");
}
mConnectivityManager = (ConnectivityManager) getContext().getSystemService(
Context.CONNECTIVITY_SERVICE);
assertNotNull("Connectivity Manager", mConnectivityManager);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
WifiAwareStateBroadcastReceiver receiver = new WifiAwareStateBroadcastReceiver();
mContext.registerReceiver(receiver, intentFilter);
if (!mWifiAwareManager.isAvailable()) {
assertTrue("Timeout waiting for Wi-Fi Aware to change status",
receiver.waitForStateChange());
assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable());
}
}
@Override
protected void tearDown() throws Exception {
if (!TestUtils.shouldTestWifiAware(getContext())) {
super.tearDown();
return;
}
synchronized (mLock) {
for (WifiAwareSession session : mSessions) {
// no damage from destroying twice (i.e. ok if test cleaned up after itself already)
session.close();
}
mSessions.clear();
}
ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
super.tearDown();
Thread.sleep(INTERVAL_BETWEEN_TESTS_SECS * 1000);
}
/**
* Validate:
* - Characteristics are available
* - Characteristics values are legitimate. Not in the CDD. However, the tested values are
* based on the Wi-Fi Aware protocol.
*/
public void testCharacteristics() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
Characteristics characteristics = mWifiAwareManager.getCharacteristics();
assertNotNull("Wi-Fi Aware characteristics are null", characteristics);
assertEquals("Service Name Length", characteristics.getMaxServiceNameLength(), 255);
assertEquals("Service Specific Information Length",
characteristics.getMaxServiceSpecificInfoLength(), 255);
assertEquals("Match Filter Length", characteristics.getMaxMatchFilterLength(), 255);
assertNotEquals("Cipher suites", characteristics.getSupportedCipherSuites(), 0);
assertTrue("Max number of NDP", characteristics.getNumberOfSupportedDataPaths() > 0);
assertTrue("Max number of NDI", characteristics.getNumberOfSupportedDataInterfaces() > 0);
assertTrue("Max number of Publish sessions",
characteristics.getNumberOfSupportedPublishSessions() > 0);
assertTrue("Max number of Subscribe sessions",
characteristics.getNumberOfSupportedSubscribeSessions() > 0);
if (ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S)) {
ShellIdentityUtils.invokeWithShellPermissions(() ->
mWifiAwareManager.enableInstantCommunicationMode(true));
assertEquals(mWifiAwareManager.isInstantCommunicationModeEnabled(),
characteristics.isInstantCommunicationModeSupported());
ShellIdentityUtils.invokeWithShellPermissions(() ->
mWifiAwareManager.enableInstantCommunicationMode(false));
}
}
/**
* Validate:
* - AwareResources are available
* - AwareResources values are legitimate. When no resources are used, the value should equal to
* the capability.
*/
public void testAvailableAwareResources() {
if (!(TestUtils.shouldTestWifiAware(getContext())
&& WifiBuildCompat.isPlatformOrWifiModuleAtLeastS(getContext()))) {
return;
}
AwareResources resources = mWifiAwareManager.getAvailableAwareResources();
assertNotNull("Available aware resources are null", resources);
assertTrue(resources.getAvailableDataPathsCount() > 0);
assertTrue(resources.getAvailablePublishSessionsCount() > 0);
assertTrue(resources.getAvailableSubscribeSessionsCount() > 0);
}
/**
* Validate that on Wi-Fi Aware availability change we get a broadcast + the API returns
* correct status.
*/
public void testAvailabilityStatusChange() throws Exception {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
// 1. Disable Wi-Fi
WifiAwareStateBroadcastReceiver receiver1 = new WifiAwareStateBroadcastReceiver();
mContext.registerReceiver(receiver1, intentFilter);
SystemUtil.runShellCommand("svc wifi disable");
assertTrue("Timeout waiting for Wi-Fi Aware to change status",
receiver1.waitForStateChange());
// Interface down event may happen before Wifi State change. In that case, Aware available
// state will keep true for a short time.
if (mWifiAwareManager.isAvailable()) {
assertTrue("Timeout waiting for Wi-Fi Aware to change status",
receiver1.waitForStateChange());
}
assertFalse("Wi-Fi Aware is available (should not be)", mWifiAwareManager.isAvailable());
// 2. Enable Wi-Fi
WifiAwareStateBroadcastReceiver receiver2 = new WifiAwareStateBroadcastReceiver();
mContext.registerReceiver(receiver2, intentFilter);
SystemUtil.runShellCommand("svc wifi enable");
assertTrue("Timeout waiting for Wi-Fi Aware to change status",
receiver2.waitForStateChange());
assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable());
}
/**
* Validate that can attach to Wi-Fi Aware.
*/
public void testAttachNoIdentity() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
AttachCallbackTest callback = attachAndGetCallback();
callback.getSession().close();
callback.waitForAnyCallback();
assertNull(callback.getSession());
if (WifiBuildCompat.isPlatformOrWifiModuleAtLeastS(getContext())) {
assertFalse(mWifiAwareManager.isDeviceAttached());
}
}
/**
* Validate that can attach to Wi-Fi Aware and get identity information. Use the identity
* information to validate that MAC address changes on every attach.
*
* Note: relies on no other entity using Wi-Fi Aware during the CTS test. Since if it is used
* then the attach/destroy will not correspond to enable/disable and will not result in a new
* MAC address being generated.
*/
public void testAttachDiscoveryAddressChanges() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
final int numIterations = 10;
Set<TestUtils.MacWrapper> macs = new HashSet<>();
for (int i = 0; i < numIterations; ++i) {
AttachCallbackTest attachCb = new AttachCallbackTest();
IdentityChangedListenerTest identityL = new IdentityChangedListenerTest();
mWifiAwareManager.attach(attachCb, identityL, mHandler);
assertEquals("Wi-Fi Aware attach: iteration " + i, AttachCallbackTest.ATTACHED,
attachCb.waitForAnyCallback());
assertTrue("Wi-Fi Aware attach: iteration " + i, identityL.waitForListener());
WifiAwareSession session = attachCb.getSession();
assertNotNull("Wi-Fi Aware session: iteration " + i, session);
byte[] mac = identityL.getMac();
assertNotNull("Wi-Fi Aware discovery MAC: iteration " + i, mac);
session.close();
macs.add(new TestUtils.MacWrapper(mac));
}
assertEquals("", numIterations, macs.size());
}
/**
* Validate a successful publish discovery session lifetime: publish, update publish, destroy.
*/
public void testPublishDiscoverySuccess() throws Exception {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_RESOURCE_CHANGED);
WifiAwareResourcesBroadcastReceiver receiver = new WifiAwareResourcesBroadcastReceiver();
mContext.registerReceiver(receiver, intentFilter);
final String serviceName = "PublishName";
WifiAwareSession session = attachAndGetSession();
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
serviceName).build();
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
int numOfAllPublishSessions = mWifiAwareManager
.getAvailableAwareResources().getAvailablePublishSessionsCount();
// 1. publish
session.publish(publishConfig, discoveryCb, mHandler);
assertTrue("Publish started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
assertNotNull("Publish session", discoverySession);
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SERVICE_DISCOVERED));
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_DISCOVERED_LOST));
assertEquals(numOfAllPublishSessions - 1, mWifiAwareManager
.getAvailableAwareResources().getAvailablePublishSessionsCount());
//TODO(211696926): Change to isAtLeast() when SDK finalize.
if (ApiLevelUtil.codenameStartsWith("T")) {
assertTrue("Time out waiting for resource change", receiver.waitForStateChange());
assertEquals(numOfAllPublishSessions - 1, receiver.getResources()
.getAvailablePublishSessionsCount());
}
// 2. update-publish
publishConfig = new PublishConfig.Builder().setServiceName(
serviceName).setServiceSpecificInfo("extras".getBytes()).build();
discoverySession.updatePublish(publishConfig);
assertTrue("Publish update", discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
// 3. destroy
assertFalse("Publish not terminated", discoveryCb.hasCallbackAlreadyHappened(
DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
discoverySession.close();
// 4. try update post-destroy: should time-out waiting for cb
discoverySession.updatePublish(publishConfig);
assertFalse("Publish update post destroy", discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
assertEquals(numOfAllPublishSessions, mWifiAwareManager
.getAvailableAwareResources().getAvailablePublishSessionsCount());
//TODO(211696926): Change to isAtLeast() when SDK finalize.
if (ApiLevelUtil.codenameStartsWith("T")) {
assertTrue("Time out waiting for resource change", receiver.waitForStateChange());
assertEquals(numOfAllPublishSessions, receiver.getResources()
.getAvailablePublishSessionsCount());
session.close();
}
}
/**
* Validate that publish with a Time To Live (TTL) setting expires within the specified
* time (and validates that the terminate callback is triggered).
*/
public void testPublishLimitedTtlSuccess() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
final String serviceName = "PublishName";
final int ttlSec = 5;
WifiAwareSession session = attachAndGetSession();
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build();
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
// 1. publish
session.publish(publishConfig, discoveryCb, mHandler);
assertTrue("Publish started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
assertNotNull("Publish session", discoverySession);
// 2. wait for terminate within 'ttlSec'.
assertTrue("Publish terminated",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED,
ttlSec + 5));
// 3. try update post-termination: should time-out waiting for cb
publishConfig = new PublishConfig.Builder().setServiceName(
serviceName).setServiceSpecificInfo("extras".getBytes()).build();
discoverySession.updatePublish(publishConfig);
assertFalse("Publish update post terminate", discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
session.close();
}
/**
* Validate successful publish session with security config.
*/
public void testPublishWithSecurityConfig() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
final String serviceName = "PublishName";
final String passphrase = "SomePassword";
final byte[] pmk = "01234567890123456789012345678901".getBytes();
final byte[] pmkId = "0123456789012345".getBytes();
WifiAwareSession session = attachAndGetSession();
WifiAwareDataPathSecurityConfig securityConfig = new WifiAwareDataPathSecurityConfig
.Builder(Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128)
.setPskPassphrase(passphrase)
.build();
assertEquals(passphrase, securityConfig.getPskPassphrase());
assertEquals(Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_SK_128,
securityConfig.getCipherSuite());
assertNull(securityConfig.getPmkId());
assertNull(securityConfig.getPmk());
PublishConfig.Builder builder = new PublishConfig.Builder()
.setServiceName(serviceName)
.setDataPathSecurityConfig(securityConfig);
PublishConfig publishConfig = builder.build();
assertEquals(securityConfig, publishConfig.getSecurityConfig());
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
// 1. publish
session.publish(publishConfig, discoveryCb, mHandler);
assertTrue("Publish started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
assertNotNull("Publish session", discoverySession);
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SERVICE_DISCOVERED));
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_DISCOVERED_LOST));
// 2. update to PK cipher suite
if ((mWifiAwareManager.getCharacteristics().getSupportedCipherSuites()
& Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128) != 0) {
securityConfig = new WifiAwareDataPathSecurityConfig
.Builder(Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_128)
.setPmk(pmk)
.setPmkId(pmkId)
.build();
publishConfig = new PublishConfig.Builder()
.setServiceName(serviceName)
.setDataPathSecurityConfig(securityConfig)
.build();
discoverySession.updatePublish(publishConfig);
assertTrue("Publish update", discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
}
// 3. destroy
assertFalse("Publish not terminated", discoveryCb.hasCallbackAlreadyHappened(
DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
discoverySession.close();
session.close();
}
/**
* Validate success publish with instant communacation enabled.
*/
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu")
public void testPublishWithInstantCommunicationModeSuccess() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
Characteristics characteristics = mWifiAwareManager.getCharacteristics();
if (!characteristics.isInstantCommunicationModeSupported()) {
return;
}
final String serviceName = "PublishName";
WifiAwareSession session = attachAndGetSession();
PublishConfig publishConfig = new PublishConfig.Builder()
.setServiceName(serviceName)
.setInstantCommunicationModeEnabled(true, WifiScanner.WIFI_BAND_24_GHZ)
.build();
assertEquals(WifiScanner.WIFI_BAND_24_GHZ, publishConfig.getInstantCommunicationBand());
assertTrue(publishConfig.isInstantCommunicationModeEnabled());
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
// 1. publish
session.publish(publishConfig, discoveryCb, mHandler);
assertTrue("Publish started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
assertNotNull("Publish session", discoverySession);
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SERVICE_DISCOVERED));
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_DISCOVERED_LOST));
// 2. destroy
assertFalse("Publish not terminated", discoveryCb.hasCallbackAlreadyHappened(
DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
discoverySession.close();
session.close();
}
/**
* Validate a successful subscribe discovery session lifetime: subscribe, update subscribe,
* destroy.
*/
public void testSubscribeDiscoverySuccess() throws Exception {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_RESOURCE_CHANGED);
WifiAwareResourcesBroadcastReceiver receiver = new WifiAwareResourcesBroadcastReceiver();
mContext.registerReceiver(receiver, intentFilter);
final String serviceName = "SubscribeName";
WifiAwareSession session = attachAndGetSession();
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(
serviceName).build();
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
int numOfAllSubscribeSessions = mWifiAwareManager
.getAvailableAwareResources().getAvailableSubscribeSessionsCount();
// 1. subscribe
session.subscribe(subscribeConfig, discoveryCb, mHandler);
assertTrue("Subscribe started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED));
SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession();
assertNotNull("Subscribe session", discoverySession);
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SERVICE_DISCOVERED));
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_DISCOVERED_LOST));
assertEquals(numOfAllSubscribeSessions - 1, mWifiAwareManager
.getAvailableAwareResources().getAvailableSubscribeSessionsCount());
//TODO(211696926): Change to isAtLeast() when SDK finalize.
if (ApiLevelUtil.codenameStartsWith("T")) {
assertTrue("Time out waiting for resource change", receiver.waitForStateChange());
assertEquals(numOfAllSubscribeSessions - 1, receiver.getResources()
.getAvailableSubscribeSessionsCount());
}
// 2. update-subscribe
boolean rttSupported = getContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WIFI_RTT);
SubscribeConfig.Builder builder = new SubscribeConfig.Builder().setServiceName(
serviceName).setServiceSpecificInfo("extras".getBytes());
if (rttSupported) {
builder.setMinDistanceMm(MIN_DISTANCE_MM);
}
subscribeConfig = builder.build();
discoverySession.updateSubscribe(subscribeConfig);
assertTrue("Subscribe update", discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
// 3. destroy
assertFalse("Subscribe not terminated", discoveryCb.hasCallbackAlreadyHappened(
DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
discoverySession.close();
// 4. try update post-destroy: should time-out waiting for cb
discoverySession.updateSubscribe(subscribeConfig);
assertFalse("Subscribe update post destroy", discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
assertEquals(numOfAllSubscribeSessions, mWifiAwareManager
.getAvailableAwareResources().getAvailableSubscribeSessionsCount());
//TODO(211696926): Change to isAtLeast() when SDK finalize.
if (ApiLevelUtil.codenameStartsWith("T")) {
assertTrue("Time out waiting for resource change", receiver.waitForStateChange());
assertEquals(numOfAllSubscribeSessions, receiver.getResources()
.getAvailableSubscribeSessionsCount());
}
session.close();
}
/**
* Validate success subscribe with instant communication enabled.
*/
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU, codeName = "Tiramisu")
public void testSubscribeWithInstantCommunicationModeSuccess() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
Characteristics characteristics = mWifiAwareManager.getCharacteristics();
if (!characteristics.isInstantCommunicationModeSupported()) {
return;
}
final String serviceName = "SubscribeName";
WifiAwareSession session = attachAndGetSession();
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder()
.setServiceName(serviceName)
.setInstantCommunicationModeEnabled(true, WifiScanner.WIFI_BAND_24_GHZ)
.build();
assertEquals(WifiScanner.WIFI_BAND_24_GHZ, subscribeConfig.getInstantCommunicationBand());
assertTrue(subscribeConfig.isInstantCommunicationModeEnabled());
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
// 1. subscribe
session.subscribe(subscribeConfig, discoveryCb, mHandler);
assertTrue("Subscribe started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED));
SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession();
assertNotNull("Subscribe session", discoverySession);
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SERVICE_DISCOVERED));
assertFalse(discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_DISCOVERED_LOST));
// 3. destroy
assertFalse("Subscribe not terminated", discoveryCb.hasCallbackAlreadyHappened(
DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
discoverySession.close();
session.close();
}
/**
* Validate that subscribe with a Time To Live (TTL) setting expires within the specified
* time (and validates that the terminate callback is triggered).
*/
public void testSubscribeLimitedTtlSuccess() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
final String serviceName = "SubscribeName";
final int ttlSec = 5;
WifiAwareSession session = attachAndGetSession();
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(
serviceName).setTtlSec(ttlSec).setTerminateNotificationEnabled(true).build();
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
// 1. subscribe
session.subscribe(subscribeConfig, discoveryCb, mHandler);
assertTrue("Subscribe started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED));
SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession();
assertNotNull("Subscribe session", discoverySession);
// 2. wait for terminate within 'ttlSec'.
assertTrue("Subscribe terminated",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SESSION_TERMINATED,
ttlSec + 5));
// 3. try update post-termination: should time-out waiting for cb
subscribeConfig = new SubscribeConfig.Builder().setServiceName(
serviceName).setServiceSpecificInfo("extras".getBytes()).build();
discoverySession.updateSubscribe(subscribeConfig);
assertFalse("Subscribe update post terminate", discoveryCb.waitForCallback(
DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
session.close();
}
/**
* Test the send message flow. Since testing single device cannot send to a real peer -
* validate that sending to a bogus peer fails.
*/
public void testSendMessageFail() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
WifiAwareSession session = attachAndGetSession();
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
"ValidName").build();
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
// 1. publish
session.publish(publishConfig, discoveryCb, mHandler);
assertTrue("Publish started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
assertNotNull("Publish session", discoverySession);
// 2. send a message with a null peer-handle - expect exception
try {
discoverySession.sendMessage(null, -1290, "some message".getBytes());
fail("Expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// empty
}
discoverySession.close();
session.close();
}
/**
* Request an Aware data-path (open) as a Responder with an arbitrary peer MAC address. Validate
* that receive an onUnavailable() callback.
*/
public void testDataPathOpenOutOfBandFail() throws InterruptedException {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
// 1. initialize Aware: only purpose is to make sure it is available for OOB data-path
WifiAwareSession session = attachAndGetSession();
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
"ValidName").build();
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
session.publish(publishConfig, discoveryCb, mHandler);
assertTrue("Publish started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
Thread.sleep(WAIT_FOR_AWARE_INTERFACE_CREATION_SEC * 1000);
// 2. request an AWARE network
NetworkCallbackTest networkCb = new NetworkCallbackTest();
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
session.createNetworkSpecifierOpen(
WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR,
mac.toByteArray())).build();
mConnectivityManager.requestNetwork(nr, networkCb);
assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable());
session.close();
}
/**
* Request an Aware data-path (encrypted with Passphrase) as a Responder with an arbitrary peer
* MAC address.
* Validate that receive an onUnavailable() callback.
*/
public void testDataPathPassphraseOutOfBandFail() throws InterruptedException {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
// 1. initialize Aware: only purpose is to make sure it is available for OOB data-path
WifiAwareSession session = attachAndGetSession();
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
"ValidName").build();
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
session.publish(publishConfig, discoveryCb, mHandler);
assertTrue("Publish started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
Thread.sleep(WAIT_FOR_AWARE_INTERFACE_CREATION_SEC * 1000);
// 2. request an AWARE network
NetworkCallbackTest networkCb = new NetworkCallbackTest();
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
session.createNetworkSpecifierPassphrase(
WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(),
"abcdefghihk")).build();
mConnectivityManager.requestNetwork(nr, networkCb);
assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable());
session.close();
}
/**
* Request an Aware data-path (encrypted with PMK) as a Responder with an arbitrary peer MAC
* address.
* Validate that receive an onUnavailable() callback.
*/
public void testDataPathPmkOutOfBandFail() throws InterruptedException {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
// 1. initialize Aware: only purpose is to make sure it is available for OOB data-path
WifiAwareSession session = attachAndGetSession();
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
"ValidName").build();
DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
session.publish(publishConfig, discoveryCb, mHandler);
assertTrue("Publish started",
discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
Thread.sleep(WAIT_FOR_AWARE_INTERFACE_CREATION_SEC * 1000);
// 2. request an AWARE network
NetworkCallbackTest networkCb = new NetworkCallbackTest();
NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
session.createNetworkSpecifierPmk(
WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR, mac.toByteArray(),
PMK_VALID)).build();
mConnectivityManager.requestNetwork(nr, networkCb);
assertTrue("OnUnavailable not received", networkCb.waitForOnUnavailable());
session.close();
}
/**
* Test WifiAwareNetworkSpecifier.
*/
public void testWifiAwareNetworkSpecifier() {
DiscoverySession session = mock(DiscoverySession.class);
PeerHandle handle = mock(PeerHandle.class);
WifiAwareNetworkSpecifier networkSpecifier =
new WifiAwareNetworkSpecifier.Builder(session, handle).build();
assertFalse(networkSpecifier.canBeSatisfiedBy(null));
assertTrue(networkSpecifier.canBeSatisfiedBy(networkSpecifier));
WifiAwareNetworkSpecifier anotherNetworkSpecifier =
new WifiAwareNetworkSpecifier.Builder(session, handle).setPmk(PMK_VALID).build();
assertFalse(networkSpecifier.canBeSatisfiedBy(anotherNetworkSpecifier));
}
/**
* Test ParcelablePeerHandle parcel.
*/
public void testParcelablePeerHandle() {
PeerHandle peerHandle = mock(PeerHandle.class);
ParcelablePeerHandle parcelablePeerHandle = new ParcelablePeerHandle(peerHandle);
Parcel parcelW = Parcel.obtain();
parcelablePeerHandle.writeToParcel(parcelW, 0);
byte[] bytes = parcelW.marshall();
parcelW.recycle();
Parcel parcelR = Parcel.obtain();
parcelR.unmarshall(bytes, 0, bytes.length);
parcelR.setDataPosition(0);
ParcelablePeerHandle rereadParcelablePeerHandle =
ParcelablePeerHandle.CREATOR.createFromParcel(parcelR);
assertEquals(parcelablePeerHandle, rereadParcelablePeerHandle);
assertEquals(parcelablePeerHandle.hashCode(), rereadParcelablePeerHandle.hashCode());
}
/**
* Test AwareResources constructor function.
*/
public void testAwareResourcesConstructor() {
AwareResources awareResources = new AwareResources(AVAILABLE_DATA_PATH_COUNT,
AVAILABLE_PUBLISH_SESSION_COUNT, AVAILABLE_SUBSCRIBE_SESSION_COUNT);
assertEquals(AVAILABLE_DATA_PATH_COUNT, awareResources.getAvailableDataPathsCount());
assertEquals(AVAILABLE_PUBLISH_SESSION_COUNT, awareResources
.getAvailablePublishSessionsCount());
assertEquals(AVAILABLE_SUBSCRIBE_SESSION_COUNT, awareResources
.getAvailableSubscribeSessionsCount());
}
/**
* Verify setAwareParams works when have permission
*/
public void testAwareParams() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
AwareParams params = new AwareParams();
params.setDiscoveryWindowWakeInterval24Ghz(5);
params.setDiscoveryWindowWakeInterval5Ghz(5);
params.setDiscoveryBeaconIntervalMillis(50);
params.setDwEarlyTerminationEnabled(true);
params.setMacRandomizationIntervalSeconds(1000);
params.setNumSpatialStreamsInDiscovery(1);
assertEquals(5, params.getDiscoveryWindowWakeInterval24Ghz());
assertEquals(5, params.getDiscoveryWindowWakeInterval5Ghz());
assertEquals(50, params.getDiscoveryBeaconIntervalMillis());
assertEquals(1000, params.getMacRandomizationIntervalSeconds());
assertEquals(1, params.getNumSpatialStreamsInDiscovery());
assertTrue(params.isDwEarlyTerminationEnabled());
if (ApiLevelUtil.isAtLeast(Build.VERSION_CODES.TIRAMISU)
|| ApiLevelUtil.codenameStartsWith("T")) {
ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiAwareManager.setAwareParams(params)
);
ShellIdentityUtils.invokeWithShellPermissions(
() -> mWifiAwareManager.setAwareParams(null)
);
}
}
/**
* Verify setAwareParams throw exception without permission
*/
public void testAwareParamsWithoutPermission() {
if (!TestUtils.shouldTestWifiAware(getContext())) {
return;
}
assertThrows(SecurityException.class, () -> mWifiAwareManager.setAwareParams(null));
}
// local utilities
private WifiAwareSession attachAndGetSession() {
AttachCallbackTest attachCb = new AttachCallbackTest();
mWifiAwareManager.attach(attachCb, mHandler);
int cbCalled = attachCb.waitForAnyCallback();
assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled);
WifiAwareSession session = attachCb.getSession();
assertNotNull("Wi-Fi Aware session", session);
if (ApiLevelUtil.isAtLeast(Build.VERSION_CODES.S)) {
assertTrue(mWifiAwareManager.isDeviceAttached());
}
return session;
}
// local utilities
private AttachCallbackTest attachAndGetCallback() {
AttachCallbackTest attachCb = new AttachCallbackTest();
mWifiAwareManager.attach(attachCb, mHandler);
int cbCalled = attachCb.waitForAnyCallback();
assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled);
return attachCb;
}
}