--- a/service/java/com/android/server/wifi/SoftApManager.java
+++ b/service/java/com/android/server/wifi/SoftApManager.java
@@ -918,6 +918,7 @@ public class SoftApManager implements ActiveModeManager {
startResult = ApConfigUtil.updateApChannelConfig(
mWifiNative, mCoexManager, mResourceCache, mCountryCode,
+ mActiveModeWarden.getClientModeManagers(),
localConfigBuilder, mCurrentSoftApConfiguration, mCurrentSoftApCapability);
if (startResult != START_RESULT_SUCCESS) {
Log.e(getTag(), "Failed to update AP band and channel");
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 88c32793b2..9b8138f42b 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -18,6 +18,7 @@ package com.android.server.wifi;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.wifi.ScanResult.WIFI_BAND_24_GHZ;
import static android.net.wifi.ScanResult.WIFI_BAND_5_GHZ;
import static android.net.wifi.ScanResult.WIFI_BAND_6_GHZ;
@@ -92,14 +93,17 @@ import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.hardware.wifi.WifiStatusCode;
import android.location.LocationManager;
+import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.DhcpOption;
import android.net.DhcpResultsParcelable;
import android.net.InetAddresses;
import android.net.MacAddress;
import android.net.Network;
+import android.net.TetheringManager;
import android.net.NetworkCapabilities;
import android.net.NetworkStack;
+import java.util.concurrent.Executors;
import android.net.TetheringManager;
import android.net.Uri;
import android.net.ip.IpClientUtil;
@@ -290,6 +294,7 @@ import java.io.DataOutputStream;
*/
public class WifiServiceImpl extends IWifiManager.Stub {
private static final String TAG = "WifiService";
+ private static final String TAG_AP = "WifiServiceAP";
private static final boolean VDBG = false;
/** Max wait time for posting blocking runnables */
@@ -391,6 +396,8 @@ public class WifiServiceImpl extends IWifiManager.Stub {
private final DefaultClientModeManager mDefaultClientModeManager;
+ private TetheringManager mTetheringManager = null;
+
private final WepNetworkUsageController mWepNetworkUsageController;
private final FeatureFlags mFeatureFlags;
@@ -809,6 +816,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
mFeatureFlags = mDeviceConfigFacade.getFeatureFlags();
mApplicationQosPolicyRequestHandler = mWifiInjector.getApplicationQosPolicyRequestHandler();
mWifiPulledAtomLogger = mWifiInjector.getWifiPulledAtomLogger();
+ mTetheringManager = mContext.getSystemService(TetheringManager.class);
mAfcManager = mWifiInjector.getAfcManager();
mTwtManager = mWifiInjector.getTwtManager();
mWepNetworkUsageController = mWifiInjector.getWepNetworkUsageController();
@@ -1047,6 +1055,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
registerForCarrierConfigChange();
mWifiInjector.getAdaptiveConnectivityEnabledSettingObserver().initialize();
mIsWifiServiceStarted = true;
+ mActiveModeWarden.addWifiNetworkStateChangedListener(new WifiNetworkStateChangedListener());
}, TAG + "#checkAndStartWifi");
}
@@ -9275,6 +9284,121 @@ public class WifiServiceImpl extends IWifiManager.Stub {
}, TAG + "#getSupportedSimultaneousBandCombinations");
}
+ public class WifiNetworkStateChangedListener extends IWifiNetworkStateChangedListener.Stub {
+
+ public static final int MAKE_Hotspot_With_Network_DELAYED_MILLIS = 2 * 1000;
+
+ @Override
+ public void onWifiNetworkStateChanged(int clientRole, int status) {
+ switch (status) {
+ case WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_DISCONNECTED:
+ mWifiThreadRunner.removeCallbacks(makeHotspotWithConnectedNetworkRunnable);
+ break;
+ case WifiManager.WifiNetworkStateChangedListener.WIFI_NETWORK_STATUS_CONNECTED:
+ mWifiThreadRunner.removeCallbacks(makeHotspotWithConnectedNetworkRunnable);
+ mWifiThreadRunner.postDelayed(makeHotspotWithConnectedNetworkRunnable,
+ MAKE_Hotspot_With_Network_DELAYED_MILLIS,"WifiServiceImpl");
+ break;
+ default:
+ break;
+ }
+ }
+
+ private Runnable makeHotspotWithConnectedNetworkRunnable = () -> {
+ updateApConfiguration();
+ restartTetheringIfNeeded();
+ };
+
+ //update new ap config
+ private void updateApConfiguration() {
+ SoftApConfiguration newSoftApConfig = makeNewSoftApConfiguration(
+ mWifiApConfigStore.getApConfiguration(), mActiveModeWarden.getConnectionInfo());
+ Log.w(TAG_AP, "Update Hotspot due network connected : " + newSoftApConfig);
+ mWifiApConfigStore.setApConfiguration(newSoftApConfig);
+ mActiveModeWarden.updateSoftApConfiguration(newSoftApConfig);
+ }
+
+ private SoftApConfiguration makeNewSoftApConfiguration(SoftApConfiguration oldSoftApConfig,
+ WifiInfo connectionInfo) {
+ if (connectionInfo.getFrequency() == 0) {
+ return new SoftApConfiguration.Builder(oldSoftApConfig)
+ .setBand(SoftApConfiguration.BAND_2GHZ)
+ .build();
+ }else {
+ return new SoftApConfiguration.Builder(oldSoftApConfig)
+ .setBand(ApConfigUtil.convertFrequencyToBand(connectionInfo.getFrequency()))
+ .build();
+ }
+ }
+
+ //restart soft ap
+ private void restartTetheringIfNeeded() {
+ int apStatue = getWifiApEnabledState();
+ if (apStatue == WIFI_AP_STATE_ENABLED || apStatue == WIFI_AP_STATE_ENABLING) {
+ Log.w(TAG_AP, "Restarting Tethering");
+ apNeedRestart = true;
+ if (!mTetheredSoftApTracker.registerSoftApCallback(new SoftApCallback(),null)) {
+ Log.e(TAG_AP, "registerSoftApCallback: Failed to add callback");
+ }
+ Log.w(TAG_AP, "Stopping Tethering");
+ mTetheringManager.stopTethering(TETHERING_WIFI);
+ }
+ }
+
+ }
+
+ private boolean apNeedRestart;
+
+ public class SoftApCallback extends ISoftApCallback.Stub {
+
+ private static final int RESTART_INTERVAL_MS = 200;
+
+ @Override
+ public void onStateChanged(SoftApState state) {
+ if (state.getState() == WIFI_AP_STATE_DISABLED) {
+ Log.w(TAG_AP, "AP DISABLED");
+ if (!apNeedRestart) {
+ return;
+ }
+ mWifiThreadRunner.postDelayed(() -> {
+ Log.w(TAG_AP, "Starting Tethering");
+ mTetheringManager.startTethering(TETHERING_WIFI,
+ Executors.newSingleThreadExecutor(), new StartTetheringCallback());
+ }, RESTART_INTERVAL_MS,"WifiServiceImpl");
+ apNeedRestart = false;
+ } else if (state.getState() == WIFI_AP_STATE_ENABLED) {
+ Log.w(TAG_AP, "AP ENABLED");
+ }
+ }
+
+ @Override
+ public void onConnectedClientsOrInfoChanged(Map<String, SoftApInfo> infos,
+ Map<String, List<WifiClient>> clients, boolean isBridged,
+ boolean isRegistration){
+ }
+
+ @Override
+ public void onCapabilityChanged(SoftApCapability capability){
+ }
+
+ @Override
+ public void onBlockedClientConnecting(WifiClient client, int blockedReason){
+ }
+ @Override
+ public void onClientsDisconnected(SoftApInfo info,List<WifiClient> clients){
+ }
+ }
+
+ private class StartTetheringCallback implements TetheringManager.StartTetheringCallback {
+ @Override
+ public void onTetheringStarted() {
+ }
+
+ @Override
+ public void onTetheringFailed(int error) {
+ }
+ }
+
/**
* Set the mock wifi service for testing
*/
diff --git a/service/java/com/android/server/wifi/util/ApConfigUtil.java b/service/java/com/android/server/wifi/util/ApConfigUtil.java
index c60a9f4f35..d5bde9a92b 100644
--- a/service/java/com/android/server/wifi/util/ApConfigUtil.java
+++ b/service/java/com/android/server/wifi/util/ApConfigUtil.java
@@ -82,6 +82,8 @@ import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
+import android.net.wifi.WifiInfo;
+import com.android.server.wifi.ClientModeManager;
/**
* Provide utility functions for updating soft AP related configuration.
@@ -1000,6 +1002,7 @@ public class ApConfigUtil {
@NonNull CoexManager coexManager,
WifiResourceCache resources,
String countryCode,
+ List<ClientModeManager> clientModeManagers,
SoftApConfiguration.Builder configBuilder,
SoftApConfiguration config,
SoftApCapability capability) {
@@ -1044,6 +1047,20 @@ public class ApConfigUtil {
}
}
+ //Make AP band same as Connect band, default BAND_5GHZ
+// configBuilder.setBand(SoftApConfiguration.BAND_5GHZ);
+ for (ClientModeManager cmm
+ : clientModeManagers) {
+ WifiInfo wifiConnectedInfo = cmm.getConnectionInfo();
+ int frequency = wifiConnectedInfo.getFrequency();
+ if (frequency > 0) {
+ Log.d(TAG, "Connected Frequency " + frequency
+ + ", make AP band same as Connected band.");
+ configBuilder.setBand(convertFrequencyToBand(frequency));
+ break;
+ }
+ }
+
return SoftApManager.START_RESULT_SUCCESS;
}