diff options
4 files changed, 98 insertions, 17 deletions
diff --git a/service/java/com/android/server/wifi/WifiApConfigStore.java b/service/java/com/android/server/wifi/WifiApConfigStore.java index 6981618b8..e6eebb9e7 100644 --- a/service/java/com/android/server/wifi/WifiApConfigStore.java +++ b/service/java/com/android/server/wifi/WifiApConfigStore.java @@ -350,13 +350,13 @@ public class WifiApConfigStore { * Generate a temporary WPA2 based configuration for use by the local only hotspot. * This config is not persisted and will not be stored by the WifiApConfigStore. */ - public static WifiConfiguration generateLocalOnlyHotspotConfig(Context context) { + public static WifiConfiguration generateLocalOnlyHotspotConfig(Context context, int apBand) { WifiConfiguration config = new WifiConfiguration(); - // For local only hotspot we only use 2.4Ghz band. - config.apBand = WifiConfiguration.AP_BAND_2GHZ; + config.SSID = context.getResources().getString( R.string.wifi_localhotspot_configure_ssid_default) + "_" + getRandomIntForDefaultSsid(); + config.apBand = apBand; config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); config.networkId = WifiConfiguration.LOCAL_ONLY_NETWORK_ID; String randomUUID = UUID.randomUUID().toString(); diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index fc7e66481..6206d9b15 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -28,6 +28,7 @@ import static android.net.wifi.WifiManager.SAP_START_FAILURE_NO_CHANNEL; import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING; import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; +import static android.net.wifi.WifiManager.WIFI_FEATURE_INFRA_5G; import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR; import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED; @@ -1382,8 +1383,14 @@ public class WifiServiceImpl extends IWifiManager.Stub { } } else if (mLocalOnlyHotspotRequests.isEmpty()) { // this is the first request, then set up our config and start LOHS - mLocalOnlyHotspotConfig = - WifiApConfigStore.generateLocalOnlyHotspotConfig(mContext); + boolean is5Ghz = hasAutomotiveFeature(mContext) + && mContext.getResources().getBoolean( + com.android.internal.R.bool.config_wifi_local_only_hotspot_5ghz) + && is5GhzSupported(); + + mLocalOnlyHotspotConfig = WifiApConfigStore.generateLocalOnlyHotspotConfig(mContext, + is5Ghz ? WifiConfiguration.AP_BAND_5GHZ : WifiConfiguration.AP_BAND_2GHZ); + startSoftApInternal(mLocalOnlyHotspotConfig, WifiManager.IFACE_IP_MODE_LOCAL_ONLY); } @@ -1612,12 +1619,7 @@ public class WifiServiceImpl extends IWifiManager.Stub { if (mVerboseLoggingEnabled) { mLog.info("getSupportedFeatures uid=%").c(Binder.getCallingUid()).flush(); } - if (mClientModeImplChannel != null) { - return mClientModeImpl.syncGetSupportedFeatures(mClientModeImplChannel); - } else { - Slog.e(TAG, "mClientModeImplChannel is not initialized"); - return 0; - } + return getSupportedFeaturesInternal(); } @Override @@ -2870,4 +2872,22 @@ public class WifiServiceImpl extends IWifiManager.Stub { mTrafficPoller.removeCallback(callbackIdentifier); }); } + + private boolean is5GhzSupported() { + return (getSupportedFeaturesInternal() & WIFI_FEATURE_INFRA_5G) == WIFI_FEATURE_INFRA_5G; + } + + private int getSupportedFeaturesInternal() { + final AsyncChannel channel = mClientModeImplChannel; + if (channel != null) { + return mClientModeImpl.syncGetSupportedFeatures(channel); + } else { + Slog.e(TAG, "mClientModeImplChannel is not initialized"); + return 0; + } + } + + private static boolean hasAutomotiveFeature(Context context) { + return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java index 88312ce4c..6b054be1f 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiApConfigStoreTest.java @@ -184,11 +184,12 @@ public class WifiApConfigStoreTest { assertTrue(config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK)); } - private void verifyDefaultLocalOnlyApConfig(WifiConfiguration config, String expectedSsid) { + private void verifyDefaultLocalOnlyApConfig(WifiConfiguration config, String expectedSsid, + int expectedApBand) { String[] splitSsid = config.SSID.split("_"); assertEquals(2, splitSsid.length); assertEquals(expectedSsid, splitSsid[0]); - assertEquals(WifiConfiguration.AP_BAND_2GHZ, config.apBand); + assertEquals(expectedApBand, config.apBand); int randomPortion = Integer.parseInt(splitSsid[1]); assertTrue(randomPortion >= RAND_SSID_INT_MIN && randomPortion <= RAND_SSID_INT_MAX); assertTrue(config.allowedKeyManagement.get(KeyMgmt.WPA2_PSK)); @@ -514,8 +515,26 @@ public class WifiApConfigStoreTest { */ @Test public void generateLocalOnlyHotspotConfigIsValid() { - WifiConfiguration config = WifiApConfigStore.generateLocalOnlyHotspotConfig(mContext); - verifyDefaultLocalOnlyApConfig(config, TEST_DEFAULT_HOTSPOT_SSID); + WifiConfiguration config = WifiApConfigStore + .generateLocalOnlyHotspotConfig(mContext, WifiConfiguration.AP_BAND_2GHZ); + verifyDefaultLocalOnlyApConfig(config, TEST_DEFAULT_HOTSPOT_SSID, + WifiConfiguration.AP_BAND_2GHZ); + // The LOHS config should also have a specific network id set - check that as well. + assertEquals(WifiConfiguration.LOCAL_ONLY_NETWORK_ID, config.networkId); + + // verify that the config passes the validateApWifiConfiguration check + assertTrue(WifiApConfigStore.validateApWifiConfiguration(config)); + } + + /** + * Verify a proper local only hotspot config is generated for 5Ghz band. + */ + @Test + public void generateLocalOnlyHotspotConfigIsValid5G() { + WifiConfiguration config = WifiApConfigStore + .generateLocalOnlyHotspotConfig(mContext, WifiConfiguration.AP_BAND_5GHZ); + verifyDefaultLocalOnlyApConfig(config, TEST_DEFAULT_HOTSPOT_SSID, + WifiConfiguration.AP_BAND_5GHZ); // The LOHS config should also have a specific network id set - check that as well. assertEquals(WifiConfiguration.LOCAL_ONLY_NETWORK_ID, config.networkId); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index d86aeaca1..b4c7014ba 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -33,6 +33,7 @@ import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING; import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED; +import static android.net.wifi.WifiManager.WIFI_FEATURE_INFRA_5G; import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED; import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; import static android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; @@ -160,6 +161,7 @@ public class WifiServiceImplTest { final ArgumentCaptor<Message> mMessageCaptor = ArgumentCaptor.forClass(Message.class); final ArgumentCaptor<SoftApModeConfiguration> mSoftApModeConfigCaptor = ArgumentCaptor.forClass(SoftApModeConfiguration.class); + final ArgumentCaptor<Handler> mHandlerCaptor = ArgumentCaptor.forClass(Handler.class); @Mock Context mContext; @Mock WifiInjector mWifiInjector; @@ -270,6 +272,7 @@ public class WifiServiceImplTest { mHandler = spy(new Handler(mLooper.getLooper())); mAppMessenger = new Messenger(mHandler); + WifiInjector.sWifiInjector = mWifiInjector; when(mRequestInfo.getPid()).thenReturn(mPid); when(mRequestInfo2.getPid()).thenReturn(mPid2); when(mWifiInjector.getUserManager()).thenReturn(mUserManager); @@ -278,6 +281,7 @@ public class WifiServiceImplTest { when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl); when(mClientModeImpl.syncInitialize(any())).thenReturn(true); + when(mClientModeImpl.getHandler()).thenReturn(new Handler()); when(mWifiInjector.getActiveModeWarden()).thenReturn(mActiveModeWarden); when(mWifiInjector.getWifiServiceHandlerThread()).thenReturn(mHandlerThread); when(mWifiInjector.getPowerProfile()).thenReturn(mPowerProfile); @@ -1358,10 +1362,48 @@ public class WifiServiceImplTest { } /** - * Verify that WifiServiceImpl does not send the stop ap message if there were no - * pending LOHS requests upon a binder death callback. + * Verify that by default startLocalOnlyHotspot starts access point at 2 GHz. */ @Test + public void testStartLocalOnlyHotspotAt2Ghz() { + registerLOHSRequestFull(); + verifyLohsBand(WifiConfiguration.AP_BAND_2GHZ); + } + + /** + * Verify that startLocalOnlyHotspot will start access point at 5 GHz if properly configured. + */ + @Test + public void testStartLocalOnlyHotspotAt5Ghz() { + when(mResources.getBoolean( + eq(com.android.internal.R.bool.config_wifi_local_only_hotspot_5ghz))) + .thenReturn(true); + when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)).thenReturn(true); + when(mClientModeImpl.syncGetSupportedFeatures(any(AsyncChannel.class))) + .thenReturn(WIFI_FEATURE_INFRA_5G); + + verify(mAsyncChannel).connect(any(), mHandlerCaptor.capture(), any(Handler.class)); + final Handler handler = mHandlerCaptor.getValue(); + handler.handleMessage(handler.obtainMessage( + AsyncChannel.CMD_CHANNEL_HALF_CONNECTED, AsyncChannel.STATUS_SUCCESSFUL, 0)); + + registerLOHSRequestFull(); + verifyLohsBand(WifiConfiguration.AP_BAND_5GHZ); + } + + private void verifyLohsBand(int expectedBand) { + verify(mWifiController) + .sendMessage(eq(CMD_SET_AP), eq(1), eq(0), mSoftApModeConfigCaptor.capture()); + final WifiConfiguration configuration = mSoftApModeConfigCaptor.getValue().mConfig; + assertNotNull(configuration); + assertEquals(expectedBand, configuration.apBand); + } + + /** + * Verify that WifiServiceImpl does not send the stop ap message if there were no + * pending LOHS requests upon a binder death callback. + */ + @Test public void testServiceImplNotCalledWhenBinderDeathTriggeredNoRequests() { LocalOnlyRequestorCallback binderDeathCallback = mWifiServiceImpl.new LocalOnlyRequestorCallback(); |