summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorJimmy Chen <jimmycmchen@google.com>2020-05-29 07:57:08 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-05-29 07:57:08 +0000
commite1273d71ef5e5b4615e02aabad0b770c90b4ba15 (patch)
treef45989268cd5be27472316aa1009ae1e220250f9 /service
parent81a23e98eb44199ac1bb7a77be2372d544b8a0ab (diff)
parent8ca6b95ba97672098cc2bffe9a99a52eaf7011ad (diff)
Merge "wifi: Register for IMS network callbacks to delay disconnection." into rvc-dev
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/ClientModeManager.java99
-rw-r--r--service/res/values/config.xml3
-rw-r--r--service/res/values/overlayable.xml1
3 files changed, 93 insertions, 10 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeManager.java b/service/java/com/android/server/wifi/ClientModeManager.java
index 66495ae9e..61df5191b 100644
--- a/service/java/com/android/server/wifi/ClientModeManager.java
+++ b/service/java/com/android/server/wifi/ClientModeManager.java
@@ -19,6 +19,11 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerExecutor;
@@ -28,6 +33,7 @@ import android.os.PersistableBundle;
import android.os.UserHandle;
import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.ims.ImsException;
@@ -45,9 +51,11 @@ import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.wifi.WifiNative.InterfaceCallback;
import com.android.server.wifi.util.WifiHandler;
+import com.android.wifi.resources.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.List;
/**
* Manager WiFi in Client Mode where we connect to configured networks.
@@ -71,6 +79,7 @@ public class ClientModeManager implements ActiveModeManager {
private @Role int mRole = ROLE_UNSPECIFIED;
private DeferStopHandler mDeferStopHandler;
private int mTargetRole = ROLE_UNSPECIFIED;
+ private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
ClientModeManager(Context context, @NonNull Looper looper, Clock clock, WifiNative wifiNative,
Listener listener, WifiMetrics wifiMetrics, SarManager sarManager,
@@ -120,6 +129,8 @@ public class ClientModeManager implements ActiveModeManager {
private final Runnable mRunnable = () -> continueToStopWifi();
private int mMaximumDeferringTimeMillis = 0;
private long mDeferringStartTimeMillis = 0;
+ private NetworkRequest mImsRequest = null;
+ private ConnectivityManager mConnectivityManager = null;
private RegistrationManager.RegistrationCallback mImsRegistrationCallback =
new RegistrationManager.RegistrationCallback() {
@@ -136,10 +147,40 @@ public class ClientModeManager implements ActiveModeManager {
@Override
public void onUnregistered(ImsReasonInfo imsReasonInfo) {
Log.d(TAG, "on IMS unregistered");
- if (mIsDeferring) continueToStopWifi();
+ // Wait for onLost in NetworkCallback
}
};
+ private NetworkCallback mImsNetworkCallback = new NetworkCallback() {
+ private int mRegisteredImsNetworkCount = 0;
+ @Override
+ public void onAvailable(Network network) {
+ synchronized (this) {
+ Log.d(TAG, "IMS network available: " + network);
+ mRegisteredImsNetworkCount++;
+ }
+ }
+
+ @Override
+ public void onLost(Network network) {
+ synchronized (this) {
+ Log.d(TAG, "IMS network lost: " + network
+ + " ,isDeferring: " + mIsDeferring
+ + " ,registered IMS network count: " + mRegisteredImsNetworkCount);
+ mRegisteredImsNetworkCount--;
+ if (mIsDeferring && mRegisteredImsNetworkCount <= 0) {
+ mRegisteredImsNetworkCount = 0;
+ // Add delay for targets where IMS PDN down at modem takes additional delay.
+ int delay = mContext.getResources()
+ .getInteger(R.integer.config_wifiDelayDisconnectOnImsLostMs);
+ if (delay == 0 || !postDelayed(mRunnable, delay)) {
+ continueToStopWifi();
+ }
+ }
+ }
+ }
+ };
+
DeferStopHandler(String tag, Looper looper) {
super(tag, looper);
mLooper = looper;
@@ -156,8 +197,7 @@ public class ClientModeManager implements ActiveModeManager {
return;
}
- mImsMmTelManager = ImsMmTelManager.createForSubscriptionId(
- SubscriptionManager.getDefaultVoiceSubscriptionId());
+ mImsMmTelManager = ImsMmTelManager.createForSubscriptionId(mActiveSubId);
if (mImsMmTelManager == null || !postDelayed(mRunnable, delayMs)) {
// if no delay or failed to add runnable, stop Wifi immediately.
continueToStopWifi();
@@ -166,7 +206,7 @@ public class ClientModeManager implements ActiveModeManager {
mIsDeferring = true;
Log.d(TAG, "Start DeferWifiOff handler with deferring time "
- + delayMs + " ms.");
+ + delayMs + " ms for subId: " + mActiveSubId);
try {
mImsMmTelManager.registerImsRegistrationCallback(
new HandlerExecutor(new Handler(mLooper)),
@@ -174,7 +214,19 @@ public class ClientModeManager implements ActiveModeManager {
} catch (RuntimeException | ImsException e) {
Log.e(TAG, "registerImsRegistrationCallback failed", e);
continueToStopWifi();
+ return;
}
+
+ mImsRequest = new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .build();
+
+ mConnectivityManager =
+ (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ mConnectivityManager.registerNetworkCallback(mImsRequest, mImsNetworkCallback,
+ new Handler(mLooper));
}
private void continueToStopWifi() {
@@ -212,6 +264,11 @@ public class ClientModeManager implements ActiveModeManager {
Log.e(TAG, "unregisterImsRegistrationCallback failed", e);
}
}
+
+ if (mConnectivityManager != null) {
+ mConnectivityManager.unregisterNetworkCallback(mImsNetworkCallback);
+ }
+
mIsDeferring = false;
}
}
@@ -220,13 +277,35 @@ public class ClientModeManager implements ActiveModeManager {
* Get deferring time before turning off WiFi.
*/
private int getWifiOffDeferringTimeMs() {
- int defaultVoiceSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
- if (defaultVoiceSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ SubscriptionManager subscriptionManager = (SubscriptionManager) mContext.getSystemService(
+ Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ if (subscriptionManager == null) {
+ return 0;
+ }
+
+ List<SubscriptionInfo> subInfoList = subscriptionManager.getActiveSubscriptionInfoList();
+ if (subInfoList == null) {
+ return 0;
+ }
+
+ // Get the maximum delay for the active subscription latched on IWLAN.
+ int maxDelay = 0;
+ for (SubscriptionInfo subInfo : subInfoList) {
+ int curDelay = getWifiOffDeferringTimeMs(subInfo.getSubscriptionId());
+ if (curDelay > maxDelay) {
+ maxDelay = curDelay;
+ mActiveSubId = subInfo.getSubscriptionId();
+ }
+ }
+ return maxDelay;
+ }
+
+ private int getWifiOffDeferringTimeMs(int subId) {
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return 0;
}
- ImsMmTelManager imsMmTelManager = ImsMmTelManager.createForSubscriptionId(
- defaultVoiceSubId);
+ ImsMmTelManager imsMmTelManager = ImsMmTelManager.createForSubscriptionId(subId);
// If no wifi calling, no delay
if (!imsMmTelManager.isAvailable(
MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
@@ -236,7 +315,7 @@ public class ClientModeManager implements ActiveModeManager {
TelephonyManager defaultVoiceTelephonyManager =
mContext.getSystemService(TelephonyManager.class)
- .createForSubscriptionId(defaultVoiceSubId);
+ .createForSubscriptionId(subId);
// if LTE is available, no delay needed as IMS will be registered over LTE
if (defaultVoiceTelephonyManager.getVoiceNetworkType()
== TelephonyManager.NETWORK_TYPE_LTE) {
@@ -245,7 +324,7 @@ public class ClientModeManager implements ActiveModeManager {
CarrierConfigManager configManager =
(CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
- PersistableBundle config = configManager.getConfigForSubId(defaultVoiceSubId);
+ PersistableBundle config = configManager.getConfigForSubId(subId);
return (config != null)
? config.getInt(CarrierConfigManager.Ims.KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT)
: 0;
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index 4451f7c12..881373807 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -430,4 +430,7 @@
The scan interval backs off from this initial interval on subsequent scans.
This scan is performed when screen is off and disconnected. -->
<integer translatable="false" name="config_wifiStationaryPnoScanIntervalMillis">60000</integer>
+
+ <!-- integer indicating additional disconnect delay (in ms) after IMS onLost() indication is received -->
+ <integer translatable="false" name="config_wifiDelayDisconnectOnImsLostMs">0</integer>
</resources>
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index 9e0a18d7d..7b77da512 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -133,6 +133,7 @@
<item type="bool" name="config_wifiSoftapAcsIncludeDfs" />
<item type="integer" name="config_wifiMovingPnoScanIntervalMillis" />
<item type="integer" name="config_wifiStationaryPnoScanIntervalMillis" />
+ <item type="integer" name="config_wifiDelayDisconnectOnImsLostMs" />
<!-- Params from config.xml that can be overlayed -->
<!-- Params from strings.xml that can be overlayed -->