Merge "Import translations. DO NOT MERGE ANYWHERE" into udc-dev
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 14db930..73b61b6 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -40,8 +40,6 @@
import com.android.internal.telephony.CallManager;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaDisplayInfoRec;
import com.android.internal.telephony.cdma.CdmaInformationRecords.CdmaSignalInfoRec;
import com.android.internal.telephony.cdma.SignalToneUtil;
@@ -489,16 +487,9 @@
}
public void updatePhoneStateListeners(boolean isRefresh, int updateType, int subIdToUpdate) {
- List<SubscriptionInfo> subInfos;
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- subInfos = SubscriptionManagerService.getInstance()
- .getActiveSubscriptionInfoList(mApplication.getOpPackageName(),
- mApplication.getAttributionTag());
- } else {
- subInfos = SubscriptionController.getInstance()
- .getActiveSubscriptionInfoList(mApplication.getOpPackageName(),
- mApplication.getAttributionTag());
- }
+ List<SubscriptionInfo> subInfos = SubscriptionManagerService.getInstance()
+ .getActiveSubscriptionInfoList(mApplication.getOpPackageName(),
+ mApplication.getAttributionTag());
// Sort sub id list based on slot id, so that CFI/MWI notifications will be updated for
// slot 0 first then slot 1. This is needed to ensure that when CFI or MWI is enabled for
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 9d11dfc..fa85f27 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -64,7 +64,6 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConfigurationManager;
import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionInfoUpdater;
import com.android.internal.telephony.TelephonyPermissions;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.util.ArrayUtils;
@@ -127,8 +126,6 @@
// CarrierService change monitoring
@NonNull private CarrierServiceChangeCallback[] mCarrierServiceChangeCallbacks;
- // SubscriptionInfoUpdater
- @NonNull private final SubscriptionInfoUpdater mSubscriptionInfoUpdater;
// Broadcast receiver for system events
@NonNull
private final BroadcastReceiver mSystemBroadcastReceiver = new ConfigLoaderBroadcastReceiver();
@@ -138,7 +135,7 @@
// Message codes; see mHandler below.
- // Request from SubscriptionInfoUpdater when SIM becomes absent or error.
+ // Request from UiccController when SIM becomes absent or error.
private static final int EVENT_CLEAR_CONFIG = 0;
// Has connected to default app.
private static final int EVENT_CONNECTED_TO_DEFAULT = 3;
@@ -166,7 +163,7 @@
private static final int EVENT_FETCH_DEFAULT_TIMEOUT = 14;
// Fetching config timed out from a carrier app.
private static final int EVENT_FETCH_CARRIER_TIMEOUT = 15;
- // SubscriptionInfoUpdater has finished updating the sub for the carrier config.
+ // SubscriptionManagerService has finished updating the sub for the carrier config.
private static final int EVENT_SUBSCRIPTION_INFO_UPDATED = 16;
// Multi-SIM config changed.
private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 17;
@@ -697,9 +694,7 @@
* receiver for relevant events.
*/
@VisibleForTesting
- /* package */ CarrierConfigLoader(@NonNull Context context,
- //TODO: Remove SubscriptionInfoUpdater.
- @Nullable SubscriptionInfoUpdater subscriptionInfoUpdater, @NonNull Looper looper) {
+ /* package */ CarrierConfigLoader(@NonNull Context context, @NonNull Looper looper) {
mContext = context;
mPlatformCarrierConfigPackage =
mContext.getString(R.string.platform_carrier_config_package);
@@ -728,7 +723,6 @@
new HandlerExecutor(mHandler), mCarrierServiceChangeCallbacks[phoneId]);
}
logd("CarrierConfigLoader has started");
- mSubscriptionInfoUpdater = subscriptionInfoUpdater;
PhoneConfigurationManager.registerForMultiSimConfigChange(
mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
@@ -745,8 +739,7 @@
/* package */ static CarrierConfigLoader init(@NonNull Context context) {
synchronized (CarrierConfigLoader.class) {
if (sInstance == null) {
- sInstance = new CarrierConfigLoader(context,
- PhoneFactory.getSubscriptionInfoUpdater(), Looper.myLooper());
+ sInstance = new CarrierConfigLoader(context, Looper.myLooper());
// Make this service available through ServiceManager.
TelephonyFrameworkInitializer.getTelephonyServiceManager()
.getCarrierConfigServiceRegisterer().register(sInstance);
@@ -811,16 +804,10 @@
configToSend.putAll(config);
}
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- SubscriptionManagerService.getInstance().updateSubscriptionByCarrierConfig(
- phoneId, configPackageName, configToSend,
- () -> mHandler.obtainMessage(EVENT_SUBSCRIPTION_INFO_UPDATED, phoneId, -1)
- .sendToTarget());
- } else {
- mSubscriptionInfoUpdater.updateSubscriptionByCarrierConfigAndNotifyComplete(
- phoneId, configPackageName, configToSend,
- mHandler.obtainMessage(EVENT_SUBSCRIPTION_INFO_UPDATED, phoneId, -1));
- }
+ SubscriptionManagerService.getInstance().updateSubscriptionByCarrierConfig(
+ phoneId, configPackageName, configToSend,
+ () -> mHandler.obtainMessage(EVENT_SUBSCRIPTION_INFO_UPDATED, phoneId, -1)
+ .sendToTarget());
}
private void broadcastConfigChangedIntent(int phoneId) {
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index f7a9865..36e5012 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -201,7 +201,6 @@
import com.android.internal.telephony.SmsApplication;
import com.android.internal.telephony.SmsController;
import com.android.internal.telephony.SmsPermissions;
-import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyPermissions;
import com.android.internal.telephony.data.DataUtils;
@@ -410,7 +409,6 @@
private final UserManager mUserManager;
private final AppOpsManager mAppOps;
private final MainThreadHandler mMainThreadHandler;
- private final SubscriptionController mSubscriptionController;
private final SharedPreferences mTelephonySharedPreferences;
private final PhoneConfigurationManager mPhoneConfigurationManager;
private final RadioInterfaceCapabilityController mRadioInterfaceCapabilities;
@@ -2461,11 +2459,6 @@
mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
mMainThreadHandler = new MainThreadHandler();
- if (!PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- mSubscriptionController = SubscriptionController.getInstance();
- } else {
- mSubscriptionController = null;
- }
mTelephonySharedPreferences = PreferenceManager.getDefaultSharedPreferences(mApp);
mNetworkScanRequestTracker = new NetworkScanRequestTracker();
mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
@@ -5499,11 +5492,8 @@
}
private boolean isActiveSubscription(int subId) {
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- return getSubscriptionManagerService().isActiveSubId(subId,
- mApp.getOpPackageName(), mApp.getFeatureId());
- }
- return mSubscriptionController.isActiveSubId(subId);
+ return getSubscriptionManagerService().isActiveSubId(subId,
+ mApp.getOpPackageName(), mApp.getFeatureId());
}
/**
@@ -7465,16 +7455,9 @@
return null;
}
- ParcelUuid groupUuid;
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- final SubscriptionInfo info = getSubscriptionManagerService()
- .getSubscriptionInfo(subId);
- groupUuid = info.getGroupUuid();
- } else {
- final SubscriptionInfo info = mSubscriptionController
- .getSubscriptionInfo(subId);
- groupUuid = info.getGroupUuid();
- }
+ final SubscriptionInfo info = getSubscriptionManagerService()
+ .getSubscriptionInfo(subId);
+ ParcelUuid groupUuid = info.getGroupUuid();
// If it doesn't belong to any group, return just subscriberId of itself.
if (groupUuid == null) {
return new String[]{subscriberId};
@@ -7482,16 +7465,9 @@
// Get all subscriberIds from the group.
final List<String> mergedSubscriberIds = new ArrayList<>();
- List<SubscriptionInfo> groupInfos;
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- groupInfos = getSubscriptionManagerService()
- .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
- mApp.getAttributionTag());
- } else {
- groupInfos = mSubscriptionController
- .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
- mApp.getAttributionTag());
- }
+ List<SubscriptionInfo> groupInfos = getSubscriptionManagerService()
+ .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
+ mApp.getAttributionTag());
for (SubscriptionInfo subInfo : groupInfos) {
subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
if (subscriberId != null) {
@@ -8051,23 +8027,12 @@
}
final long identity = Binder.clearCallingIdentity();
try {
- SubscriptionInfo info;
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- info = getSubscriptionManagerService().getActiveSubscriptionInfo(subId,
- phone.getContext().getOpPackageName(),
- phone.getContext().getAttributionTag());
- if (info == null) {
- log("getSimLocaleForSubscriber, inactive subId: " + subId);
- return null;
- }
- } else {
- info = mSubscriptionController.getActiveSubscriptionInfo(subId,
- phone.getContext().getOpPackageName(),
- phone.getContext().getAttributionTag());
- if (info == null) {
- log("getSimLocaleForSubscriber, inactive subId: " + subId);
- return null;
- }
+ SubscriptionInfo info = getSubscriptionManagerService().getActiveSubscriptionInfo(subId,
+ phone.getContext().getOpPackageName(),
+ phone.getContext().getAttributionTag());
+ if (info == null) {
+ log("getSimLocaleForSubscriber, inactive subId: " + subId);
+ return null;
}
// Try and fetch the locale from the carrier properties or from the SIM language
// preferences (EF-PL and EF-LI)...
@@ -8119,12 +8084,8 @@
* NOTE: this method assumes permission checks are done and caller identity has been cleared.
*/
private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- return getSubscriptionManagerService().getActiveSubscriptionInfoList(
- mApp.getOpPackageName(), mApp.getAttributionTag());
- }
- return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
- mApp.getAttributionTag());
+ return getSubscriptionManagerService().getActiveSubscriptionInfoList(
+ mApp.getOpPackageName(), mApp.getAttributionTag());
}
private ActivityStatsTechSpecificInfo[] mLastModemActivitySpecificInfo = null;
@@ -8334,21 +8295,12 @@
.contains(callingPackage);
try {
// isActiveSubId requires READ_PHONE_STATE, which we already check for above
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- SubscriptionInfoInternal subInfo = getSubscriptionManagerService()
- .getSubscriptionInfoInternal(subId);
- if (subInfo == null || !subInfo.isActive()) {
- Rlog.d(LOG_TAG, "getServiceStateForSubscriber returning null for inactive "
- + "subId=" + subId);
- return null;
- }
- } else {
- if (!mSubscriptionController.isActiveSubId(subId, callingPackage,
- callingFeatureId)) {
- Rlog.d(LOG_TAG, "getServiceStateForSubscriber returning null for inactive "
- + "subId=" + subId);
- return null;
- }
+ SubscriptionInfoInternal subInfo = getSubscriptionManagerService()
+ .getSubscriptionInfoInternal(subId);
+ if (subInfo == null || !subInfo.isActive()) {
+ Rlog.d(LOG_TAG, "getServiceStateForSubscriber returning null for inactive "
+ + "subId=" + subId);
+ return null;
}
ServiceState ss = phone.getServiceState();
diff --git a/src/com/android/phone/settings/AccessibilitySettingsFragment.java b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
index 4c29e65..8c4a343 100644
--- a/src/com/android/phone/settings/AccessibilitySettingsFragment.java
+++ b/src/com/android/phone/settings/AccessibilitySettingsFragment.java
@@ -39,7 +39,6 @@
import com.android.ims.ImsManager;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.phone.PhoneGlobals;
import com.android.phone.R;
@@ -184,12 +183,8 @@
// Update RTT config with IMS Manager if the always-on carrier config isn't set to true.
CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(
Context.CARRIER_CONFIG_SERVICE);
- int[] activeSubIds;
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- activeSubIds = SubscriptionManagerService.getInstance().getActiveSubIdList(true);
- } else {
- activeSubIds = SubscriptionController.getInstance().getActiveSubIdList(true);
- }
+ int[] activeSubIds = SubscriptionManagerService.getInstance().getActiveSubIdList(true);
+
for (int subId : activeSubIds) {
if (!configManager.getConfigForSubId(subId).getBoolean(
CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL, false)) {
@@ -271,15 +266,7 @@
private boolean shouldShowRttSetting() {
// Go through all the subs -- if we want to display the RTT setting for any of them, do
// display it.
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- for (int subId : SubscriptionManagerService.getInstance().getActiveSubIdList(true)) {
- if (PhoneGlobals.getInstance().phoneMgr.isRttSupported(subId)) {
- return true;
- }
- }
- return false;
- }
- for (int subId : SubscriptionController.getInstance().getActiveSubIdList(true)) {
+ for (int subId : SubscriptionManagerService.getInstance().getActiveSubIdList(true)) {
if (PhoneGlobals.getInstance().phoneMgr.isRttSupported(subId)) {
return true;
}
diff --git a/src/com/android/phone/vvm/RemoteVvmTaskManager.java b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
index 7329854..daa5d67b 100644
--- a/src/com/android/phone/vvm/RemoteVvmTaskManager.java
+++ b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
@@ -183,6 +183,7 @@
if (targetPackage != null && !TextUtils.equals(packageName, targetPackage)) {
VvmLog.w(TAG, "target package " + targetPackage
+ " is no longer the active VisualVoicemailService, ignoring");
+ continue;
}
ComponentInfo componentInfo = TelephonyUtils.getComponentInfo(info);
return new ComponentName(componentInfo.packageName, componentInfo.name);
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 57e65ee..2b69b82 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -63,7 +63,6 @@
import com.android.internal.telephony.ExponentialBackoff;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.phone.PhoneGlobals;
import com.android.phone.PhoneUtils;
@@ -550,38 +549,22 @@
return false;
}
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- if (SubscriptionManagerService.getInstance() == null) {
- Log.d(this,
- "isEmergencyPreferredAccount: SubscriptionManagerService not "
- + "available.");
- return false;
- }
- // Only set an emergency preference on devices with multiple active subscriptions
- // (include opportunistic subscriptions) in this check.
- // API says never null, but this can return null in testing.
- int[] activeSubIds = SubscriptionManagerService.getInstance()
- .getActiveSubIdList(false);
- if (activeSubIds == null || activeSubIds.length <= 1) {
- Log.d(this, "isEmergencyPreferredAccount: one or less active subscriptions.");
- return false;
- }
- } else {
- SubscriptionController controller = SubscriptionController.getInstance();
- if (controller == null) {
- Log.d(this,
- "isEmergencyPreferredAccount: SubscriptionController not available.");
- return false;
- }
- // Only set an emergency preference on devices with multiple active subscriptions
- // (include opportunistic subscriptions) in this check.
- // API says never null, but this can return null in testing.
- int[] activeSubIds = controller.getActiveSubIdList(false);
- if (activeSubIds == null || activeSubIds.length <= 1) {
- Log.d(this, "isEmergencyPreferredAccount: one or less active subscriptions.");
- return false;
- }
+ if (SubscriptionManagerService.getInstance() == null) {
+ Log.d(this,
+ "isEmergencyPreferredAccount: SubscriptionManagerService not "
+ + "available.");
+ return false;
}
+ // Only set an emergency preference on devices with multiple active subscriptions
+ // (include opportunistic subscriptions) in this check.
+ // API says never null, but this can return null in testing.
+ int[] activeSubIds = SubscriptionManagerService.getInstance()
+ .getActiveSubIdList(false);
+ if (activeSubIds == null || activeSubIds.length <= 1) {
+ Log.d(this, "isEmergencyPreferredAccount: one or less active subscriptions.");
+ return false;
+ }
+
// Check to see if this PhoneAccount is associated with the default Data subscription.
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Log.d(this, "isEmergencyPreferredAccount: provided subId " + subId + "is not "
@@ -591,17 +574,10 @@
int userDefaultData = SubscriptionManager.getDefaultDataSubscriptionId();
boolean isActiveDataValid = SubscriptionManager.isValidSubscriptionId(activeDataSubId);
- boolean isActiveDataOpportunistic;
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- SubscriptionInfo subInfo;
- subInfo = SubscriptionManagerService.getInstance()
- .getSubscriptionInfo(activeDataSubId);
- isActiveDataOpportunistic = isActiveDataValid && subInfo != null
- && subInfo.isOpportunistic();
- } else {
- isActiveDataOpportunistic = isActiveDataValid
- && SubscriptionController.getInstance().isOpportunistic(activeDataSubId);
- }
+ SubscriptionInfo subInfo = SubscriptionManagerService.getInstance()
+ .getSubscriptionInfo(activeDataSubId);
+ boolean isActiveDataOpportunistic = isActiveDataValid && subInfo != null
+ && subInfo.isOpportunistic();
// compare the activeDataSubId to the subId specified only if it is valid and not an
// opportunistic subscription (only supports data). If not, use the current default
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 7c30bff..91d345f 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -56,6 +56,7 @@
import android.telephony.TelephonyManager;
import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.util.Pair;
import android.view.WindowManager;
@@ -71,7 +72,6 @@
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.RIL;
-import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.d2d.Communicator;
import com.android.internal.telephony.data.PhoneSwitcher;
import com.android.internal.telephony.domainselection.DomainSelectionConnection;
@@ -125,7 +125,7 @@
// Timeout before we terminate the outgoing DSDA call if HOLD did not complete in time on the
// existing call.
- private static final int DEFAULT_DSDA_OUTGOING_CALL_HOLD_TIMEOUT_MS = 1000;
+ private static final int DEFAULT_DSDA_OUTGOING_CALL_HOLD_TIMEOUT_MS = 2000;
private static final String KEY_DOMAIN_COMPARE_FEATURE_ENABLED_FLAG =
"is_domain_selection_compare_feature_enabled";
@@ -654,14 +654,14 @@
if (c != null) {
switch (c.getState()) {
case Connection.STATE_HOLDING: {
- Log.d(LOG_TAG, "Connection " + connection
+ Log.d(LOG_TAG, "Connection " + connection.getTelecomCallId()
+ " changed to STATE_HOLDING!");
mStateHoldingFuture.complete(true);
c.removeTelephonyConnectionListener(this);
}
break;
case Connection.STATE_DISCONNECTED: {
- Log.d(LOG_TAG, "Connection " + connection
+ Log.d(LOG_TAG, "Connection " + connection.getTelecomCallId()
+ " changed to STATE_DISCONNECTED!");
mStateHoldingFuture.complete(false);
c.removeTelephonyConnectionListener(this);
@@ -1106,27 +1106,16 @@
return (phone.getState() == PhoneConstants.State.OFFHOOK)
|| phone.getServiceStateTracker().isRadioOn();
} else {
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- SubscriptionInfoInternal subInfo = SubscriptionManagerService
- .getInstance().getSubscriptionInfoInternal(phone.getSubId());
- // Wait until we are in service and ready to make calls. This can happen
- // when we power down the radio on bluetooth to save power on watches or
- // if it is a test emergency number and we have to wait for the device
- // to move IN_SERVICE before the call can take place over normal
- // routing.
- return (phone.getState() == PhoneConstants.State.OFFHOOK)
- // Do not wait for voice in service on opportunistic SIMs.
- || (subInfo != null && subInfo.isOpportunistic())
- || serviceState == ServiceState.STATE_IN_SERVICE;
- }
+ SubscriptionInfoInternal subInfo = SubscriptionManagerService
+ .getInstance().getSubscriptionInfoInternal(phone.getSubId());
// Wait until we are in service and ready to make calls. This can happen
- // when we power down the radio on bluetooth to save power on watches or if
- // it is a test emergency number and we have to wait for the device to move
- // IN_SERVICE before the call can take place over normal routing.
+ // when we power down the radio on bluetooth to save power on watches or
+ // if it is a test emergency number and we have to wait for the device
+ // to move IN_SERVICE before the call can take place over normal
+ // routing.
return (phone.getState() == PhoneConstants.State.OFFHOOK)
// Do not wait for voice in service on opportunistic SIMs.
- || SubscriptionController.getInstance().isOpportunistic(
- phone.getSubId())
+ || (subInfo != null && subInfo.isOpportunistic())
|| serviceState == ServiceState.STATE_IN_SERVICE;
}
}
@@ -1157,29 +1146,56 @@
return resultConnection;
} else {
if (mTelephonyManagerProxy.isConcurrentCallsPossible()) {
- delayDialForOtherSubHold(phone, request.getAccountHandle(), (result) -> {
- Log.d(this,
- "onCreateOutgoingConn - delayDialForOtherSubHold result = "
- + result);
- if (result) {
- placeOutgoingConnection(request, resultConnection, phone);
- } else {
- ((TelephonyConnection) resultConnection).hangup(
- android.telephony.DisconnectCause.LOCAL);
- }
- });
- return resultConnection;
+ Conferenceable c = maybeHoldCallsOnOtherSubs(request.getAccountHandle());
+ if (c != null) {
+ delayDialForOtherSubHold(phone, c, (success) -> {
+ Log.d(this,
+ "onCreateOutgoingConn - delayDialForOtherSubHold"
+ + " success = " + success);
+ if (success) {
+ placeOutgoingConnection(request, resultConnection,
+ phone);
+ } else {
+ ((TelephonyConnection) resultConnection).hangup(
+ android.telephony.DisconnectCause.LOCAL);
+ }
+ });
+ return resultConnection;
+ }
}
- // The standard case.
return placeOutgoingConnection(request, resultConnection, phone);
}
} else {
final Connection resultConnection = getTelephonyConnection(request, numberToDial,
true, handle, phone);
- delayDialForDdsSwitch(phone, (result) -> {
- Log.i(this, "onCreateOutgoingConn - delayDialForDdsSwitch result = " + result);
- placeOutgoingConnection(request, resultConnection, phone);
- });
+
+ CompletableFuture<Void> maybeHoldFuture = CompletableFuture.completedFuture(null);
+ if (mTelephonyManagerProxy.isConcurrentCallsPossible()
+ && shouldHoldForEmergencyCall(phone)) {
+ // If the PhoneAccountHandle was adjusted on building the TelephonyConnection,
+ // the relevant PhoneAccountHandle will be updated in resultConnection.
+ PhoneAccountHandle phoneAccountHandle =
+ resultConnection.getPhoneAccountHandle() == null
+ ? request.getAccountHandle() : resultConnection.getPhoneAccountHandle();
+ Conferenceable c = maybeHoldCallsOnOtherSubs(phoneAccountHandle);
+ if (c != null) {
+ maybeHoldFuture = delayDialForOtherSubHold(phone, c, (success) -> {
+ Log.i(this, "onCreateOutgoingConn emergency-"
+ + " delayDialForOtherSubHold success = " + success);
+ if (!success) {
+ // Terminates the existing call to make way for the emergency call.
+ hangup(c, android.telephony.DisconnectCause
+ .OUTGOING_EMERGENCY_CALL_PLACED);
+ }
+ });
+ }
+ }
+ Consumer<Boolean> ddsSwitchConsumer = (result) -> {
+ Log.i(this, "onCreateOutgoingConn emergency-"
+ + " delayDialForDdsSwitch result = " + result);
+ placeOutgoingConnection(request, resultConnection, phone);
+ };
+ maybeHoldFuture.thenRun(() -> delayDialForDdsSwitch(phone, ddsSwitchConsumer));
return resultConnection;
}
}
@@ -1294,16 +1310,9 @@
// Notify Telecom of the new Connection type.
// TODO: Switch out the underlying connection instead of creating a new
// one and causing UI Jank.
- boolean noActiveSimCard;
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- noActiveSimCard = SubscriptionManagerService.getInstance()
- .getActiveSubInfoCount(phone.getContext().getOpPackageName(),
- phone.getContext().getAttributionTag()) == 0;
- } else {
- noActiveSimCard = SubscriptionController.getInstance()
- .getActiveSubInfoCount(phone.getContext().getOpPackageName(),
- phone.getContext().getAttributionTag()) == 0;
- }
+ boolean noActiveSimCard = SubscriptionManagerService.getInstance()
+ .getActiveSubInfoCount(phone.getContext().getOpPackageName(),
+ phone.getContext().getAttributionTag()) == 0;
// If there's no active sim card and the device is in emergency mode, use E account.
addExistingConnection(mPhoneUtilsProxy.makePstnPhoneAccountHandleWithPrefix(
phone, "", isEmergencyNumber && noActiveSimCard), repConnection);
@@ -2942,7 +2951,7 @@
}
/**
- * If needed, block until the the default data is is switched for outgoing emergency call, or
+ * If needed, block until the default data is switched for outgoing emergency call, or
* timeout expires.
* @param phone The Phone to switch the DDS on.
* @param completeConsumer The consumer to call once the default data subscription has been
@@ -3097,37 +3106,30 @@
return future;
}
- // If there are any live calls on the other subscription, sends a hold request for the live call
- // and waits for the STATE_HOLDING confirmation, to sequence the dial of the outgoing call.
- private void delayDialForOtherSubHold(Phone phone, PhoneAccountHandle phoneAccountHandle,
+ // Returns a future that waits for the STATE_HOLDING confirmation on the input
+ // {@link Conferenceable}, or times out.
+ private CompletableFuture<Void> delayDialForOtherSubHold(Phone phone, Conferenceable c,
Consumer<Boolean> completeConsumer) {
- Conferenceable c = maybeHoldCallsOnOtherSubs(phoneAccountHandle);
- if (c == null) {
- // Nothing to hold.
- completeConsumer.accept(true);
- return;
- }
-
- if (phone == null) {
+ if (c == null || phone == null) {
+ // Unexpected inputs
completeConsumer.accept(false);
- return;
+ return CompletableFuture.completedFuture(null);
}
try {
- // We have dispatched a 'hold' command to a live call (Connection or Conference) on the
- // other sub. Listen to state changed events to see if this entered hold state.
CompletableFuture<Boolean> stateHoldingFuture = listenForHoldStateChanged(c);
// a timeout that will complete the future to not block the outgoing call indefinitely.
CompletableFuture<Boolean> timeout = new CompletableFuture<>();
phone.getContext().getMainThreadHandler().postDelayed(
() -> timeout.complete(false), DEFAULT_DSDA_OUTGOING_CALL_HOLD_TIMEOUT_MS);
// Ensure that the Consumer is completed on the main thread.
- stateHoldingFuture.acceptEitherAsync(timeout, completeConsumer,
+ return stateHoldingFuture.acceptEitherAsync(timeout, completeConsumer,
phone.getContext().getMainExecutor());
} catch (Exception e) {
Log.w(this, "delayDialForOtherSubHold - exception= "
+ e.getMessage());
completeConsumer.accept(false);
+ return CompletableFuture.completedFuture(null);
}
}
@@ -3366,6 +3368,13 @@
* Returns true if the state of the Phone is IN_SERVICE or available for emergency calling only.
*/
private boolean isAvailableForEmergencyCalls(Phone phone) {
+ if (phone.getImsRegistrationTech() == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
+ // When a Phone is registered to Cross-SIM calling, there must always be a Phone on the
+ // other sub which is registered to cellular, so that must be selected.
+ Log.d(this, "isAvailableForEmergencyCalls: skipping over phone "
+ + phone + " as it is registered to CROSS_SIM");
+ return false;
+ }
return ServiceState.STATE_IN_SERVICE == phone.getServiceState().getState() ||
phone.getServiceState().isEmergencyOnly();
}
@@ -3774,6 +3783,16 @@
}
}
+ private static void hangup(Conferenceable conferenceable, int code) {
+ if (conferenceable instanceof TelephonyConnection) {
+ ((TelephonyConnection) conferenceable).hangup(code);
+ } else if (conferenceable instanceof Conference) {
+ ((Conference) conferenceable).onDisconnect();
+ } else {
+ Log.w(LOG_TAG, "hangup(): Unexpected conferenceable! " + conferenceable);
+ }
+ }
+
/**
* Evaluates whether a connection or conference exists on subscriptions other than the one
* corresponding to the existing {@link PhoneAccountHandle}.
@@ -3801,6 +3820,9 @@
currentHandle))
.toList();
if (!otherSubConferences.isEmpty()) {
+ Log.i(LOG_TAG, "maybeGetFirstConferenceable: found "
+ + otherSubConferences.get(0).getTelecomCallId() + " on "
+ + otherSubConferences.get(0).getPhoneAccountHandle());
return otherSubConferences.get(0);
}
@@ -3818,6 +3840,9 @@
Log.w(LOG_TAG, "Unexpected number of connections: "
+ otherSubConnections.size() + " on other sub!");
}
+ Log.i(LOG_TAG, "maybeGetFirstConferenceable: found "
+ + otherSubConnections.get(0).getTelecomCallId() + " on "
+ + otherSubConnections.get(0).getPhoneAccountHandle());
return otherSubConnections.get(0);
}
return null;
diff --git a/tests/src/com/android/phone/CarrierConfigLoaderTest.java b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
index f29c123..b6f8ed8 100644
--- a/tests/src/com/android/phone/CarrierConfigLoaderTest.java
+++ b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
@@ -40,7 +40,6 @@
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
-import android.os.Message;
import android.os.PersistableBundle;
import android.os.UserHandle;
import android.service.carrier.CarrierIdentifier;
@@ -55,8 +54,6 @@
import com.android.TelephonyTestBase;
import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionInfoUpdater;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import org.junit.After;
@@ -90,7 +87,6 @@
@Mock Resources mResources;
@Mock PackageManager mPackageManager;
@Mock PackageInfo mPackageInfo;
- @Mock SubscriptionInfoUpdater mSubscriptionInfoUpdater;
@Mock SubscriptionManagerService mSubscriptionManagerService;
@Mock SharedPreferences mSharedPreferences;
@Mock TelephonyRegistryManager mTelephonyRegistryManager;
@@ -136,8 +132,7 @@
mHandlerThread.start();
mTestableLooper = new TestableLooper(mHandlerThread.getLooper());
- mCarrierConfigLoader = new CarrierConfigLoader(mContext, mSubscriptionInfoUpdater,
- mTestableLooper.getLooper());
+ mCarrierConfigLoader = new CarrierConfigLoader(mContext, mTestableLooper.getLooper());
mHandler = mCarrierConfigLoader.getHandler();
// Clear all configs to have the same starting point.
@@ -279,15 +274,9 @@
mTestableLooper.processAllMessages();
assertThat(mCarrierConfigLoader.getOverrideConfig(DEFAULT_PHONE_ID).isEmpty()).isTrue();
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- verify(mSubscriptionManagerService).updateSubscriptionByCarrierConfig(
- eq(DEFAULT_PHONE_ID), eq(PLATFORM_CARRIER_CONFIG_PACKAGE),
- any(PersistableBundle.class), any(Runnable.class));
- } else {
- verify(mSubscriptionInfoUpdater).updateSubscriptionByCarrierConfigAndNotifyComplete(
- eq(DEFAULT_PHONE_ID), eq(PLATFORM_CARRIER_CONFIG_PACKAGE),
- any(PersistableBundle.class), any(Message.class));
- }
+ verify(mSubscriptionManagerService).updateSubscriptionByCarrierConfig(
+ eq(DEFAULT_PHONE_ID), eq(PLATFORM_CARRIER_CONFIG_PACKAGE),
+ any(PersistableBundle.class), any(Runnable.class));
}
/**
@@ -308,15 +297,9 @@
assertThat(mCarrierConfigLoader.getOverrideConfig(DEFAULT_PHONE_ID).getInt(
CARRIER_CONFIG_EXAMPLE_KEY)).isEqualTo(CARRIER_CONFIG_EXAMPLE_VALUE);
- if (PhoneFactory.isSubscriptionManagerServiceEnabled()) {
- verify(mSubscriptionManagerService).updateSubscriptionByCarrierConfig(
- eq(DEFAULT_PHONE_ID), eq(PLATFORM_CARRIER_CONFIG_PACKAGE),
- any(PersistableBundle.class), any(Runnable.class));
- } else {
- verify(mSubscriptionInfoUpdater).updateSubscriptionByCarrierConfigAndNotifyComplete(
- eq(DEFAULT_PHONE_ID), eq(PLATFORM_CARRIER_CONFIG_PACKAGE),
- any(PersistableBundle.class), any(Message.class));
- }
+ verify(mSubscriptionManagerService).updateSubscriptionByCarrierConfig(
+ eq(DEFAULT_PHONE_ID), eq(PLATFORM_CARRIER_CONFIG_PACKAGE),
+ any(PersistableBundle.class), any(Runnable.class));
}
/**
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 49b9c98..d144d9d 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -1703,6 +1703,110 @@
assertTrue(tc1.wasHeld);
}
+ // For 'Virtual DSDA' devices, if there is an existing call on sub1, an outgoing call on sub2
+ // will place the sub1 call on hold.
+ @Test
+ @SmallTest
+ public void testOutgoingCallOnOtherSubPutsFirstCallOnHoldForVirtualDsdaDevice()
+ throws Exception {
+ setupForCallTest();
+ when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true);
+ doNothing().when(mContext).startActivity(any());
+
+ mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_1, "TC@1",
+ new ConnectionRequest(PHONE_ACCOUNT_HANDLE_1, Uri.parse("tel:16505551212"),
+ new Bundle()),
+ true, false, null);
+ waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS);
+ assertEquals(1, mTestConnectionService.getAllConnections().size());
+
+ TelephonyConnection connection1 = (TelephonyConnection)
+ mTestConnectionService.getAllConnections().toArray()[0];
+
+ TelephonyConnection connection2 = (TelephonyConnection) mTestConnectionService
+ .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_2,
+ createConnectionRequest(PHONE_ACCOUNT_HANDLE_2, "1234", "TC@2"));
+ assertNotNull("test connection was not set up correctly.", connection2);
+
+ // Simulates that connection1 is placed on HOLD.
+ connection1.setTelephonyConnectionOnHold();
+
+ verify(mPhone1).dial(anyString(), any(), any());
+ assertEquals(connection1.getState(), android.telecom.Connection.STATE_HOLDING);
+ }
+
+ // For 'Virtual DSDA' devices, if the carrier config 'KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL'
+ // is not configured, or set to true, an outgoing emergency call will place the existing call on
+ // a different sub on hold.
+ @Test
+ @SmallTest
+ public void testEmergencyCallOnOtherSubPutsFirstCallOnHoldForVirtualDsdaDevice()
+ throws Exception {
+ setupForCallTest();
+ when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true);
+ doNothing().when(mContext).startActivity(any());
+
+ doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString());
+ mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_1, "TC@1",
+ new ConnectionRequest(PHONE_ACCOUNT_HANDLE_1, Uri.parse("tel:16505551212"),
+ new Bundle()),
+ true, false, null);
+ waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS);
+ assertEquals(1, mTestConnectionService.getAllConnections().size());
+
+ TelephonyConnection connection1 = (TelephonyConnection)
+ mTestConnectionService.getAllConnections().toArray()[0];
+
+ // Simulates an outgoing emergency call.
+ TelephonyConnection connection2 = (TelephonyConnection) mTestConnectionService
+ .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_2,
+ createConnectionRequest(PHONE_ACCOUNT_HANDLE_2,
+ TEST_EMERGENCY_NUMBER, "TC@2"));
+ assertNotNull("test connection was not set up correctly.", connection2);
+
+ // Simulates that connection1 is placed on HOLD.
+ connection1.setTelephonyConnectionOnHold();
+
+ verify(mPhone1).dial(anyString(), any(), any());
+ assertEquals(connection1.getState(), android.telecom.Connection.STATE_HOLDING);
+ }
+
+ // For 'Virtual DSDA' devices If the carrier config 'KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL'
+ // is explicitly configured false, an outgoing emergency call will disconnect all existing
+ // calls, across subscriptions.
+ @Test
+ @SmallTest
+ public void testEmergencyCallOnOtherSubDisconnectsExistingCallForVirtualDsdaDevice()
+ throws Exception {
+ setupForCallTest();
+ when(mTelephonyManagerProxy.isConcurrentCallsPossible()).thenReturn(true);
+ doNothing().when(mContext).startActivity(any());
+
+ doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString());
+ getTestContext().getCarrierConfig(0 /*subId*/).putBoolean(
+ CarrierConfigManager.KEY_ALLOW_HOLD_CALL_DURING_EMERGENCY_BOOL, false);
+
+ mBinderStub.createConnection(PHONE_ACCOUNT_HANDLE_1, "TC@1",
+ new ConnectionRequest(PHONE_ACCOUNT_HANDLE_1, Uri.parse("tel:16505551212"),
+ new Bundle()),
+ true, false, null);
+ waitForHandlerAction(mTestConnectionService.getHandler(), TIMEOUT_MS);
+ assertEquals(1, mTestConnectionService.getAllConnections().size());
+
+ TelephonyConnection connection1 = (TelephonyConnection)
+ mTestConnectionService.getAllConnections().toArray()[0];
+
+ // Simulates an outgoing emergency call.
+ TelephonyConnection connection2 = (TelephonyConnection) mTestConnectionService
+ .onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_2,
+ createConnectionRequest(PHONE_ACCOUNT_HANDLE_2,
+ TEST_EMERGENCY_NUMBER, "TC@2"));
+ assertNotNull("test connection was not set up correctly.", connection2);
+
+ verify(mPhone1).dial(anyString(), any(), any());
+ assertEquals(connection1.getState(), android.telecom.Connection.STATE_DISCONNECTED);
+ }
+
/**
* Verifies that TelephonyManager is used to determine whether a connection is Emergency when
* creating an outgoing connection.