diff options
4 files changed, 211 insertions, 1 deletions
diff --git a/service/ServiceWifiResources/res/values/config.xml b/service/ServiceWifiResources/res/values/config.xml index c6068b0ab9..da98aa9694 100644 --- a/service/ServiceWifiResources/res/values/config.xml +++ b/service/ServiceWifiResources/res/values/config.xml @@ -1114,6 +1114,14 @@ <item>com.company2.example.test.name2</item> --> </string-array> + <!-- list of package names that the framework will allow to use SoftAp/Aware concurrency. If + this list is empty, then all packages are allowed --> + <string-array translatable="false" name="config_wifiSoftApAwareConcurrencyAllowlist"> + <!-- Below is a sample configuration for this list: + <item>com.company1.example.test.name1</item> + <item>com.company2.example.test.name2</item> + --> + </string-array> <!-- boolean indicating whether the Easy Connect (DPP) AKM is supported --> <bool translatable="false" name ="config_wifiDppAkmSupported">false</bool> <!-- Indicates the number of octets to mask for each BSSID in the SecurityLog output. diff --git a/service/ServiceWifiResources/res/values/overlayable.xml b/service/ServiceWifiResources/res/values/overlayable.xml index 7409ad1414..1c0c6a348d 100644 --- a/service/ServiceWifiResources/res/values/overlayable.xml +++ b/service/ServiceWifiResources/res/values/overlayable.xml @@ -308,6 +308,7 @@ <item type="bool" name="config_wifiUserApprovalNotRequireForDisconnectedP2p" /> <item type="integer" name="config_disconnectedP2pIfaceLowPriorityTimeoutMs" /> <item type="array" name="config_wifiP2pAwareConcurrencyAllowlist" /> + <item type="array" name="config_wifiSoftApAwareConcurrencyAllowlist" /> <item type="bool" name="config_wifiNetworkCentricQosPolicyFeatureEnabled" /> <item type="bool" name="config_wifiApplicationCentricQosPolicyFeatureEnabled" /> <item type="string" name="config_wifiDriverWorldModeCountryCode" /> diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java index 57d12f58b4..a251af8578 100644 --- a/service/java/com/android/server/wifi/HalDeviceManager.java +++ b/service/java/com/android/server/wifi/HalDeviceManager.java @@ -1900,6 +1900,51 @@ public class HalDeviceManager { return false; } + private boolean isRequestorAllowedToUseApNanConcurrency(WorkSource requestorWs) { + String[] allowlistArray = mContext.getResources().getStringArray( + R.array.config_wifiSoftApAwareConcurrencyAllowlist); + if (allowlistArray == null || allowlistArray.length == 0) { + // No allowlist defined, so allow. + return true; + } + List<String> allowlist = Arrays.asList(allowlistArray); + for (int i = 0; i < requestorWs.size(); i++) { + if (allowlist.contains(requestorWs.getPackageName(i))) { + return true; + } + } + return false; + } + + /** + * Remove AP from the combo if NAN requested (or NAN if AP is requested) if the current + * requestor is not allowed to use AP/NAN concurrency. + */ + @NonNull + private int[] removeApNanConcurrencyIfNotAllowed( + @NonNull int[] chipCreateTypeCombo, + @HdmIfaceTypeForCreation int requestedCreateType, + WorkSource requestorWs) { + if (isRequestorAllowedToUseApNanConcurrency(requestorWs)) { + return chipCreateTypeCombo; + } + + int[] newCombo = chipCreateTypeCombo.clone(); + switch (requestedCreateType) { + case HDM_CREATE_IFACE_AP: + case HDM_CREATE_IFACE_AP_BRIDGE: + newCombo[HDM_CREATE_IFACE_NAN] = 0; + break; + case HDM_CREATE_IFACE_NAN: + newCombo[HDM_CREATE_IFACE_AP] = 0; + newCombo[HDM_CREATE_IFACE_AP_BRIDGE] = 0; + break; + default: + break; + } + return newCombo; + } + /** * Checks whether the input chip-create-type-combo can support the requested create type: * if not then returns null, if yes then returns information containing the list of interfaces @@ -1947,6 +1992,10 @@ public class HalDeviceManager { } } + // Remove AP/NAN concurrency if the requestor isn't on the allowlist. + chipCreateTypeCombo = removeApNanConcurrencyIfNotAllowed( + chipCreateTypeCombo, requestedCreateType, requestorWs); + IfaceCreationData ifaceCreationData = new IfaceCreationData(); ifaceCreationData.chipInfo = chipInfo; ifaceCreationData.chipModeId = chipModeId; diff --git a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java index a53be5d328..40fd2597c6 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java @@ -4222,6 +4222,157 @@ public class HalDeviceManagerTest extends WifiBaseTest { collector.checkThat("interface was null", p2pIface, IsNull.notNullValue()); } + /** + * Validate an AP request from requestors not on the AP/NAN concurrency allowlist. + */ + @Test + public void testApNanConcurrencyNotAllowedTestChipV11() + throws Exception { + when(mResources.getStringArray(R.array.config_wifiSoftApAwareConcurrencyAllowlist)) + .thenReturn(new String[]{"Some other package"}); + + TestChipV11 chipMock = new TestChipV11(); + chipMock.initialize(); + mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock); + executeAndValidateStartupSequence(); + + InterfaceDestroyedListener idl = mock(InterfaceDestroyedListener.class); + + // Create a NAN + WifiInterface nanIface = validateInterfaceSequence(chipMock, + false, // chipModeValid + -1000, // chipModeId (only used if chipModeValid is true) + HDM_CREATE_IFACE_NAN, + "wlan0", + TestChipV11.CHIP_MODE_ID, + null, // tearDownList + idl, // destroyedListener + TEST_WORKSOURCE_0 // requestorWs + ); + collector.checkThat("interface was null", nanIface, IsNull.notNullValue()); + + // AP request from Worksource 1 (lower priority) should be blocked. + when(mWorkSourceHelper1.getRequestorWsPriority()) + .thenReturn(WorkSourceHelper.PRIORITY_FG_APP); + List<Pair<Integer, WorkSource>> apDetails = mDut.reportImpactToCreateIface( + HDM_CREATE_IFACE_AP, true, TEST_WORKSOURCE_1); + if (SdkLevel.isAtLeastS()) { + assertNull("Should not be able to create this AP", apDetails); + } else { + // Pre-S lets AP/NAN destroy each other. + assertEquals(apDetails.get(0).second, TEST_WORKSOURCE_0); + } + + // Bridged AP request should also be blocked + apDetails = mDut.reportImpactToCreateIface( + HDM_CREATE_IFACE_AP_BRIDGE, true, TEST_WORKSOURCE_1); + if (SdkLevel.isAtLeastS()) { + assertNull("Should not be able to create this Bridged AP", apDetails); + } else { + // Pre-S lets AP/NAN destroy each other. + assertEquals(apDetails.get(0).second, TEST_WORKSOURCE_0); + } + + // AP request from Worksource 2 (same privileged priority) should tear down NAN. + WifiInterface ApIface = validateInterfaceSequence(chipMock, + true, // chipModeValid + TestChipV11.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true) + HDM_CREATE_IFACE_AP, + "wlan1", + TestChipV11.CHIP_MODE_ID, + new WifiInterface[]{nanIface}, // tearDownList + idl, // destroyedListener + TEST_WORKSOURCE_2 // requestorWs + ); + collector.checkThat("interface was null", ApIface, IsNull.notNullValue()); + } + + /** + * Validate an AP request from a requestor on the AP/NAN concurrency allowlist. + */ + @Test + public void testSingleApNanConcurrencyAllowedTestChipV11() + throws Exception { + when(mResources.getStringArray(R.array.config_wifiSoftApAwareConcurrencyAllowlist)) + .thenReturn(new String[]{TEST_WORKSOURCE_1.getPackageName(0)}); + + TestChipV11 chipMock = new TestChipV11(); + chipMock.initialize(); + mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock); + executeAndValidateStartupSequence(); + + InterfaceDestroyedListener idl = mock(InterfaceDestroyedListener.class); + + // Create a NAN + WifiInterface nanIface = validateInterfaceSequence(chipMock, + false, // chipModeValid + -1000, // chipModeId (only used if chipModeValid is true) + HDM_CREATE_IFACE_NAN, + "wlan0", + TestChipV11.CHIP_MODE_ID, + null, // tearDownList + idl, // destroyedListener + TEST_WORKSOURCE_0 // requestorWs + ); + collector.checkThat("interface was null", nanIface, IsNull.notNullValue()); + + // AP request from Worksource 1 (on allowlist) should be allowed. + WifiInterface apIface = validateInterfaceSequence(chipMock, + true, // chipModeValid + TestChipV11.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true) + HDM_CREATE_IFACE_AP, + "wlan1", + TestChipV11.CHIP_MODE_ID, + null, // tearDownList + idl, // destroyedListener + TEST_WORKSOURCE_1 // requestorWs + ); + collector.checkThat("interface was null", apIface, IsNull.notNullValue()); + } + + /** + * Validate a Bridged AP request from a requestor on the AP/NAN concurrency allowlist. + */ + @Test + public void testBridgedApNanConcurrencyAllowedTestChipV11() + throws Exception { + when(mResources.getStringArray(R.array.config_wifiSoftApAwareConcurrencyAllowlist)) + .thenReturn(new String[]{TEST_WORKSOURCE_1.getPackageName(0)}); + + TestChipV11 chipMock = new TestChipV11(); + chipMock.initialize(); + mInOrder = inOrder(mWifiMock, chipMock.chip, mManagerStatusListenerMock); + executeAndValidateStartupSequence(); + + InterfaceDestroyedListener idl = mock(InterfaceDestroyedListener.class); + + // Create a NAN + WifiInterface nanIface = validateInterfaceSequence(chipMock, + false, // chipModeValid + -1000, // chipModeId (only used if chipModeValid is true) + HDM_CREATE_IFACE_NAN, + "wlan0", + TestChipV11.CHIP_MODE_ID, + null, // tearDownList + idl, // destroyedListener + TEST_WORKSOURCE_0 // requestorWs + ); + collector.checkThat("interface was null", nanIface, IsNull.notNullValue()); + + // Bridged AP request from Worksource 1 (on allowlist) should be allowed. + WifiInterface apIface = validateInterfaceSequence(chipMock, + true, // chipModeValid + TestChipV11.CHIP_MODE_ID, // chipModeId (only used if chipModeValid is true) + HDM_CREATE_IFACE_AP_BRIDGE, + "wlan1", + TestChipV11.CHIP_MODE_ID, + null, // tearDownList + idl, // destroyedListener + TEST_WORKSOURCE_1 // requestorWs + ); + collector.checkThat("interface was null", apIface, IsNull.notNullValue()); + } + /////////////////////////////////////////////////////////////////////////////////////// // utilities /////////////////////////////////////////////////////////////////////////////////////// @@ -5533,7 +5684,7 @@ public class HalDeviceManagerTest extends WifiBaseTest { // Test chip configuration V11 for P2P/NAN concurrency // mode: - // (STA + AP + NAN + P2P) + // (STA + AP + AP_BRIDGE + NAN + P2P) private class TestChipV11 extends ChipMockBase { static final int CHIP_MODE_ID = 90; @@ -5555,6 +5706,7 @@ public class HalDeviceManagerTest extends WifiBaseTest { WifiChip.ChipConcurrencyCombination combo1 = createConcurrencyCombo( createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_STA), createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP), + createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED), createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_P2P), createConcurrencyComboLimit(1, WifiChip.IFACE_CONCURRENCY_TYPE_NAN)); availableModes.add(createChipMode(CHIP_MODE_ID, combo1)); |