diff options
author | 2024-02-09 18:47:48 +0000 | |
---|---|---|
committer | 2024-02-09 18:47:48 +0000 | |
commit | 4a67d5de10dc8233a3e3f65b3682756bb26d0427 (patch) | |
tree | 565648becc63222173bdd22c34049d52828e2e7d | |
parent | 701b65d0a86cf613153f34de1a089f92219e2aea (diff) | |
parent | fbd69323e21a2f3c70a821167cca9c8dc496f46a (diff) |
Merge "Add the framework implementation for QoS R3." into main
4 files changed, 245 insertions, 16 deletions
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java index 9a9f285801..7722e4accb 100644 --- a/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java +++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHalAidlImpl.java @@ -56,12 +56,17 @@ import android.hardware.wifi.supplicant.KeyMgmtMask; import android.hardware.wifi.supplicant.LegacyMode; import android.hardware.wifi.supplicant.MloLinksInfo; import android.hardware.wifi.supplicant.MscsParams.FrameClassifierFields; +import android.hardware.wifi.supplicant.MsduDeliveryInfo; +import android.hardware.wifi.supplicant.MsduDeliveryInfo.DeliveryRatio; import android.hardware.wifi.supplicant.PortRange; +import android.hardware.wifi.supplicant.QosCharacteristics; +import android.hardware.wifi.supplicant.QosCharacteristics.QosCharacteristicsMask; import android.hardware.wifi.supplicant.QosPolicyClassifierParams; import android.hardware.wifi.supplicant.QosPolicyClassifierParamsMask; import android.hardware.wifi.supplicant.QosPolicyData; import android.hardware.wifi.supplicant.QosPolicyRequestType; import android.hardware.wifi.supplicant.QosPolicyScsData; +import android.hardware.wifi.supplicant.QosPolicyScsData.LinkDirection; import android.hardware.wifi.supplicant.QosPolicyScsRequestStatus; import android.hardware.wifi.supplicant.QosPolicyScsRequestStatusCode; import android.hardware.wifi.supplicant.QosPolicyStatus; @@ -2895,11 +2900,107 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal { hasSrcIp, srcIp, hasDstIp, dstIp, srcPort, dstPortRange, protocol)); } + @VisibleForTesting + protected static byte frameworkToHalDeliveryRatio( + @android.net.wifi.QosCharacteristics.DeliveryRatio int frameworkRatio) { + switch (frameworkRatio) { + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_95: + return DeliveryRatio.RATIO_95; + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_96: + return DeliveryRatio.RATIO_96; + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_97: + return DeliveryRatio.RATIO_97; + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_98: + return DeliveryRatio.RATIO_98; + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99: + return DeliveryRatio.RATIO_99; + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_9: + return DeliveryRatio.RATIO_99_9; + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_99: + return DeliveryRatio.RATIO_99_99; + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_999: + return DeliveryRatio.RATIO_99_999; + case android.net.wifi.QosCharacteristics.DELIVERY_RATIO_99_9999: + return DeliveryRatio.RATIO_99_9999; + default: + Log.e(TAG, "Invalid delivery ratio received: " + frameworkRatio); + return DeliveryRatio.RATIO_95; + } + } + + @VisibleForTesting + protected static byte frameworkToHalPolicyDirection( + @QosPolicyParams.Direction int frameworkDirection) { + switch (frameworkDirection) { + case QosPolicyParams.DIRECTION_UPLINK: + return LinkDirection.UPLINK; + case QosPolicyParams.DIRECTION_DOWNLINK: + return LinkDirection.DOWNLINK; + default: + Log.e(TAG, "Invalid direction received: " + frameworkDirection); + return LinkDirection.DOWNLINK; + } + } + + /** + * Convert from a framework QosCharacteristics to its HAL equivalent. + */ + @VisibleForTesting + protected static QosCharacteristics frameworkToHalQosCharacteristics( + android.net.wifi.QosCharacteristics frameworkChars) { + QosCharacteristics halChars = new QosCharacteristics(); + halChars.minServiceIntervalUs = frameworkChars.getMinServiceIntervalMicros(); + halChars.maxServiceIntervalUs = frameworkChars.getMaxServiceIntervalMicros(); + halChars.minDataRateKbps = frameworkChars.getMinDataRateKbps(); + halChars.delayBoundUs = frameworkChars.getDelayBoundMicros(); + + int optionalFieldMask = 0; + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.MAX_MSDU_SIZE)) { + optionalFieldMask |= QosCharacteristicsMask.MAX_MSDU_SIZE; + halChars.maxMsduSizeOctets = (char) frameworkChars.getMaxMsduSizeOctets(); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.SERVICE_START_TIME)) { + optionalFieldMask |= QosCharacteristicsMask.SERVICE_START_TIME; + optionalFieldMask |= QosCharacteristicsMask.SERVICE_START_TIME_LINK_ID; + halChars.serviceStartTimeUs = frameworkChars.getServiceStartTimeMicros(); + halChars.serviceStartTimeLinkId = (byte) frameworkChars.getServiceStartTimeLinkId(); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.MEAN_DATA_RATE)) { + optionalFieldMask |= QosCharacteristicsMask.MEAN_DATA_RATE; + halChars.meanDataRateKbps = frameworkChars.getMeanDataRateKbps(); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.BURST_SIZE)) { + optionalFieldMask |= QosCharacteristicsMask.BURST_SIZE; + halChars.burstSizeOctets = frameworkChars.getBurstSizeOctets(); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.MSDU_LIFETIME)) { + optionalFieldMask |= QosCharacteristicsMask.MSDU_LIFETIME; + halChars.msduLifetimeMs = (char) frameworkChars.getMsduLifetimeMillis(); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.MSDU_DELIVERY_INFO)) { + optionalFieldMask |= QosCharacteristicsMask.MSDU_DELIVERY_INFO; + MsduDeliveryInfo deliveryInfo = new MsduDeliveryInfo(); + deliveryInfo.deliveryRatio = + frameworkToHalDeliveryRatio(frameworkChars.getDeliveryRatio()); + deliveryInfo.countExponent = (byte) frameworkChars.getCountExponent(); + halChars.msduDeliveryInfo = deliveryInfo; + } + + halChars.optionalFieldMask = optionalFieldMask; + return halChars; + } + /** * Convert from a framework {@link QosPolicyParams} to a HAL QosPolicyScsData object. */ @VisibleForTesting - protected static QosPolicyScsData frameworkToHalQosPolicyScsData(QosPolicyParams params) { + protected QosPolicyScsData frameworkToHalQosPolicyScsData(QosPolicyParams params) { QosPolicyScsData halData = new QosPolicyScsData(); halData.policyId = (byte) params.getTranslatedPolicyId(); halData.userPriority = (byte) params.getUserPriority(); @@ -2943,13 +3044,20 @@ public class SupplicantStaIfaceHalAidlImpl implements ISupplicantStaIfaceHal { paramsMask |= QosPolicyClassifierParamsMask.FLOW_LABEL; classifierParams.flowLabelIpv6 = params.getFlowLabel(); } + if (SdkLevel.isAtLeastV() && isServiceVersionAtLeast(3)) { + halData.direction = frameworkToHalPolicyDirection(params.getDirection()); + if (params.getQosCharacteristics() != null) { + halData.QosCharacteristics = + frameworkToHalQosCharacteristics(params.getQosCharacteristics()); + } + } classifierParams.classifierParamMask = paramsMask; halData.classifierParams = classifierParams; return halData; } - private static QosPolicyScsData[] frameworkToHalQosPolicyScsDataList( + private QosPolicyScsData[] frameworkToHalQosPolicyScsDataList( List<QosPolicyParams> frameworkPolicies) { QosPolicyScsData[] halDataList = new QosPolicyScsData[frameworkPolicies.size()]; int index = 0; diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index b8271006ba..70da8f3be6 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -7629,8 +7629,8 @@ public class WifiServiceImpl extends BaseWifiService { return policyIdSet.size() == policyIds.length; } - private boolean policiesHaveDirection(List<QosPolicyParams> policyList, - @QosPolicyParams.Direction int direction) { + private boolean policiesHaveSameDirection(List<QosPolicyParams> policyList) { + int direction = policyList.get(0).getDirection(); for (QosPolicyParams policy : policyList) { if (policy.getDirection() != direction) { return false; @@ -7681,14 +7681,20 @@ public class WifiServiceImpl extends BaseWifiService { return; } - // Only downlink policies are currently supported. if (policyParamsList.size() == 0 || policyParamsList.size() > WifiManager.getMaxNumberOfPoliciesPerQosRequest() || !policyIdsAreUnique(policyParamsList) - || !policiesHaveDirection(policyParamsList, QosPolicyParams.DIRECTION_DOWNLINK)) { + || !policiesHaveSameDirection(policyParamsList)) { throw new IllegalArgumentException("policyParamsList is invalid"); } + if (!SdkLevel.isAtLeastV() + && policyParamsList.get(0).getDirection() == QosPolicyParams.DIRECTION_UPLINK) { + Log.e(TAG, "Uplink QoS policies are only supported on SDK >= V"); + rejectAllQosPolicies(policyParamsList, listener); + return; + } + mWifiThreadRunner.post(() -> { mApplicationQosPolicyRequestHandler.queueAddRequest( policyParamsList, listener, binder, uid); diff --git a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java index a376360873..0ebc8f43a0 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalAidlImplTest.java @@ -35,6 +35,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; @@ -78,10 +79,12 @@ import android.hardware.wifi.supplicant.LegacyMode; import android.hardware.wifi.supplicant.MloLink; import android.hardware.wifi.supplicant.MloLinksInfo; import android.hardware.wifi.supplicant.MscsParams.FrameClassifierFields; +import android.hardware.wifi.supplicant.MsduDeliveryInfo; import android.hardware.wifi.supplicant.OceRssiBasedAssocRejectAttr; import android.hardware.wifi.supplicant.OsuMethod; import android.hardware.wifi.supplicant.PmkSaCacheData; import android.hardware.wifi.supplicant.PortRange; +import android.hardware.wifi.supplicant.QosCharacteristics.QosCharacteristicsMask; import android.hardware.wifi.supplicant.QosPolicyClassifierParams; import android.hardware.wifi.supplicant.QosPolicyClassifierParamsMask; import android.hardware.wifi.supplicant.QosPolicyData; @@ -103,6 +106,7 @@ import android.net.DscpPolicy; import android.net.MacAddress; import android.net.NetworkAgent; import android.net.wifi.MscsParams; +import android.net.wifi.QosCharacteristics; import android.net.wifi.QosPolicyParams; import android.net.wifi.ScanResult; import android.net.wifi.SecurityParams; @@ -2464,8 +2468,35 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest { .setDestinationPort(10) .build(); frameworkPolicy.setTranslatedPolicyId(translatedPolicyId); - QosPolicyScsData halPolicy = SupplicantStaIfaceHalAidlImpl - .frameworkToHalQosPolicyScsData(frameworkPolicy); + QosPolicyScsData halPolicy = mDut.frameworkToHalQosPolicyScsData(frameworkPolicy); + compareQosPolicyParamsToHal(frameworkPolicy, halPolicy); + } + + /** + * Tests the conversion method + * {@link SupplicantStaIfaceHalAidlImpl#frameworkToHalQosPolicyScsData(QosPolicyParams)} + * when the instance contains QosCharacteristics. + */ + @Test + public void testFrameworkToHalQosPolicyScsDataWithCharacteristics() throws Exception { + assumeTrue(SdkLevel.isAtLeastV()); + when(mISupplicantMock.getInterfaceVersion()).thenReturn(3); + assertTrue(mDut.startDaemon()); // retrieves and caches the interface version + + QosCharacteristics frameworkChars = new QosCharacteristics.Builder( + 2000, 5000, 500, 2) + .setMaxMsduSizeOctets(4) + .setServiceStartTimeInfo(250, 0x5) + .setMeanDataRateKbps(1500) + .setMsduLifetimeMillis(400) + .setMsduDeliveryInfo(QosCharacteristics.DELIVERY_RATIO_99, 5) + .build(); + QosPolicyParams frameworkPolicy = new QosPolicyParams.Builder( + 5 /* policyId */, QosPolicyParams.DIRECTION_UPLINK) + .setQosCharacteristics(frameworkChars) + .build(); + frameworkPolicy.setTranslatedPolicyId(15); + QosPolicyScsData halPolicy = mDut.frameworkToHalQosPolicyScsData(frameworkPolicy); compareQosPolicyParamsToHal(frameworkPolicy, halPolicy); } @@ -2576,6 +2607,55 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest { return qosPolicyData; } + private static void compareFrameworkQosCharacteristicsToHal( + android.net.wifi.QosCharacteristics frameworkChars, + android.hardware.wifi.supplicant.QosCharacteristics halChars) { + assertEquals(frameworkChars.getMinServiceIntervalMicros(), halChars.minServiceIntervalUs); + assertEquals(frameworkChars.getMaxServiceIntervalMicros(), halChars.maxServiceIntervalUs); + assertEquals(frameworkChars.getMinDataRateKbps(), halChars.minDataRateKbps); + assertEquals(frameworkChars.getDelayBoundMicros(), halChars.delayBoundUs); + + int paramsMask = halChars.optionalFieldMask; + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.MAX_MSDU_SIZE)) { + assertNotEquals(0, paramsMask & QosCharacteristicsMask.MAX_MSDU_SIZE); + assertEquals((char) frameworkChars.getMaxMsduSizeOctets(), halChars.maxMsduSizeOctets); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.SERVICE_START_TIME)) { + assertNotEquals(0, paramsMask & QosCharacteristicsMask.SERVICE_START_TIME); + assertNotEquals(0, paramsMask & QosCharacteristicsMask.SERVICE_START_TIME_LINK_ID); + assertEquals(frameworkChars.getServiceStartTimeMicros(), halChars.serviceStartTimeUs); + assertEquals((byte) frameworkChars.getServiceStartTimeLinkId(), + halChars.serviceStartTimeLinkId); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.MEAN_DATA_RATE)) { + assertNotEquals(0, paramsMask & QosCharacteristicsMask.MEAN_DATA_RATE); + assertEquals(frameworkChars.getMeanDataRateKbps(), halChars.meanDataRateKbps); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.BURST_SIZE)) { + assertNotEquals(0, paramsMask & QosCharacteristicsMask.BURST_SIZE); + assertEquals(frameworkChars.getBurstSizeOctets(), halChars.burstSizeOctets); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.MSDU_LIFETIME)) { + assertNotEquals(0, paramsMask & QosCharacteristicsMask.MSDU_LIFETIME); + assertEquals((char) frameworkChars.getMsduLifetimeMillis(), halChars.msduLifetimeMs); + } + if (frameworkChars.containsOptionalField( + android.net.wifi.QosCharacteristics.MSDU_DELIVERY_INFO)) { + assertNotEquals(0, paramsMask & QosCharacteristicsMask.MSDU_DELIVERY_INFO); + MsduDeliveryInfo halDeliveryInfo = halChars.msduDeliveryInfo; + int convertedFrameworkRatio = + SupplicantStaIfaceHalAidlImpl.frameworkToHalDeliveryRatio( + frameworkChars.getDeliveryRatio()); + assertEquals(convertedFrameworkRatio, halDeliveryInfo.deliveryRatio); + assertEquals((byte) frameworkChars.getCountExponent(), halDeliveryInfo.countExponent); + } + } + private void compareQosPolicyParamsToHal(QosPolicyParams frameworkPolicy, QosPolicyScsData halPolicy) { assertEquals((byte) frameworkPolicy.getTranslatedPolicyId(), halPolicy.policyId); @@ -2612,6 +2692,17 @@ public class SupplicantStaIfaceHalAidlImplTest extends WifiBaseTest { assertNotEquals(0, paramsMask & QosPolicyClassifierParamsMask.DSCP); assertEquals((byte) frameworkPolicy.getDscp(), classifierParams.dscp); } + + if (mDut.isServiceVersionAtLeast(3)) { + int convertedFrameworkDirection = + SupplicantStaIfaceHalAidlImpl.frameworkToHalPolicyDirection( + frameworkPolicy.getDirection()); + assertEquals(convertedFrameworkDirection, halPolicy.direction); + if (frameworkPolicy.getQosCharacteristics() != null) { + compareFrameworkQosCharacteristicsToHal( + frameworkPolicy.getQosCharacteristics(), halPolicy.QosCharacteristics); + } + } } /** diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index 4f3e97d9ac..683dcc633d 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -11465,7 +11465,7 @@ public class WifiServiceImplTest extends WifiBaseTest { .thenReturn(true); } - private List<QosPolicyParams> createQosPolicyParamsList(int size, boolean uniqueIds) { + private List<QosPolicyParams> createDownlinkQosPolicyParamsList(int size, boolean uniqueIds) { List<QosPolicyParams> policyParamsList = new ArrayList<>(); for (int i = 0; i < size; i++) { int policyId = uniqueIds ? i + 2 : 5; @@ -11478,6 +11478,22 @@ public class WifiServiceImplTest extends WifiBaseTest { return policyParamsList; } + private static List<QosPolicyParams> createUplinkQosPolicyParamsList(int size) { + List<QosPolicyParams> policyParamsList = new ArrayList<>(); + QosCharacteristics mockQosCharacteristics = mock(QosCharacteristics.class); + when(mockQosCharacteristics.validate()).thenReturn(true); + + for (int i = 0; i < size; i++) { + int policyId = i + 2; + policyParamsList.add(new QosPolicyParams.Builder( + policyId, QosPolicyParams.DIRECTION_UPLINK) + .setQosCharacteristics(mockQosCharacteristics) + .build()); + } + + return policyParamsList; + } + /** * Verify that addQosPolicies works correctly. */ @@ -11486,13 +11502,21 @@ public class WifiServiceImplTest extends WifiBaseTest { assumeTrue(SdkLevel.isAtLeastU()); enableQosPolicyFeature(); - List<QosPolicyParams> paramsList = createQosPolicyParamsList(5, true); + List<QosPolicyParams> paramsList = createDownlinkQosPolicyParamsList(5, true); IBinder binder = mock(IBinder.class); IListListener listener = mock(IListListener.class); mWifiServiceImpl.addQosPolicies(paramsList, binder, TEST_PACKAGE_NAME, listener); + int expectedNumCalls = 1; + + if (SdkLevel.isAtLeastV()) { + // Uplink policies are supported on SDK >= V + paramsList = createUplinkQosPolicyParamsList(5); + mWifiServiceImpl.addQosPolicies(paramsList, binder, TEST_PACKAGE_NAME, listener); + expectedNumCalls += 1; + } mLooper.dispatchAll(); - verify(mApplicationQosPolicyRequestHandler).queueAddRequest( + verify(mApplicationQosPolicyRequestHandler, times(expectedNumCalls)).queueAddRequest( anyList(), any(), any(), anyInt()); } @@ -11503,7 +11527,7 @@ public class WifiServiceImplTest extends WifiBaseTest { public void testAddQosPoliciesError() throws RemoteException { assumeTrue(SdkLevel.isAtLeastU()); enableQosPolicyFeature(); - List<QosPolicyParams> paramsList = createQosPolicyParamsList(5, true); + List<QosPolicyParams> paramsList = createDownlinkQosPolicyParamsList(5, true); IBinder binder = mock(IBinder.class); IListListener listener = mock(IListListener.class); @@ -11527,10 +11551,10 @@ public class WifiServiceImplTest extends WifiBaseTest { mWifiServiceImpl.addQosPolicies(paramsList, binder, TEST_PACKAGE_NAME, null)); // Invalid QoS policy params list - List<QosPolicyParams> emptyList = createQosPolicyParamsList(0, true); - List<QosPolicyParams> largeList = createQosPolicyParamsList( + List<QosPolicyParams> emptyList = createDownlinkQosPolicyParamsList(0, true); + List<QosPolicyParams> largeList = createDownlinkQosPolicyParamsList( WifiManager.getMaxNumberOfPoliciesPerQosRequest() + 1, true); - List<QosPolicyParams> duplicatePolicyList = createQosPolicyParamsList(5, false); + List<QosPolicyParams> duplicatePolicyList = createDownlinkQosPolicyParamsList(5, false); assertThrows(IllegalArgumentException.class, () -> mWifiServiceImpl.addQosPolicies(emptyList, binder, TEST_PACKAGE_NAME, listener)); @@ -11542,7 +11566,7 @@ public class WifiServiceImplTest extends WifiBaseTest { duplicatePolicyList, binder, TEST_PACKAGE_NAME, listener)); if (SdkLevel.isAtLeastV()) { - List<QosPolicyParams> mixedDirectionList = createQosPolicyParamsList(1, true); + List<QosPolicyParams> mixedDirectionList = createDownlinkQosPolicyParamsList(1, true); QosCharacteristics mockQosCharacteristics = mock(QosCharacteristics.class); when(mockQosCharacteristics.validate()).thenReturn(true); mixedDirectionList.add( |