[Aware] Fix the offloading transition for device does not support FW priority
Bug: 266092994
Test: atest com.android.server.wifi, SingleDeviceTest
Change-Id: Ie8b17696a7f49e95cd357810ecd1f30c2e9e0592
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index f772cc1..e8e5f87 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -287,6 +287,8 @@
"bootstrapping_request_id";
private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_ACCEPT = "bootstrapping_accept";
private static final String MESSAGE_BUNDLE_KEY_AWARE_OFFLOAD = "aware_offload";
+ private static final String MESSAGE_BUNDLE_KEY_RE_ENABLE_AWARE_FROM_OFFLOAD =
+ "aware_re_enable_from_offload";
private WifiAwareNativeApi mWifiAwareNativeApi;
@@ -1018,10 +1020,14 @@
@Nullable String callingFeatureId, IWifiAwareEventCallback callback,
ConfigRequest configRequest, boolean notifyOnIdentityChanged, Bundle extra,
boolean forAwareOffload) {
+ boolean reEnableAware = false;
+ // If FW could not handle the Aware request priority, disable the Aware first
if (!mContext.getResources()
.getBoolean(R.bool.config_wifiAwareOffloadingFirmwareHandlePriority)
&& isAwareOffloading() && !forAwareOffload) {
- deferDisableAware();
+ // Do not release Aware, as new request will get Interface again
+ deferDisableAware(false);
+ reEnableAware = true;
}
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_CONNECT;
@@ -1036,7 +1042,9 @@
notifyOnIdentityChanged);
msg.getData().putBundle(MESSAGE_BUNDLE_KEY_ATTRIBUTION_SOURCE, extra);
msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_AWARE_OFFLOAD, forAwareOffload);
+ msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_RE_ENABLE_AWARE_FROM_OFFLOAD, reEnableAware);
mSm.sendMessage(msg);
+ // Clean the client after the connect to avoid Aware disable
if (!forAwareOffload) {
for (int i = 0; i < mClients.size(); i++) {
WifiAwareClientState clientState = mClients.valueAt(i);
@@ -1060,11 +1068,13 @@
/**
* Place a request to defer Disable Aware on the state machine queue.
+ * @param releaseAware
*/
- private void deferDisableAware() {
+ private void deferDisableAware(boolean releaseAware) {
mAwareIsDisabling = true;
Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND);
msg.arg1 = COMMAND_TYPE_DISABLE;
+ msg.obj = releaseAware;
mSm.sendMessage(msg);
}
@@ -2461,6 +2471,8 @@
MESSAGE_BUNDLE_KEY_NOTIFY_IDENTITY_CHANGE);
boolean awareOffload = msg.getData().getBoolean(
MESSAGE_BUNDLE_KEY_AWARE_OFFLOAD);
+ boolean reEnableAware = msg.getData()
+ .getBoolean(MESSAGE_BUNDLE_KEY_RE_ENABLE_AWARE_FROM_OFFLOAD);
WorkSource workSource;
if (awareOffload) {
workSource = new WorkSource(Process.WIFI_UID);
@@ -2492,7 +2504,7 @@
callingPackage, callingFeatureId, callback, configRequest,
notifyIdentityChange,
msg.getData().getBundle(MESSAGE_BUNDLE_KEY_ATTRIBUTION_SOURCE),
- awareOffload);
+ awareOffload, reEnableAware);
} else { // InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER
waitForResponse = false;
}
@@ -3295,11 +3307,14 @@
private boolean connectLocal(short transactionId, int clientId, int uid, int pid,
String callingPackage, @Nullable String callingFeatureId,
IWifiAwareEventCallback callback, ConfigRequest configRequest,
- boolean notifyIdentityChange, Bundle extra, boolean awareOffload) {
+ boolean notifyIdentityChange, Bundle extra, boolean awareOffload,
+ boolean reEnableAware) {
mLocalLog.log("connectLocal(): transactionId=" + transactionId + ", clientId=" + clientId
+ ", uid=" + uid + ", pid=" + pid + ", callingPackage=" + callingPackage
+ ", callback=" + callback + ", configRequest=" + configRequest
- + ", notifyIdentityChange=" + notifyIdentityChange);
+ + ", notifyIdentityChange=" + notifyIdentityChange
+ + ", awareOffload" + awareOffload
+ + ", reEnableAware" + reEnableAware);
if (!mUsageEnabled) {
Log.w(TAG, "connect(): called with mUsageEnabled=false");
@@ -3337,7 +3352,8 @@
}
if (mCurrentAwareConfiguration != null && mCurrentAwareConfiguration.equals(merged)
- && (mCurrentIdentityNotification || !notifyIdentityChange)) {
+ && (mCurrentIdentityNotification || !notifyIdentityChange)
+ && !reEnableAware) {
if (awareOffload && !isAwareOffloading()) {
try {
mLocalLog.log("Connect failure for clientId:" + clientId);
@@ -3387,9 +3403,10 @@
}
mWifiAwareNativeManager.tryToGetAware(workSource);
}
-
+ boolean initialConfiguration = mCurrentAwareConfiguration == null
+ || reEnableAware;
boolean success = mWifiAwareNativeApi.enableAndConfigure(transactionId, merged,
- notificationRequired, mCurrentAwareConfiguration == null,
+ notificationRequired, initialConfiguration,
mPowerManager.isInteractive(), mPowerManager.isDeviceIdleMode(),
rangingRequired, enableInstantMode, instantModeChannel, mClusterIdInt);
if (!success) {
@@ -3432,7 +3449,7 @@
mCurrentRangingEnabled = false;
mCurrentIdentityNotification = false;
mInstantCommModeClientRequest = INSTANT_MODE_DISABLED;
- deferDisableAware();
+ deferDisableAware(true);
return false;
}
@@ -3777,7 +3794,7 @@
mCurrentRangingEnabled = false;
mCurrentIdentityNotification = false;
mInstantCommModeClientRequest = INSTANT_MODE_DISABLED;
- deferDisableAware();
+ deferDisableAware(true);
sendAwareStateChangedBroadcast(markAsAvailable);
if (!markAsAvailable) {
mAwareMetrics.recordDisableUsage();
@@ -3948,7 +3965,12 @@
Log.e(TAG, "onDisableResponseLocal: FAILED!? command=" + command + ", reason="
+ reason);
}
- mWifiAwareNativeManager.releaseAware();
+
+ boolean releaseAware = (boolean) command.obj;
+ if (releaseAware) {
+ // Need to release Aware
+ mWifiAwareNativeManager.releaseAware();
+ }
mAwareMetrics.recordDisableAware();
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
index b857fa8..30cf8b8 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
@@ -43,6 +43,7 @@
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -209,7 +210,6 @@
mResources = new MockResources();
mResources.setInteger(R.integer.config_wifiAwareInstantCommunicationModeDurationMillis,
30000);
- mResources.setBoolean(R.bool.config_wifiAwareOffloadingFirmwareHandlePriority, true);
when(mMockContext.getResources()).thenReturn(mResources);
when(mInterfaceConflictManager.manageInterfaceConflictForStateMachine(any(), any(), any(),
@@ -5235,7 +5235,8 @@
* that IdentityChanged not delivered if configuration disables delivery.
*/
@Test
- public void testAwareWithOffloading() throws Exception {
+ public void testAwareWithOffloadingWithFwHandlePriority() throws Exception {
+ mResources.setBoolean(R.bool.config_wifiAwareOffloadingFirmwareHandlePriority, true);
final int clientId1 = 1005;
final int clientId2 = 1007;
final int clusterLow = 5;
@@ -5274,10 +5275,84 @@
// (2) connect Aware session for App
mDut.connect(clientId2, uid, pid, callingPackage, callingFeature, mockCallback2,
- configRequest, true, mExtras, false);
+ configRequest, false, mExtras, false);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockCallback2).onConnectSuccess(clientId2);
+ // Session for offloading should be terminated.
+ inOrder.verify(mockCallback1).onAttachTerminate();
+
+ // (3) connect Aware session for offloading again - should reject
+ mDut.connect(clientId1, uid, pid, callingPackage, callingFeature, mockCallback1,
+ configRequest, false, mExtras, true);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockCallback1).onConnectFail(anyInt());
+
+ // (6) Aware down - session should be terminated.
+ mDut.onAwareDownNotification(reason);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockCallback2).onAttachTerminate();
+
+ validateInternalClientInfoCleanedUp(clientId1);
+ validateInternalClientInfoCleanedUp(clientId2);
+
+ verifyNoMoreInteractions(mockCallback1, mockCallback2, mMockNative);
+ }
+
+ /**
+ * Validates that all events are delivered with correct arguments. Validates
+ * that IdentityChanged not delivered if configuration disables delivery.
+ */
+ @Test
+ public void testAwareWithOffloadingWithoutFwHandlePriority() throws Exception {
+ mResources.setBoolean(R.bool.config_wifiAwareOffloadingFirmwareHandlePriority, false);
+ final int clientId1 = 1005;
+ final int clientId2 = 1007;
+ final int clusterLow = 5;
+ final int clusterHigh = 100;
+ final int masterPref = 111;
+ final int uid = 1000;
+ final int pid = 2000;
+ final String callingPackage = "com.google.somePackage";
+ final String callingFeature = "com.google.someFeature";
+ final int reason = NanStatusCode.INTERNAL_FAILURE;
+
+ ConfigRequest configRequest = new ConfigRequest.Builder().setClusterLow(clusterLow)
+ .setClusterHigh(clusterHigh).setMasterPreference(masterPref)
+ .build();
+
+ IWifiAwareEventCallback mockCallback1 = mock(IWifiAwareEventCallback.class);
+ IWifiAwareEventCallback mockCallback2 = mock(IWifiAwareEventCallback.class);
+ ArgumentCaptor<Short> transactionIdCapture = ArgumentCaptor.forClass(Short.class);
+ InOrder inOrder = inOrder(mockCallback1, mockCallback2, mMockNative);
+
+ mDut.enableUsage();
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).getCapabilities(transactionIdCapture.capture());
+ reset(mMockNativeManager);
+
+ // (1) connect Aware session for offloading
+ mDut.connect(clientId1, uid, pid, callingPackage, callingFeature, mockCallback1,
+ configRequest, false, mExtras, true);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
- eq(configRequest), eq(true), eq(false), eq(true), eq(false), eq(false), eq(false),
+ eq(configRequest), eq(false), eq(true), eq(true), eq(false), eq(false), eq(false),
+ anyInt(), anyInt());
+ short transactionId = transactionIdCapture.getValue();
+ mDut.onConfigSuccessResponse(transactionId);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mockCallback1).onConnectSuccess(clientId1);
+
+ // (2) connect Aware session for App
+ mDut.connect(clientId2, uid, pid, callingPackage, callingFeature, mockCallback2,
+ configRequest, true, mExtras, false);
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).disable(transactionIdCapture.capture());
+ mDut.onDisableResponse(transactionIdCapture.getValue(), NanStatusCode.SUCCESS);
+ mMockLooper.dispatchAll();
+ verify(mMockNativeManager, never()).releaseAware();
+ mMockLooper.dispatchAll();
+ inOrder.verify(mMockNative).enableAndConfigure(transactionIdCapture.capture(),
+ eq(configRequest), eq(true), eq(true), eq(true), eq(false), eq(false), eq(false),
anyInt(), anyInt());
transactionId = transactionIdCapture.getValue();
mDut.onConfigSuccessResponse(transactionId);