aboutsummaryrefslogtreecommitdiff
path: root/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/com/android/internal/telephony/data/PhoneSwitcher.java')
-rw-r--r--src/java/com/android/internal/telephony/data/PhoneSwitcher.java433
1 files changed, 64 insertions, 369 deletions
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index d2fdf4abb9..cf1a47d3f6 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -18,6 +18,7 @@ package com.android.internal.telephony.data;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.telephony.CarrierConfigManager.KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG;
+import static android.telephony.SubscriptionManager.DEFAULT_PHONE_INDEX;
import static android.telephony.SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.INVALID_PHONE_INDEX;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -27,14 +28,10 @@ import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_VALIDATIO
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
-
import static java.util.Arrays.copyOf;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -50,7 +47,6 @@ import android.net.NetworkSpecifier;
import android.net.TelephonyNetworkSpecifier;
import android.os.AsyncResult;
import android.os.Build;
-import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -58,10 +54,7 @@ import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
-import android.provider.Settings;
-import android.telephony.AccessNetworkConstants;
import android.telephony.CarrierConfigManager;
-import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneCapability;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionInfo;
@@ -79,6 +72,7 @@ import android.util.Log;
import com.android.ims.ImsException;
import com.android.ims.ImsManager;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.Call;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.ISetOpportunisticDataCallback;
import com.android.internal.telephony.IccCard;
@@ -96,7 +90,6 @@ import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent.OnDeman
import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.subscription.SubscriptionManagerService.WatchedInt;
-import com.android.internal.telephony.util.NotificationChannelController;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;
@@ -121,21 +114,6 @@ public class PhoneSwitcher extends Handler {
private static final String LOG_TAG = "PhoneSwitcher";
protected static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
- /** Fragment "key" argument passed thru {@link #SETTINGS_EXTRA_SHOW_FRAGMENT_ARGUMENTS} */
- private static final String SETTINGS_EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
- /**
- * When starting this activity, this extra can also be specified to supply a Bundle of arguments
- * to pass to that fragment when it is instantiated during the initial creation of the activity.
- */
- private static final String SETTINGS_EXTRA_SHOW_FRAGMENT_ARGUMENTS =
- ":settings:show_fragment_args";
- /** The res Id of the auto data switch fragment in settings. **/
- private static final String AUTO_DATA_SWITCH_SETTING_R_ID = "auto_data_switch";
- /** Notification tag **/
- private static final String AUTO_DATA_SWITCH_NOTIFICATION_TAG = "auto_data_switch";
- /** Notification ID **/
- private static final int AUTO_DATA_SWITCH_NOTIFICATION_ID = 1;
-
private static final int MODEM_COMMAND_RETRY_PERIOD_MS = 5000;
// After the emergency call ends, wait for a few seconds to see if we enter ECBM before starting
// the countdown to remove the emergency DDS override.
@@ -257,9 +235,6 @@ public class PhoneSwitcher extends Handler {
// its value will be DEFAULT_SUBSCRIPTION_ID.
private int mAutoSelectedDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
- /** The count of consecutive auto switch validation failure **/
- private int mAutoSwitchRetryFailedCount = 0;
-
// The phone ID that has an active voice call. If set, and its mobile data setting is on,
// it will become the mPreferredDataPhoneId.
protected int mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX;
@@ -302,10 +277,10 @@ public class PhoneSwitcher extends Handler {
// ECBM, which is detected by EVENT_EMERGENCY_TOGGLE.
private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 109;
private static final int EVENT_NETWORK_VALIDATION_DONE = 110;
- private static final int EVENT_EVALUATE_AUTO_SWITCH = 111;
+
private static final int EVENT_MODEM_COMMAND_DONE = 112;
private static final int EVENT_MODEM_COMMAND_RETRY = 113;
- private static final int EVENT_SERVICE_STATE_CHANGED = 114;
+
// An emergency call is about to be originated and requires the DDS to be overridden.
// Uses EVENT_PRECISE_CALL_STATE_CHANGED message to start countdown to finish override defined
// in mEmergencyOverride. If EVENT_PRECISE_CALL_STATE_CHANGED does not come in
@@ -318,7 +293,6 @@ public class PhoneSwitcher extends Handler {
private static final int EVENT_NETWORK_AVAILABLE = 118;
private static final int EVENT_PROCESS_SIM_STATE_CHANGE = 119;
private static final int EVENT_IMS_RADIO_TECH_CHANGED = 120;
- private static final int EVENT_MEETS_AUTO_DATA_SWITCH_STATE = 121;
// List of events triggers re-evaluations
private static final String EVALUATION_REASON_RADIO_ON = "EVENT_RADIO_ON";
@@ -343,23 +317,9 @@ public class PhoneSwitcher extends Handler {
private List<Set<CommandException.Error>> mCurrentDdsSwitchFailure;
- /**
- * {@code true} if requires ping test before switching preferred data modem; otherwise, switch
- * even if ping test fails.
- */
- private boolean mRequirePingTestBeforeDataSwitch = true;
-
- /**
- * Time threshold in ms to define a internet connection status to be stable(e.g. out of service,
- * in service, wifi is the default active network.etc), while -1 indicates auto switch
- * feature disabled.
- */
- private long mAutoDataSwitchAvailabilityStabilityTimeThreshold = -1;
-
- /**
- * The maximum number of retries when a validation for switching failed.
- */
- private int mAutoDataSwitchValidationMaxRetry;
+ private AutoDataSwitchController mAutoDataSwitchController;
+ private AutoDataSwitchController.AutoDataSwitchControllerCallback
+ mAutoDataSwitchCallback;
/** Data settings manager callback. Key is the phone id. */
private final @NonNull Map<Integer, DataSettingsManagerCallback> mDataSettingsManagerCallbacks =
@@ -368,12 +328,10 @@ public class PhoneSwitcher extends Handler {
private class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback {
public int mExpectedSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
public int mSwitchReason = TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN;
- public boolean isDefaultNetworkOnCellular = false;
@Override
public void onCapabilitiesChanged(Network network,
NetworkCapabilities networkCapabilities) {
if (networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
- isDefaultNetworkOnCellular = true;
if (SubscriptionManager.isValidSubscriptionId(mExpectedSubId)
&& mExpectedSubId == getSubIdFromNetworkSpecifier(
networkCapabilities.getNetworkSpecifier())) {
@@ -384,22 +342,13 @@ public class PhoneSwitcher extends Handler {
mExpectedSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mSwitchReason = TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN;
}
- } else {
- if (isDefaultNetworkOnCellular) {
- // non-cellular transport is active
- isDefaultNetworkOnCellular = false;
- log("default network is active on non cellular");
- evaluateIfAutoSwitchIsNeeded();
- }
}
+ mAutoDataSwitchController.updateDefaultNetworkCapabilities(networkCapabilities);
}
@Override
public void onLost(Network network) {
- // try find an active sub to switch to
- if (!hasMessages(EVENT_EVALUATE_AUTO_SWITCH)) {
- sendEmptyMessage(EVENT_EVALUATE_AUTO_SWITCH);
- }
+ mAutoDataSwitchController.updateDefaultNetworkCapabilities(null);
}
}
@@ -551,8 +500,6 @@ public class PhoneSwitcher extends Handler {
}});
phone.getDataSettingsManager().registerCallback(
mDataSettingsManagerCallbacks.get(phoneId));
- phone.getServiceStateTracker().registerForServiceStateChanged(this,
- EVENT_SERVICE_STATE_CHANGED, phoneId);
registerForImsRadioTechChange(context, phoneId);
}
Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
@@ -563,8 +510,6 @@ public class PhoneSwitcher extends Handler {
PhoneFactory.getPhone(0).mCi.registerForOn(this, EVENT_RADIO_ON, null);
}
- readDeviceResourceConfig();
-
TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
telephonyRegistryManager.addOnSubscriptionsChangedListener(
@@ -573,6 +518,36 @@ public class PhoneSwitcher extends Handler {
mConnectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ mAutoDataSwitchCallback = new AutoDataSwitchController.AutoDataSwitchControllerCallback() {
+ @Override
+ public void onRequireValidation(int targetPhoneId, boolean needValidation) {
+ int targetSubId = targetPhoneId == DEFAULT_PHONE_INDEX
+ ? DEFAULT_SUBSCRIPTION_ID
+ : mSubscriptionManagerService.getSubId(targetPhoneId);
+ PhoneSwitcher.this.validate(targetSubId, needValidation,
+ DataSwitch.Reason.DATA_SWITCH_REASON_AUTO, null);
+ }
+
+ @Override
+ public void onRequireImmediatelySwitchToPhone(int targetPhoneId,
+ @AutoDataSwitchController.AutoDataSwitchEvaluationReason int reason) {
+ PhoneSwitcher.this.mAutoSelectedDataSubId =
+ targetPhoneId == DEFAULT_PHONE_INDEX
+ ? DEFAULT_SUBSCRIPTION_ID
+ : mSubscriptionManagerService.getSubId(targetPhoneId);
+ PhoneSwitcher.this.evaluateIfImmediateDataSwitchIsNeeded(
+ AutoDataSwitchController.evaluationReasonToString(reason),
+ DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
+ }
+
+ @Override
+ public void onRequireCancelAnyPendingAutoSwitchValidation() {
+ PhoneSwitcher.this.cancelPendingAutoDataSwitchValidation();
+ }
+ };
+ mAutoDataSwitchController = new AutoDataSwitchController(context, looper, this,
+ mAutoDataSwitchCallback);
+
mContext.registerReceiver(mDefaultDataChangedReceiver,
new IntentFilter(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED));
@@ -675,19 +650,6 @@ public class PhoneSwitcher extends Handler {
onEvaluate(REQUESTS_UNCHANGED, "subscription changed");
break;
}
- case EVENT_SERVICE_STATE_CHANGED: {
- AsyncResult ar = (AsyncResult) msg.obj;
- final int phoneId = (int) ar.userObj;
- onServiceStateChanged(phoneId);
- break;
- }
- case EVENT_MEETS_AUTO_DATA_SWITCH_STATE: {
- final int targetSubId = msg.arg1;
- final boolean needValidation = (boolean) msg.obj;
- validate(targetSubId, needValidation,
- DataSwitch.Reason.DATA_SWITCH_REASON_AUTO, null);
- break;
- }
case EVENT_PRIMARY_DATA_SUB_CHANGED: {
evaluateIfImmediateDataSwitchIsNeeded("primary data sub changed",
DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
@@ -718,9 +680,6 @@ public class PhoneSwitcher extends Handler {
onEvaluate(REQUESTS_CHANGED, "emergencyToggle");
break;
}
- case EVENT_EVALUATE_AUTO_SWITCH:
- evaluateIfAutoSwitchIsNeeded();
- break;
case EVENT_RADIO_CAPABILITY_CHANGED: {
final int phoneId = msg.arg1;
sendRilCommands(phoneId);
@@ -792,7 +751,8 @@ public class PhoneSwitcher extends Handler {
DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
if (!isAnyVoiceCallActiveOnDevice()) {
// consider auto switch on hang up all voice call
- evaluateIfAutoSwitchIsNeeded();
+ mAutoDataSwitchController.evaluateAutoDataSwitch(
+ AutoDataSwitchController.EVALUATION_REASON_VOICE_CALL_END);
}
break;
}
@@ -892,33 +852,19 @@ public class PhoneSwitcher extends Handler {
} else if (TelephonyManager.SIM_STATE_LOADED == simState) {
if (mCurrentDdsSwitchFailure.get(slotIndex).contains(
CommandException.Error.INVALID_SIM_STATE)
- && (TelephonyManager.SIM_STATE_LOADED == simState)
&& isSimApplicationReady(slotIndex)) {
sendRilCommands(slotIndex);
}
// SIM loaded after subscriptions slot mapping are done. Evaluate for auto
// data switch.
- sendEmptyMessage(EVENT_EVALUATE_AUTO_SWITCH);
+ mAutoDataSwitchController.evaluateAutoDataSwitch(
+ AutoDataSwitchController.EVALUATION_REASON_SIM_LOADED);
}
break;
}
}
}
- /**
- * Read the default device config from any default phone because the resource config are per
- * device. No need to register callback for the same reason.
- */
- private void readDeviceResourceConfig() {
- Phone phone = PhoneFactory.getDefaultPhone();
- DataConfigManager dataConfig = phone.getDataNetworkController().getDataConfigManager();
- mRequirePingTestBeforeDataSwitch = dataConfig.isPingTestBeforeAutoDataSwitchRequired();
- mAutoDataSwitchAvailabilityStabilityTimeThreshold =
- dataConfig.getAutoDataSwitchAvailabilityStabilityTimeThreshold();
- mAutoDataSwitchValidationMaxRetry =
- dataConfig.getAutoDataSwitchValidationMaxRetry();
- }
-
private synchronized void onMultiSimConfigChanged(int activeModemCount) {
// No change.
if (mActiveModemCount == activeModemCount) return;
@@ -958,13 +904,13 @@ public class PhoneSwitcher extends Handler {
});
phone.getDataSettingsManager().registerCallback(
mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
- phone.getServiceStateTracker().registerForServiceStateChanged(this,
- EVENT_SERVICE_STATE_CHANGED, phoneId);
Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
mCurrentDdsSwitchFailure.add(ddsFailure);
registerForImsRadioTechChange(mContext, phoneId);
}
+
+ mAutoDataSwitchController.onMultiSimConfigChanged(activeModemCount);
}
/**
@@ -973,14 +919,14 @@ public class PhoneSwitcher extends Handler {
* 2. OR user changed auto data switch feature
*/
private void onDataEnabledChanged() {
- logl("user changed data related settings");
if (isAnyVoiceCallActiveOnDevice()) {
// user changed data related settings during call, switch or turn off immediately
evaluateIfImmediateDataSwitchIsNeeded(
"user changed data settings during call",
DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
} else {
- evaluateIfAutoSwitchIsNeeded();
+ mAutoDataSwitchController.evaluateAutoDataSwitch(AutoDataSwitchController
+ .EVALUATION_REASON_DATA_SETTINGS_CHANGED);
}
}
@@ -1069,134 +1015,9 @@ public class PhoneSwitcher extends Handler {
}
/**
- * Called when service state changed.
- */
- private void onServiceStateChanged(int phoneId) {
- Phone phone = findPhoneById(phoneId);
- if (phone != null) {
- int newRegState = phone.getServiceState()
- .getNetworkRegistrationInfo(
- NetworkRegistrationInfo.DOMAIN_PS,
- AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .getRegistrationState();
- if (newRegState != mPhoneStates[phoneId].dataRegState) {
- mPhoneStates[phoneId].dataRegState = newRegState;
- logl("onServiceStateChanged: phoneId:" + phoneId + " dataReg-> "
- + NetworkRegistrationInfo.registrationStateToString(newRegState));
- if (!hasMessages(EVENT_EVALUATE_AUTO_SWITCH)) {
- sendEmptyMessage(EVENT_EVALUATE_AUTO_SWITCH);
- }
- }
- }
- }
-
- /**
- * Evaluate if auto switch is suitable at the moment.
- */
- private void evaluateIfAutoSwitchIsNeeded() {
- // auto data switch feature is disabled from server
- if (mAutoDataSwitchAvailabilityStabilityTimeThreshold < 0) return;
- // check is valid DSDS
- if (!isActiveSubId(mPrimaryDataSubId) || mSubscriptionManagerService
- .getActiveSubIdList(true).length <= 1) {
- return;
- }
-
- Phone primaryDataPhone = getPhoneBySubId(mPrimaryDataSubId);
- if (primaryDataPhone == null) {
- loge("evaluateIfAutoSwitchIsNeeded: cannot find primary data phone. subId="
- + mPrimaryDataSubId);
- return;
- }
-
- int primaryPhoneId = primaryDataPhone.getPhoneId();
- log("evaluateIfAutoSwitchIsNeeded: primaryPhoneId: " + primaryPhoneId
- + " preferredPhoneId: " + mPreferredDataPhoneId);
- Phone secondaryDataPhone;
-
- if (mPreferredDataPhoneId == primaryPhoneId) {
- // on primary data sub
-
- int candidateSubId = getAutoSwitchTargetSubIdIfExists();
- if (candidateSubId != INVALID_SUBSCRIPTION_ID) {
- startAutoDataSwitchStabilityCheck(candidateSubId, mRequirePingTestBeforeDataSwitch);
- } else {
- cancelPendingAutoDataSwitch();
- }
- } else if ((secondaryDataPhone = findPhoneById(mPreferredDataPhoneId)) != null) {
- // on secondary data sub
-
- if (!primaryDataPhone.isUserDataEnabled()
- || !secondaryDataPhone.isDataAllowed()) {
- // immediately switch back if user setting changes
- mAutoSelectedDataSubId = DEFAULT_SUBSCRIPTION_ID;
- evaluateIfImmediateDataSwitchIsNeeded("User disabled data settings",
- DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
- return;
- }
-
- NetworkCapabilities defaultNetworkCapabilities = mConnectivityManager
- .getNetworkCapabilities(mConnectivityManager.getActiveNetwork());
- if (defaultNetworkCapabilities != null && !defaultNetworkCapabilities
- .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- log("evaluateIfAutoSwitchIsNeeded: "
- + "Default network is active on non-cellular transport");
- startAutoDataSwitchStabilityCheck(DEFAULT_SUBSCRIPTION_ID, false);
- return;
- }
-
- if (mPhoneStates[secondaryDataPhone.getPhoneId()].dataRegState
- != NetworkRegistrationInfo.REGISTRATION_STATE_HOME) {
- // secondary phone lost its HOME availability
- startAutoDataSwitchStabilityCheck(DEFAULT_SUBSCRIPTION_ID, false);
- return;
- }
-
- if (isInService(mPhoneStates[primaryPhoneId])) {
- // primary becomes available
- startAutoDataSwitchStabilityCheck(DEFAULT_SUBSCRIPTION_ID,
- mRequirePingTestBeforeDataSwitch);
- return;
- }
-
- // cancel any previous attempts of switching back to primary
- cancelPendingAutoDataSwitch();
- }
- }
-
- /**
- * @param phoneState The phone state to check
- * @return {@code true} if the phone state is considered in service.
- */
- private boolean isInService(@NonNull PhoneState phoneState) {
- return phoneState.dataRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
- || phoneState.dataRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
- }
-
- /**
- * Called when the current environment suits auto data switch.
- * Start pre-switch validation if the current environment suits auto data switch for
- * {@link #mAutoDataSwitchAvailabilityStabilityTimeThreshold} MS.
- * @param targetSubId the target sub Id.
- * @param needValidation {@code true} if validation is needed.
- */
- private void startAutoDataSwitchStabilityCheck(int targetSubId, boolean needValidation) {
- log("startAutoDataSwitchStabilityCheck: targetSubId=" + targetSubId
- + " needValidation=" + needValidation);
- if (!hasMessages(EVENT_MEETS_AUTO_DATA_SWITCH_STATE, needValidation)) {
- sendMessageDelayed(obtainMessage(EVENT_MEETS_AUTO_DATA_SWITCH_STATE, targetSubId,
- 0/*placeholder*/,
- needValidation),
- mAutoDataSwitchAvailabilityStabilityTimeThreshold);
- }
- }
-
- /**
* Cancel any auto switch attempts when the current environment is not suitable for auto switch.
*/
- private void cancelPendingAutoDataSwitch() {
- mAutoSwitchRetryFailedCount = 0;
- removeMessages(EVENT_MEETS_AUTO_DATA_SWITCH_STATE);
+ private void cancelPendingAutoDataSwitchValidation() {
if (mValidator.isValidating()) {
mValidator.stopValidation();
@@ -1207,56 +1028,6 @@ public class PhoneSwitcher extends Handler {
}
}
- /**
- * Called when consider switching from primary default data sub to another data sub.
- * @return the target subId if a suitable candidate is found, otherwise return
- * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
- */
- private int getAutoSwitchTargetSubIdIfExists() {
- Phone primaryDataPhone = getPhoneBySubId(mPrimaryDataSubId);
- if (primaryDataPhone == null) {
- log("getAutoSwitchTargetSubId: no sim loaded");
- return INVALID_SUBSCRIPTION_ID;
- }
-
- int primaryPhoneId = primaryDataPhone.getPhoneId();
-
- if (!primaryDataPhone.isUserDataEnabled()) {
- log("getAutoSwitchTargetSubId: user disabled data");
- return INVALID_SUBSCRIPTION_ID;
- }
-
- NetworkCapabilities defaultNetworkCapabilities = mConnectivityManager
- .getNetworkCapabilities(mConnectivityManager.getActiveNetwork());
- if (defaultNetworkCapabilities != null && !defaultNetworkCapabilities
- .hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
- // Exists other active default transport
- log("getAutoSwitchTargetSubId: Default network is active on non-cellular transport");
- return INVALID_SUBSCRIPTION_ID;
- }
-
- // check whether primary and secondary signal status worth switching
- if (isInService(mPhoneStates[primaryPhoneId])) {
- log("getAutoSwitchTargetSubId: primary is in service");
- return INVALID_SUBSCRIPTION_ID;
- }
- for (int phoneId = 0; phoneId < mPhoneStates.length; phoneId++) {
- if (phoneId != primaryPhoneId) {
- // the alternative phone must have HOME availability
- if (mPhoneStates[phoneId].dataRegState
- == NetworkRegistrationInfo.REGISTRATION_STATE_HOME) {
- log("getAutoSwitchTargetSubId: found phone " + phoneId + " in HOME service");
- Phone secondaryDataPhone = findPhoneById(phoneId);
- if (secondaryDataPhone != null && // check auto switch feature enabled
- secondaryDataPhone.isDataAllowed()) {
- return secondaryDataPhone.getSubId();
- }
- }
- }
- }
- return INVALID_SUBSCRIPTION_ID;
- }
-
private TelephonyManager getTm() {
return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
}
@@ -1415,8 +1186,6 @@ public class PhoneSwitcher extends Handler {
protected static class PhoneState {
public volatile boolean active = false;
- public @NetworkRegistrationInfo.RegistrationState int dataRegState =
- NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
public long lastRequested = 0;
}
@@ -1836,14 +1605,12 @@ public class PhoneSwitcher extends Handler {
if (!isActiveSubId(subId)) {
logl("confirmSwitch: subId " + subId + " is no longer active");
resultForCallBack = SET_OPPORTUNISTIC_SUB_INACTIVE_SUBSCRIPTION;
- mAutoSwitchRetryFailedCount = 0;
} else if (!confirm) {
resultForCallBack = SET_OPPORTUNISTIC_SUB_VALIDATION_FAILED;
// retry for auto data switch validation failure
if (mLastSwitchPreferredDataReason == DataSwitch.Reason.DATA_SWITCH_REASON_AUTO) {
- scheduleAutoSwitchRetryEvaluation();
- mAutoSwitchRetryFailedCount++;
+ mAutoDataSwitchController.evaluateRetryOnValidationFailed();
}
} else {
if (subId == mPrimaryDataSubId) {
@@ -1852,7 +1619,7 @@ public class PhoneSwitcher extends Handler {
setAutoSelectedDataSubIdInternal(subId);
}
resultForCallBack = SET_OPPORTUNISTIC_SUB_SUCCESS;
- mAutoSwitchRetryFailedCount = 0;
+ mAutoDataSwitchController.resetFailedCount();
}
// Trigger callback if needed
@@ -1861,23 +1628,6 @@ public class PhoneSwitcher extends Handler {
mPendingSwitchSubId = INVALID_SUBSCRIPTION_ID;
}
- /**
- * Schedule auto data switch evaluation retry if haven't reached the max retry count.
- */
- private void scheduleAutoSwitchRetryEvaluation() {
- if (mAutoSwitchRetryFailedCount < mAutoDataSwitchValidationMaxRetry) {
- if (!hasMessages(EVENT_EVALUATE_AUTO_SWITCH)) {
- sendMessageDelayed(obtainMessage(EVENT_EVALUATE_AUTO_SWITCH),
- mAutoDataSwitchAvailabilityStabilityTimeThreshold
- << mAutoSwitchRetryFailedCount);
- }
- } else {
- logl("scheduleAutoSwitchEvaluation: reached max auto switch retry count "
- + mAutoDataSwitchValidationMaxRetry);
- mAutoSwitchRetryFailedCount = 0;
- }
- }
-
private void onNetworkAvailable(int subId, Network network) {
log("onNetworkAvailable: on subId " + subId);
// Do nothing unless pending switch matches target subId and it doesn't require
@@ -1928,8 +1678,14 @@ public class PhoneSwitcher extends Handler {
}
// A phone in voice call might trigger data being switched to it.
+ // Exclude dialing to give modem time to process an EMC first before dealing with DDS switch
+ // Include alerting because modem RLF leads to delay in switch, so carrier required to
+ // switch in alerting phase.
+ // TODO: check ringing call for vDADA
return (!phone.getBackgroundCall().isIdle()
- || !phone.getForegroundCall().isIdle());
+ && phone.getBackgroundCall().getState() != Call.State.DIALING)
+ || (!phone.getForegroundCall().isIdle()
+ && phone.getForegroundCall().getState() != Call.State.DIALING);
}
private void updateHalCommandToUse() {
@@ -2062,8 +1818,7 @@ public class PhoneSwitcher extends Handler {
for (int i = 0; i < mActiveModemCount; i++) {
PhoneState ps = mPhoneStates[i];
c.setTimeInMillis(ps.lastRequested);
- pw.println("PhoneId(" + i + ") active=" + ps.active + ", dataRegState="
- + NetworkRegistrationInfo.registrationStateToString(ps.dataRegState)
+ pw.println("PhoneId(" + i + ") active=" + ps.active
+ ", lastRequest="
+ (ps.lastRequested == 0 ? "never" :
String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)));
@@ -2081,10 +1836,6 @@ public class PhoneSwitcher extends Handler {
pw.println("mActiveModemCount=" + mActiveModemCount);
pw.println("mPhoneIdInVoiceCall=" + mPhoneIdInVoiceCall);
pw.println("mCurrentDdsSwitchFailure=" + mCurrentDdsSwitchFailure);
- pw.println("mAutoDataSwitchAvailabilityStabilityTimeThreshold="
- + mAutoDataSwitchAvailabilityStabilityTimeThreshold);
- pw.println("mAutoDataSwitchValidationMaxRetry=" + mAutoDataSwitchValidationMaxRetry);
- pw.println("mRequirePingTestBeforeDataSwitch=" + mRequirePingTestBeforeDataSwitch);
pw.println("mLastSwitchPreferredDataReason="
+ switchReasonToString(mLastSwitchPreferredDataReason));
pw.println("mDisplayedAutoSwitchNotification=" + mDisplayedAutoSwitchNotification);
@@ -2092,6 +1843,7 @@ public class PhoneSwitcher extends Handler {
pw.increaseIndent();
mLocalLog.dump(fd, pw, args);
pw.decreaseIndent();
+ mAutoDataSwitchController.dump(fd, pw, args);
pw.decreaseIndent();
}
@@ -2130,72 +1882,15 @@ public class PhoneSwitcher extends Handler {
phoneId), MODEM_COMMAND_RETRY_PERIOD_MS);
return;
}
- if (commandSuccess) logl("onDdsSwitchResponse: DDS switch success on phoneId = " + phoneId);
+ if (commandSuccess) {
+ logl("onDdsSwitchResponse: DDS switch success on phoneId = " + phoneId);
+ mAutoDataSwitchController.displayAutoDataSwitchNotification(phoneId,
+ mLastSwitchPreferredDataReason == DataSwitch.Reason.DATA_SWITCH_REASON_AUTO);
+ }
mCurrentDdsSwitchFailure.get(phoneId).clear();
// Notify all registrants
mActivePhoneRegistrants.notifyRegistrants();
notifyPreferredDataSubIdChanged();
- displayAutoDataSwitchNotification();
- }
-
- /**
- * Display a notification the first time auto data switch occurs.
- */
- private void displayAutoDataSwitchNotification() {
- NotificationManager notificationManager = (NotificationManager)
- mContext.getSystemService(Context.NOTIFICATION_SERVICE);
-
- if (mDisplayedAutoSwitchNotification) {
- // cancel posted notification if any exist
- log("displayAutoDataSwitchNotification: canceling any notifications for subId "
- + mAutoSelectedDataSubId);
- notificationManager.cancel(AUTO_DATA_SWITCH_NOTIFICATION_TAG,
- AUTO_DATA_SWITCH_NOTIFICATION_ID);
- return;
- }
- // proceed only the first time auto data switch occurs, which includes data during call
- if (mLastSwitchPreferredDataReason != DataSwitch.Reason.DATA_SWITCH_REASON_AUTO) {
- log("displayAutoDataSwitchNotification: Ignore DDS switch due to "
- + switchReasonToString(mLastSwitchPreferredDataReason));
- return;
- }
- SubscriptionInfo subInfo = mSubscriptionManagerService
- .getSubscriptionInfo(mAutoSelectedDataSubId);
- if (subInfo == null || subInfo.isOpportunistic()) {
- loge("displayAutoDataSwitchNotification: mAutoSelectedDataSubId="
- + mAutoSelectedDataSubId + " unexpected subInfo " + subInfo);
- return;
- }
- logl("displayAutoDataSwitchNotification: display for subId=" + mAutoSelectedDataSubId);
- // "Mobile network settings" screen / dialog
- Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS);
- final Bundle fragmentArgs = new Bundle();
- // Special contract for Settings to highlight permission row
- fragmentArgs.putString(SETTINGS_EXTRA_FRAGMENT_ARG_KEY, AUTO_DATA_SWITCH_SETTING_R_ID);
- intent.putExtra(Settings.EXTRA_SUB_ID, mAutoSelectedDataSubId);
- intent.putExtra(SETTINGS_EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArgs);
- PendingIntent contentIntent = PendingIntent.getActivity(
- mContext, mAutoSelectedDataSubId, intent, PendingIntent.FLAG_IMMUTABLE);
-
- CharSequence activeCarrierName = subInfo.getDisplayName();
- CharSequence contentTitle = mContext.getString(
- com.android.internal.R.string.auto_data_switch_title, activeCarrierName);
- CharSequence contentText = mContext.getText(
- com.android.internal.R.string.auto_data_switch_content);
-
- final Notification notif = new Notification.Builder(mContext)
- .setContentTitle(contentTitle)
- .setContentText(contentText)
- .setSmallIcon(android.R.drawable.stat_sys_warning)
- .setColor(mContext.getResources().getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .setChannelId(NotificationChannelController.CHANNEL_ID_MOBILE_DATA_STATUS)
- .setContentIntent(contentIntent)
- .setStyle(new Notification.BigTextStyle().bigText(contentText))
- .build();
- notificationManager.notify(AUTO_DATA_SWITCH_NOTIFICATION_TAG,
- AUTO_DATA_SWITCH_NOTIFICATION_ID, notif);
- mDisplayedAutoSwitchNotification = true;
}
private boolean isPhoneIdValidForRetry(int phoneId) {