diff options
author | 2022-03-14 11:57:26 -0700 | |
---|---|---|
committer | 2022-03-30 11:57:48 -0700 | |
commit | 32e6836bd24d19a85da7f8c2e4e184fd9b6ec407 (patch) | |
tree | 3e6355aab89ec436c662e011772135249dddb7d4 | |
parent | c947d2d3b8efda5075b5f28a95d283c8d88b7aa3 (diff) |
Use stored static chip info when HAL is not running
HalDeviceManager uses chip info that is not expected to change each time
the chip comes up -- thus we should store this info in the config store
and refer to the stored info when the chip is not up, such as when
getting the device concurrency capabilities.
Bug: 223875626
Test: atest HalDeviceManagerTest WifiVendorHalTest
Change-Id: Id34eb54a546f3b29bbe71346b49dc055ef3dd242
6 files changed, 524 insertions, 135 deletions
diff --git a/service/java/com/android/server/wifi/HalDeviceManager.java b/service/java/com/android/server/wifi/HalDeviceManager.java index abeeffbf90..dcb845a538 100644 --- a/service/java/com/android/server/wifi/HalDeviceManager.java +++ b/service/java/com/android/server/wifi/HalDeviceManager.java @@ -16,6 +16,10 @@ package com.android.server.wifi; +import static com.android.server.wifi.HalDeviceManagerUtil.jsonToStaticChipInfo; +import static com.android.server.wifi.HalDeviceManagerUtil.staticChipInfoToJson; +import static com.android.server.wifi.WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -48,6 +52,7 @@ import android.os.Handler; import android.os.IHwBinder.DeathRecipient; import android.os.RemoteException; import android.os.WorkSource; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import android.util.Pair; @@ -57,10 +62,14 @@ import android.util.SparseIntArray; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.build.SdkLevel; +import com.android.server.wifi.HalDeviceManagerUtil.StaticChipInfo; import com.android.server.wifi.util.GeneralUtil.Mutable; import com.android.server.wifi.util.WorkSourceHelper; import com.android.wifi.resources.R; +import org.json.JSONArray; +import org.json.JSONException; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; @@ -173,7 +182,10 @@ public class HalDeviceManager { mServiceManagerDeathRecipient = new ServiceManagerDeathRecipient(); } - /* package */ void enableVerboseLogging(boolean verboseEnabled) { + /** + * Enables verbose logging. + */ + public void enableVerboseLogging(boolean verboseEnabled) { mDbg = verboseEnabled; if (VDBG) { @@ -672,46 +684,47 @@ public class HalDeviceManager { * * @param createTypeCombo SparseArray keyed in by @HdmIfaceTypeForCreation to number of ifaces * needed. - * @param requiredChipCapabilities The bitmask of Capabilities which are required. - * See IWifiChip.hal for documentation. * @return true if the device supports the provided combo, false otherwise. */ - public boolean canSupportCreateTypeCombo(SparseArray<Integer> createTypeCombo, - long requiredChipCapabilities) { + public boolean canDeviceSupportCreateTypeCombo(SparseArray<Integer> createTypeCombo) { if (VDBG) { - Log.d(TAG, "canSupportCreateTypeCombo: createTypeCombo=" + createTypeCombo - + ", requiredChipCapabilities=" + requiredChipCapabilities); + Log.d(TAG, "canDeviceSupportCreateTypeCombo: createTypeCombo=" + createTypeCombo); } synchronized (mLock) { - if (mWifi == null) return false; - int[] createTypeComboArray = - new int[CREATE_TYPES_BY_PRIORITY.length]; + int[] requestedCombo = new int[CREATE_TYPES_BY_PRIORITY.length]; for (int createType : CREATE_TYPES_BY_PRIORITY) { - createTypeComboArray[createType] = createTypeCombo.get(createType, 0); + requestedCombo[createType] = createTypeCombo.get(createType, 0); } - WifiChipInfo[] chipInfos = getAllChipInfoCached(); - if (chipInfos == null) return false; - return isItPossibleToCreateCreateTypeCombo( - chipInfos, requiredChipCapabilities, createTypeComboArray); + for (StaticChipInfo staticChipInfo : getStaticChipInfos()) { + SparseArray<List<int[][]>> expandedCreateTypeCombosPerChipModeId = + getExpandedCreateTypeCombosPerChipModeId( + staticChipInfo.getAvailableModes()); + for (int i = 0; i < expandedCreateTypeCombosPerChipModeId.size(); i++) { + int chipModeId = expandedCreateTypeCombosPerChipModeId.keyAt(i); + for (int[][] expandedCreateTypeCombo + : expandedCreateTypeCombosPerChipModeId.get(chipModeId)) { + for (int[] supportedCombo : expandedCreateTypeCombo) { + if (canCreateTypeComboSupportRequestedCreateTypeCombo( + supportedCombo, requestedCombo)) { + if (VDBG) { + Log.d(TAG, "Device can support createTypeCombo=" + + createTypeCombo); + } + return true; + } + } + } + } + } + if (VDBG) { + Log.d(TAG, "Device cannot support createTypeCombo=" + createTypeCombo); + } + return false; } } /** - * Returns whether the provided @HdmIfaceTypeForCreation combo can be supported by the device. - * Note: This only returns an answer based on the create type combination exposed by the HAL. - * The actual iface creation/deletion rules depend on the iface priorities set in - * {@link #allowedToDeleteIfaceTypeForRequestedType(int, WorkSource, int, WifiIfaceInfo[][])} - * - * @param createTypeCombo SparseArray keyed in by @HdmIfaceTypeForCreation to number of ifaces - * needed. - * @return true if the device supports the provided combo, false otherwise. - */ - public boolean canSupportCreateTypeCombo(SparseArray<Integer> createTypeCombo) { - return canSupportCreateTypeCombo(createTypeCombo, CHIP_CAPABILITY_ANY); - } - - /** * Returns whether the provided Iface can be requested by specifier requestor. * * @param createIfaceType Type of iface requested. @@ -925,10 +938,10 @@ public class HalDeviceManager { private class WifiChipInfo { public IWifiChip chip; - public int chipId; + public int chipId = -1; public ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> availableModes; - public boolean currentModeIdValid; - public int currentModeId; + public boolean currentModeIdValid = false; + public int currentModeId = -1; public WifiIfaceInfo[][] ifaces = new WifiIfaceInfo[IFACE_TYPES_BY_PRIORITY.length][]; public long chipCapabilities; public WifiRadioCombinationMatrix radioCombinationMatrix = null; @@ -1612,6 +1625,61 @@ public class HalDeviceManager { return newChipModes; } + @Nullable + private StaticChipInfo[] mCachedStaticChipInfos = null; + + @NonNull + private StaticChipInfo[] getStaticChipInfos() { + if (mCachedStaticChipInfos == null) { + mCachedStaticChipInfos = loadStaticChipInfoFromStore(); + } + return mCachedStaticChipInfos; + } + + private void saveStaticChipInfoToStore(StaticChipInfo[] staticChipInfos) { + try { + JSONArray staticChipInfosJson = new JSONArray(); + for (StaticChipInfo staticChipInfo : staticChipInfos) { + staticChipInfosJson.put(staticChipInfoToJson(staticChipInfo)); + } + mWifiInjector.getSettingsConfigStore().put(WIFI_STATIC_CHIP_INFO, + staticChipInfosJson.toString()); + } catch (JSONException e) { + Log.e(TAG, "JSONException while converting StaticChipInfo to JSON: " + e); + } + } + + private StaticChipInfo[] loadStaticChipInfoFromStore() { + StaticChipInfo[] staticChipInfos = new StaticChipInfo[0]; + String configString = mWifiInjector.getSettingsConfigStore().get(WIFI_STATIC_CHIP_INFO); + if (TextUtils.isEmpty(configString)) { + return staticChipInfos; + } + try { + JSONArray staticChipInfosJson = new JSONArray( + mWifiInjector.getSettingsConfigStore().get(WIFI_STATIC_CHIP_INFO)); + staticChipInfos = new StaticChipInfo[staticChipInfosJson.length()]; + for (int i = 0; i < staticChipInfosJson.length(); i++) { + staticChipInfos[i] = jsonToStaticChipInfo(staticChipInfosJson.getJSONObject(i)); + } + } catch (JSONException e) { + Log.e(TAG, "Failed to load static chip info from store: " + e); + } + return staticChipInfos; + } + + private StaticChipInfo[] convertWifiChipInfoToStaticChipInfos(WifiChipInfo[] chipInfos) { + StaticChipInfo[] staticChipInfos = new StaticChipInfo[chipInfos.length]; + for (int i = 0; i < chipInfos.length; i++) { + WifiChipInfo chipInfo = chipInfos[i]; + staticChipInfos[i] = new StaticChipInfo( + chipInfo.chipId, + chipInfo.chipCapabilities, + chipInfo.availableModes); + } + return staticChipInfos; + } + /** * Checks the local state of this object (the cached state) against the input 'chipInfos' * state (which is a live representation of the Wi-Fi firmware status - read through the HAL). @@ -1701,6 +1769,14 @@ public class HalDeviceManager { Log.d(TAG, "start IWifi succeeded after trying " + triedCount + " times"); } + WifiChipInfo[] wifiChipInfos = getAllChipInfo(); + if (wifiChipInfos != null) { + mCachedStaticChipInfos = + convertWifiChipInfoToStaticChipInfos(getAllChipInfo()); + saveStaticChipInfoToStore(mCachedStaticChipInfos); + } else { + Log.e(TAG, "Started wifi but could not get current chip info."); + } return true; } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) { // Should retry. Hal might still be stopping. @@ -1920,15 +1996,13 @@ public class HalDeviceManager { } } - private static boolean isChipCapabilitiesSupported(@NonNull WifiChipInfo chipInfo, + private static boolean isChipCapabilitiesSupported(long currentChipCapabilities, long requiredChipCapabilities) { - if (chipInfo == null) return false; - if (requiredChipCapabilities == CHIP_CAPABILITY_ANY) return true; - if (CHIP_CAPABILITY_UNINITIALIZED == chipInfo.chipCapabilities) return true; + if (CHIP_CAPABILITY_UNINITIALIZED == currentChipCapabilities) return true; - return (chipInfo.chipCapabilities & requiredChipCapabilities) + return (currentChipCapabilities & requiredChipCapabilities) == requiredChipCapabilities; } @@ -1946,10 +2020,13 @@ public class HalDeviceManager { synchronized (mLock) { IfaceCreationData bestIfaceCreationProposal = null; for (WifiChipInfo chipInfo : chipInfos) { - if (!isChipCapabilitiesSupported(chipInfo, requiredChipCapabilities)) continue; + if (!isChipCapabilitiesSupported( + chipInfo.chipCapabilities, requiredChipCapabilities)) { + continue; + } SparseArray<List<int[][]>> expandedCreateTypeCombosPerChipModeId = - getExpandedCreateTypeCombosPerChipModeId(chipInfo); + getExpandedCreateTypeCombosPerChipModeId(chipInfo.availableModes); for (int i = 0; i < expandedCreateTypeCombosPerChipModeId.size(); i++) { int chipModeId = expandedCreateTypeCombosPerChipModeId.keyAt(i); for (int[][] expandedCreateTypeCombo : @@ -1972,15 +2049,13 @@ public class HalDeviceManager { } /** - * Returns a SparseArray indexed by ChipModeId, containing Lists of I - * @param chipInfo - * @return + * Returns a SparseArray indexed by ChipModeId, containing Lists of expanded create type combos + * supported by that id. */ private SparseArray<List<int[][]>> getExpandedCreateTypeCombosPerChipModeId( - WifiChipInfo chipInfo) { + ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> chipModes) { SparseArray<List<int[][]>> combosPerChipModeId = new SparseArray<>(); - for (android.hardware.wifi.V1_6.IWifiChip.ChipMode chipMode - : chipInfo.availableModes) { + for (android.hardware.wifi.V1_6.IWifiChip.ChipMode chipMode : chipModes) { List<int[][]> expandedCreateTypeCombos = new ArrayList<>(); for (ChipConcurrencyCombination chipConcurrencyCombo : chipMode.availableCombinations) { @@ -2519,37 +2594,6 @@ public class HalDeviceManager { return true; } - // Is it possible to create a @HdmIfaceTypeForCreation combo just looking at the device - // capabilities. - private boolean isItPossibleToCreateCreateTypeCombo(WifiChipInfo[] chipInfos, - long requiredChipCapabilities, int[] requestedCombo) { - if (VDBG) { - Log.d(TAG, "isItPossibleToCreateCreateTypeCombo: chipInfos=" - + Arrays.deepToString(chipInfos) - + ", requestedCombo=" + Arrays.toString(requestedCombo) - + ", requiredChipCapabilities=" + requiredChipCapabilities); - } - - for (WifiChipInfo chipInfo: chipInfos) { - if (!isChipCapabilitiesSupported(chipInfo, requiredChipCapabilities)) continue; - SparseArray<List<int[][]>> expandedCreateTypeCombosPerChipModeId = - getExpandedCreateTypeCombosPerChipModeId(chipInfo); - for (int i = 0; i < expandedCreateTypeCombosPerChipModeId.size(); i++) { - int chipModeId = expandedCreateTypeCombosPerChipModeId.keyAt(i); - for (int[][] expandedCreateTypeCombo - : expandedCreateTypeCombosPerChipModeId.get(chipModeId)) { - for (int[] createTypeCombo : expandedCreateTypeCombo) { - if (canCreateTypeComboSupportRequestedCreateTypeCombo( - createTypeCombo, requestedCombo)) { - return true; - } - } - } - } - } - return false; - } - /** * Performs chip reconfiguration per the input: * - Removes the specified interfaces diff --git a/service/java/com/android/server/wifi/HalDeviceManagerUtil.java b/service/java/com/android/server/wifi/HalDeviceManagerUtil.java new file mode 100644 index 0000000000..08a4727924 --- /dev/null +++ b/service/java/com/android/server/wifi/HalDeviceManagerUtil.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2022 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 com.android.server.wifi; + +import android.annotation.NonNull; +import android.hardware.wifi.V1_6.IWifiChip; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +/** + * Utility methods for HalDeviceManager. + */ +public class HalDeviceManagerUtil { + static class StaticChipInfo { + private int mChipId; + private long mChipCapabilities; + private @NonNull ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> mAvailableModes = + new ArrayList<>(); + + StaticChipInfo( + int chipId, + long chipCapabilities, + @NonNull ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> availableModes) { + mChipId = chipId; + mChipCapabilities = chipCapabilities; + if (availableModes != null) { + mAvailableModes = availableModes; + } + } + + int getChipId() { + return mChipId; + } + + long getChipCapabilities() { + return mChipCapabilities; + } + + ArrayList<android.hardware.wifi.V1_6.IWifiChip.ChipMode> getAvailableModes() { + return mAvailableModes; + } + } + + private static final String KEY_CHIP_ID = "chipId"; + private static final String KEY_CHIP_CAPABILITIES = "chipCapabilities"; + private static final String KEY_AVAILABLE_MODES = "availableModes"; + + static JSONObject staticChipInfoToJson(@NonNull StaticChipInfo staticChipInfo) + throws JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(KEY_CHIP_ID, staticChipInfo.getChipId()); + jsonObject.put(KEY_CHIP_CAPABILITIES, staticChipInfo.getChipCapabilities()); + JSONArray availableModesJson = new JSONArray(); + for (android.hardware.wifi.V1_6.IWifiChip.ChipMode mode + : staticChipInfo.getAvailableModes()) { + availableModesJson.put(chipModeToJson(mode)); + } + jsonObject.put(KEY_AVAILABLE_MODES, availableModesJson); + return jsonObject; + } + + static StaticChipInfo jsonToStaticChipInfo(JSONObject jsonObject) throws JSONException { + ArrayList<IWifiChip.ChipMode> availableModes = + new ArrayList<>(); + int chipId = jsonObject.getInt(KEY_CHIP_ID); + long chipCapabilities = jsonObject.getLong(KEY_CHIP_CAPABILITIES); + JSONArray modesJson = jsonObject.getJSONArray(KEY_AVAILABLE_MODES); + for (int i = 0; i < modesJson.length(); i++) { + availableModes.add(jsonToChipMode(modesJson.getJSONObject(i))); + } + return new StaticChipInfo(chipId, chipCapabilities, availableModes); + } + + private static final String KEY_ID = "id"; + private static final String KEY_AVAILABLE_COMBINATIONS = "availableCombinations"; + + private static JSONObject chipModeToJson(android.hardware.wifi.V1_6.IWifiChip.ChipMode chipMode) + throws JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(KEY_ID, chipMode.id); + JSONArray availableCombinationsJson = new JSONArray(); + for (IWifiChip.ChipConcurrencyCombination combo + : chipMode.availableCombinations) { + availableCombinationsJson.put(chipConcurrencyCombinationToJson(combo)); + } + jsonObject.put(KEY_AVAILABLE_COMBINATIONS, availableCombinationsJson); + return jsonObject; + } + + private static android.hardware.wifi.V1_6.IWifiChip.ChipMode jsonToChipMode( + JSONObject jsonObject) throws JSONException { + android.hardware.wifi.V1_6.IWifiChip.ChipMode chipMode = + new android.hardware.wifi.V1_6.IWifiChip.ChipMode(); + chipMode.id = jsonObject.getInt(KEY_ID); + JSONArray availableCombinationsJson = + jsonObject.getJSONArray(KEY_AVAILABLE_COMBINATIONS); + for (int i = 0; i < availableCombinationsJson.length(); i++) { + chipMode.availableCombinations.add(jsonToChipConcurrencyCombination( + availableCombinationsJson.getJSONObject(i))); + } + return chipMode; + } + + private static final String KEY_CONCURRENCY_LIMITS = "limits"; + + private static JSONObject chipConcurrencyCombinationToJson( + IWifiChip.ChipConcurrencyCombination combo) throws JSONException { + JSONObject jsonObject = new JSONObject(); + JSONArray limitsJson = new JSONArray(); + for (IWifiChip.ChipConcurrencyCombinationLimit limit : combo.limits) { + limitsJson.put(chipConcurrencyCombinationLimitToJson(limit)); + } + jsonObject.put(KEY_CONCURRENCY_LIMITS, limitsJson); + return jsonObject; + } + + private static IWifiChip.ChipConcurrencyCombination jsonToChipConcurrencyCombination( + JSONObject jsonObject) throws JSONException { + IWifiChip.ChipConcurrencyCombination combo = new IWifiChip.ChipConcurrencyCombination(); + combo.limits = new ArrayList<>(); + JSONArray limitsJson = jsonObject.getJSONArray(KEY_CONCURRENCY_LIMITS); + for (int i = 0; i < limitsJson.length(); i++) { + combo.limits.add( + jsonToChipConcurrencyCombinationLimit(limitsJson.getJSONObject(i))); + } + return combo; + } + + private static final String KEY_MAX_IFACES = "maxIfaces"; + private static final String KEY_TYPES = "types"; + + private static JSONObject chipConcurrencyCombinationLimitToJson( + IWifiChip.ChipConcurrencyCombinationLimit limit) throws JSONException { + JSONObject jsonObject = new JSONObject(); + jsonObject.put(KEY_MAX_IFACES, limit.maxIfaces); + jsonObject.put(KEY_TYPES, new JSONArray(limit.types)); + return jsonObject; + } + + private static IWifiChip.ChipConcurrencyCombinationLimit jsonToChipConcurrencyCombinationLimit( + JSONObject jsonObject) throws JSONException { + IWifiChip.ChipConcurrencyCombinationLimit + limit = new IWifiChip.ChipConcurrencyCombinationLimit(); + limit.maxIfaces = jsonObject.getInt(KEY_MAX_IFACES); + limit.types = new ArrayList<>(); + JSONArray limitsJson = jsonObject.getJSONArray(KEY_TYPES); + for (int i = 0; i < limitsJson.length(); i++) { + limit.types.add(limitsJson.getInt(i)); + } + return limit; + } +} + diff --git a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java index 5218425dc8..6c4c658257 100644 --- a/service/java/com/android/server/wifi/WifiSettingsConfigStore.java +++ b/service/java/com/android/server/wifi/WifiSettingsConfigStore.java @@ -120,6 +120,11 @@ public class WifiSettingsConfigStore { public static final Key<Long> WIFI_NATIVE_SUPPORTED_FEATURES = new Key<>("wifi_native_supported_features", 0L); + /** + * Store the static chip info retrieved from WiFi HAL + */ + public static final Key<String> WIFI_STATIC_CHIP_INFO = new Key<>("wifi_static_chip_info", ""); + /******** Wifi shared pref keys ***************/ private final Context mContext; diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java index a2204123d1..5bad7d7fa6 100644 --- a/service/java/com/android/server/wifi/WifiVendorHal.java +++ b/service/java/com/android/server/wifi/WifiVendorHal.java @@ -3411,7 +3411,7 @@ public class WifiVendorHal { */ public boolean isStaApConcurrencySupported() { synchronized (sLock) { - return mHalDeviceManager.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + return mHalDeviceManager.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(HDM_CREATE_IFACE_STA, 1); put(HDM_CREATE_IFACE_AP, 1); }}); @@ -3423,7 +3423,7 @@ public class WifiVendorHal { */ public boolean isStaStaConcurrencySupported() { synchronized (sLock) { - return mHalDeviceManager.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + return mHalDeviceManager.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(HDM_CREATE_IFACE_STA, 2); }}); } 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 78faf9fcf3..5b227ff31a 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/HalDeviceManagerTest.java @@ -92,6 +92,7 @@ import com.android.wifi.resources.R; import com.google.common.collect.ImmutableList; import org.hamcrest.core.IsNull; +import org.json.JSONArray; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -132,6 +133,7 @@ public class HalDeviceManagerTest extends WifiBaseTest { @Mock private Resources mResources; @Mock private Clock mClock; @Mock private WifiInjector mWifiInjector; + @Mock private WifiSettingsConfigStore mWifiSettingsConfigStore; @Mock private WorkSourceHelper mWorkSourceHelper0; @Mock private WorkSourceHelper mWorkSourceHelper1; @Mock private WorkSourceHelper mWorkSourceHelper2; @@ -220,6 +222,7 @@ public class HalDeviceManagerTest extends WifiBaseTest { when(mWorkSourceHelper0.getWorkSource()).thenReturn(TEST_WORKSOURCE_0); when(mWorkSourceHelper1.getWorkSource()).thenReturn(TEST_WORKSOURCE_1); when(mWorkSourceHelper2.getWorkSource()).thenReturn(TEST_WORKSOURCE_2); + when(mWifiInjector.getSettingsConfigStore()).thenReturn(mWifiSettingsConfigStore); when(mServiceManagerMock.linkToDeath(any(IHwBinder.DeathRecipient.class), anyLong())).thenReturn(true); @@ -266,6 +269,9 @@ public class HalDeviceManagerTest extends WifiBaseTest { */ @Test public void testStartStopFlow() throws Exception { + TestChipV5 chipMock = new TestChipV5(); + setupWifiChipV15(chipMock); + chipMock.initialize(); mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, mManagerStatusListenerMock); executeAndValidateInitializationSequence(); @@ -305,6 +311,9 @@ public class HalDeviceManagerTest extends WifiBaseTest { */ @Test public void testMultipleCallbackRegistrations() throws Exception { + TestChipV5 chipMock = new TestChipV5(); + setupWifiChipV15(chipMock); + chipMock.initialize(); mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, mManagerStatusListenerMock); executeAndValidateInitializationSequence(); @@ -333,6 +342,9 @@ public class HalDeviceManagerTest extends WifiBaseTest { */ @Test public void testWifiDeathAndRegistration() throws Exception { + TestChipV5 chipMock = new TestChipV5(); + setupWifiChipV15(chipMock); + chipMock.initialize(); mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, mWifiMockV15, mManagerStatusListenerMock); executeAndValidateInitializationSequence(); @@ -378,6 +390,9 @@ public class HalDeviceManagerTest extends WifiBaseTest { */ @Test public void testWifiFail() throws Exception { + TestChipV5 chipMock = new TestChipV5(); + setupWifiChipV15(chipMock); + chipMock.initialize(); mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, mWifiMockV15, mManagerStatusListenerMock); executeAndValidateInitializationSequence(); @@ -1414,20 +1429,20 @@ public class HalDeviceManagerTest extends WifiBaseTest { } /** - * Validate {@link HalDeviceManager#canSupportCreateTypeCombo(SparseArray)} + * Validate {@link HalDeviceManager#canDeviceSupportCreateTypeCombo(SparseArray)} */ @Test - public void testCanSupportIfaceComboTestChipV1() throws Exception { - final String name = "wlan0"; - + public void testCanDeviceSupportCreateTypeComboChipV1() throws Exception { TestChipV1 chipMock = new TestChipV1(); chipMock.initialize(); mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip, mManagerStatusListenerMock); executeAndValidateInitializationSequence(); - // Try to query iface support before starting the HAL. Should return false. + + // Try to query iface support before starting the HAL. Should return false without any + // stored static chip info. when(mWifiMock.isStarted()).thenReturn(false); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); }} )); @@ -1437,50 +1452,114 @@ public class HalDeviceManagerTest extends WifiBaseTest { clearInvocations(mWifiMock); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + // Verify that the latest static chip info is saved to store. + verify(mWifiSettingsConfigStore).put(eq(WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO), + eq(new JSONArray(TestChipV1.STATIC_CHIP_INFO_JSON_STRING).toString())); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + // AP should now be supported after we read directly from the chip. + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.AP, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.P2P, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.NAN, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.P2P, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.NAN, 1); }} )); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.AP, 1); }} )); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 2); }} )); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.P2P, 1); put(IfaceConcurrencyType.NAN, 1); }} )); - // Ensure we only fetched chip info once, use the cache after that. - verify(mWifiMock, times(1)).getChipIds(any()); + verifyNoMoreInteractions(mManagerStatusListenerMock); + } + + /** + * Validate {@link HalDeviceManager#canDeviceSupportCreateTypeCombo(SparseArray)} with stored + * static chip info. + */ + @Test + public void testCanDeviceSupportCreateTypeComboChipV1WithStoredStaticChipInfo() + throws Exception { + TestChipV1 chipMock = new TestChipV1(); + chipMock.initialize(); + mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip, + mManagerStatusListenerMock); + executeAndValidateInitializationSequence(); + + // Try to query iface support before starting the HAL. Should return true with the stored + // static chip info. + when(mWifiMock.isStarted()).thenReturn(false); + when(mWifiSettingsConfigStore.get(WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO)) + .thenReturn(TestChipV1.STATIC_CHIP_INFO_JSON_STRING); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.STA, 1); + }} + )); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.AP, 1); + }} + )); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.P2P, 1); + }} + )); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.NAN, 1); + }} + )); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.STA, 1); + put(IfaceConcurrencyType.P2P, 1); + }} + )); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.STA, 1); + put(IfaceConcurrencyType.NAN, 1); + }} + )); + + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.STA, 1); + put(IfaceConcurrencyType.AP, 1); + }} + )); + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.STA, 2); + }} + )); + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ + put(IfaceConcurrencyType.P2P, 1); + put(IfaceConcurrencyType.NAN, 1); + }} + )); verifyNoMoreInteractions(mManagerStatusListenerMock); } @@ -1837,20 +1916,21 @@ public class HalDeviceManagerTest extends WifiBaseTest { } /** - * Validate {@link HalDeviceManager#canSupportCreateTypeCombo(SparseArray)} + * Validate {@link HalDeviceManager#canDeviceSupportCreateTypeCombo(SparseArray)} */ @Test - public void testCanSupportIfaceComboTestChipV2() throws Exception { - final String name = "wlan0"; - + public void testCanDeviceSupportIfaceComboTestChipV2() throws Exception { TestChipV2 chipMock = new TestChipV2(); chipMock.initialize(); mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, chipMock.chip, mManagerStatusListenerMock); executeAndValidateInitializationSequence(); - // Try to query iface support before starting the HAL. Should return false. + // Try to query iface support before starting the HAL. Should return true with the stored + // static chip info. when(mWifiMock.isStarted()).thenReturn(false); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + when(mWifiSettingsConfigStore.get(WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO)) + .thenReturn(TestChipV2.STATIC_CHIP_INFO_JSON_STRING); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); }} )); @@ -1860,77 +1940,74 @@ public class HalDeviceManagerTest extends WifiBaseTest { clearInvocations(mWifiMock); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.AP, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.P2P, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.NAN, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.P2P, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.NAN, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.AP, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 2); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.P2P, 1); put(IfaceConcurrencyType.AP, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.P2P, 1); put(IfaceConcurrencyType.AP, 1); }} )); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.AP, 1); put(IfaceConcurrencyType.NAN, 1); }} )); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.P2P, 1); put(IfaceConcurrencyType.NAN, 1); }} )); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.AP, 2); }} )); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() {{ + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() {{ put(IfaceConcurrencyType.STA, 2); put(IfaceConcurrencyType.AP, 1); }} )); - // Ensure we only fetched chip info once, use the cache after that. - verify(mWifiMock, times(1)).getChipIds(any()); - verifyNoMoreInteractions(mManagerStatusListenerMock); } @@ -3078,18 +3155,21 @@ public class HalDeviceManagerTest extends WifiBaseTest { } /** - * Validate {@link HalDeviceManager#canSupportCreateTypeCombo(SparseArray)} + * Validate {@link HalDeviceManager#canDeviceSupportCreateTypeCombo(SparseArray)} */ @Test - public void testCanSupportIfaceComboTestChipV6() throws Exception { + public void testCanDeviceSupportIfaceComboTestChipV6() throws Exception { TestChipV6 testChip = new TestChipV6(); testChip.initialize(); mInOrder = inOrder(mServiceManagerMock, mWifiMock, mWifiMockV15, testChip.chip, mManagerStatusListenerMock); executeAndValidateInitializationSequence(); - // Try to query iface support before starting the HAL. Should return false. + // Try to query iface support before starting the HAL. Should return true with the stored + // static chip info. when(mWifiMock.isStarted()).thenReturn(false); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + when(mWifiSettingsConfigStore.get(WifiSettingsConfigStore.WIFI_STATIC_CHIP_INFO)) + .thenReturn(TestChipV6.STATIC_CHIP_INFO_JSON_STRING); + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.STA, 1); } @@ -3100,55 +3180,52 @@ public class HalDeviceManagerTest extends WifiBaseTest { clearInvocations(mWifiMock); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.STA, 1); } })); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.AP, 1); } })); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.AP, 1); } })); - assertTrue(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + assertTrue(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.AP_BRIDGED, 1); } })); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.AP, 1); put(IfaceConcurrencyType.AP_BRIDGED, 1); } })); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.STA, 1); put(IfaceConcurrencyType.AP, 1); put(IfaceConcurrencyType.AP_BRIDGED, 1); } })); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.NAN, 1); } })); - assertFalse(mDut.canSupportCreateTypeCombo(new SparseArray<Integer>() { + assertFalse(mDut.canDeviceSupportCreateTypeCombo(new SparseArray<Integer>() { { put(IfaceConcurrencyType.P2P, 2); } })); - // Ensure we only fetched chip info once, use the cache after that. - verify(mWifiMock, times(1)).getChipIds(any()); - verifyNoMoreInteractions(mManagerStatusListenerMock); } @@ -4126,6 +4203,44 @@ public class HalDeviceManagerTest extends WifiBaseTest { private class TestChipV1 extends ChipMockBase { static final int STA_CHIP_MODE_ID = 0; static final int AP_CHIP_MODE_ID = 1; + static final String STATIC_CHIP_INFO_JSON_STRING = "[" + + " {" + + " \"chipId\": 10," + + " \"chipCapabilities\": -1," + + " \"availableModes\": [" + + " {" + + " \"id\": 0," + + " \"availableCombinations\": [" + + " {" + + " \"limits\": [" + + " {" + + " \"maxIfaces\": 1," + + " \"types\": [0]" + + " }," + + " {" + + " \"maxIfaces\": 1," + + " \"types\": [3, 4]" + + " }" + + " ]" + + " }" + + " ]" + + " }," + + " {" + + " \"id\": 1," + + " \"availableCombinations\": [" + + " {" + + " \"limits\": [" + + " {" + + " \"maxIfaces\": 1," + + " \"types\": [1]" + + " }" + + " ]" + + " }" + + " ]" + + " }" + + " ]" + + " }" + + "]"; void initialize() throws Exception { super.initialize(); @@ -4191,6 +4306,35 @@ public class HalDeviceManagerTest extends WifiBaseTest { private class TestChipV2 extends ChipMockBase { // only mode (different number from any in TestChipV1 so can catch test errors) static final int CHIP_MODE_ID = 5; + static final String STATIC_CHIP_INFO_JSON_STRING = "[" + + " {" + + " \"chipId\": 12," + + " \"chipCapabilities\": 0," + + " \"availableModes\": [" + + " {" + + " \"id\": 5," + + " \"availableCombinations\": [" + + " {" + + " \"limits\": [" + + " {" + + " \"maxIfaces\": 1," + + " \"types\": [0]" + + " }," + + " {" + + " \"maxIfaces\": 1," + + " \"types\": [0, 1]" + + " }," + + " {" + + " \"maxIfaces\": 1," + + " \"types\": [3, 4]" + + " }" + + " ]" + + " }" + + " ]" + + " }" + + " ]" + + " }" + + "]"; void initialize() throws Exception { super.initialize(); @@ -4470,6 +4614,31 @@ public class HalDeviceManagerTest extends WifiBaseTest { // only mode (different number from any in other TestChips so can catch test errors) static final int CHIP_MODE_ID = 60; static final int CHIP_ID = 6; + static final String STATIC_CHIP_INFO_JSON_STRING = "[" + + " {" + + " \"chipId\": 6," + + " \"chipCapabilities\": 0," + + " \"availableModes\": [" + + " {" + + " \"id\": 60," + + " \"availableCombinations\": [" + + " {" + + " \"limits\": [" + + " {" + + " \"maxIfaces\": 1," + + " \"types\": [0]" + + " }," + + " {" + + " \"maxIfaces\": 1," + + " \"types\": [1, 2]" + + " }" + + " ]" + + " }" + + " ]" + + " }" + + " ]" + + " }" + + "]"; void initialize() throws Exception { super.initialize(); diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java index 4ef60b4de3..0a12c571ed 100644 --- a/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java +++ b/service/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java @@ -3846,7 +3846,7 @@ public class WifiVendorHalTest extends WifiBaseTest { @Test public void testIsStaApConcurrencySupported() { - when(mHalDeviceManager.canSupportCreateTypeCombo( + when(mHalDeviceManager.canDeviceSupportCreateTypeCombo( argThat(ifaceCombo -> ifaceCombo.get(IfaceType.STA) == 1 && ifaceCombo.get(IfaceType.AP) == 1))).thenReturn(true); assertTrue(mWifiVendorHal.isStaApConcurrencySupported()); @@ -3854,7 +3854,7 @@ public class WifiVendorHalTest extends WifiBaseTest { @Test public void testIsStaStaConcurrencySupported() { - when(mHalDeviceManager.canSupportCreateTypeCombo( + when(mHalDeviceManager.canDeviceSupportCreateTypeCombo( argThat(ifaceCombo -> ifaceCombo.get(IfaceType.STA) == 2))).thenReturn(true); assertTrue(mWifiVendorHal.isStaStaConcurrencySupported()); } |