Merge "Revert "Add SimultaneousCallingTracker"" into main
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index c088406..97eb447 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -17,7 +17,6 @@
package com.android.internal.telephony;
import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
-import static android.telephony.ims.ImsService.CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -4621,20 +4620,6 @@
}
}
- public boolean isImsServiceSimultaneousCallingSupportCapable(Context context) {
- if (!mFeatureFlags.simultaneousCallingIndications()) return false;
- boolean capable = false;
- ImsManager imsManager = ImsManager.getInstance(context, mPhoneId);
- if (imsManager != null) {
- try {
- capable = imsManager.isCapable(CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING);
- } catch (ImsException e) {
- loge("initializeTerminalBasedCallWaiting : exception " + e);
- }
- }
- return capable;
- }
-
public void startRingbackTone() {
}
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 49e1e38..7141f37 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -49,7 +49,6 @@
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -75,25 +74,6 @@
private static final int EVENT_GET_SIMULTANEOUS_CALLING_SUPPORT_DONE = 105;
private static final int EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED = 106;
- /**
- * Listener interface for events related to the {@link PhoneConfigurationManager} which should
- * be reported to the {@link SimultaneousCallingTracker}.
- */
- public interface Listener {
- public void onPhoneCapabilityChanged();
- public void onDeviceConfigChanged();
- }
-
- /**
- * Base listener implementation.
- */
- public abstract static class ListenerBase implements Listener {
- @Override
- public void onPhoneCapabilityChanged() {}
- @Override
- public void onDeviceConfigChanged() {}
- }
-
private static PhoneConfigurationManager sInstance = null;
private final Context mContext;
@@ -115,8 +95,6 @@
@NonNull
private final FeatureFlags mFeatureFlags;
private final DefaultPhoneNotifier mNotifier;
- public Set<Listener> mListeners = new CopyOnWriteArraySet<>();
-
/**
* True if 'Virtual DSDA' i.e., in-call IMS connectivity on both subs with only single logical
* modem, is enabled.
@@ -178,24 +156,6 @@
}
/**
- * Assign a listener to be notified of state changes.
- *
- * @param listener A listener.
- */
- public void addListener(Listener listener) {
- mListeners.add(listener);
- }
-
- /**
- * Removes a listener.
- *
- * @param listener A listener.
- */
- public final void removeListener(Listener listener) {
- mListeners.remove(listener);
- }
-
- /**
* Updates the mapping between the slot IDs that support simultaneous calling and the
* associated sub IDs as well as notifies listeners.
*/
@@ -345,9 +305,6 @@
if (ar != null && ar.exception == null) {
mStaticCapability = (PhoneCapability) ar.result;
notifyCapabilityChanged();
- for (Listener l : mListeners) {
- l.onPhoneCapabilityChanged();
- }
maybeEnableCellularDSDASupport();
} else {
log(msg.what + " failure. Not getting phone capability." + ar.exception);
@@ -360,9 +317,6 @@
log("EVENT_DEVICE_CONFIG_CHANGED: from " + mVirtualDsdaEnabled + " to "
+ isVirtualDsdaEnabled);
mVirtualDsdaEnabled = isVirtualDsdaEnabled;
- for (Listener l : mListeners) {
- l.onDeviceConfigChanged();
- }
}
break;
case EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED:
@@ -509,10 +463,7 @@
return mTelephonyManager.getActiveModemCount();
}
- /**
- * @return The updated list of logical slots that support simultaneous cellular calling from the
- * modem based on current network conditions.
- */
+ @VisibleForTesting
public Set<Integer> getSlotsSupportingSimultaneousCellularCalls() {
return mSlotsSupportingSimultaneousCellularCalls;
}
@@ -559,14 +510,6 @@
return mStaticCapability.getMaxActiveDataSubscriptions();
}
- public int getNumberOfModemsWithSimultaneousVoiceConnections() {
- return getStaticPhoneCapability().getMaxActiveVoiceSubscriptions();
- }
-
- public boolean isVirtualDsdaEnabled() {
- return mVirtualDsdaEnabled;
- }
-
/**
* Register to listen to changes in the Phone slots that support simultaneous calling.
* @param consumer A consumer that will be used to consume the new slots supporting simultaneous
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index c5bc428..b1ff500 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -98,7 +98,6 @@
@UnsupportedAppUsage
static private Context sContext;
static private PhoneConfigurationManager sPhoneConfigurationManager;
- static private SimultaneousCallingTracker sSimultaneousCallingTracker;
static private PhoneSwitcher sPhoneSwitcher;
static private TelephonyNetworkFactory[] sTelephonyNetworkFactories;
static private NotificationChannelController sNotificationChannelController;
@@ -258,10 +257,6 @@
}
sPhoneConfigurationManager = PhoneConfigurationManager.init(sContext, featureFlags);
- if (featureFlags.simultaneousCallingIndications()) {
- sSimultaneousCallingTracker =
- SimultaneousCallingTracker.init(sContext, featureFlags);
- }
sCellularNetworkValidator = CellularNetworkValidator.make(sContext);
diff --git a/src/java/com/android/internal/telephony/SimultaneousCallingTracker.java b/src/java/com/android/internal/telephony/SimultaneousCallingTracker.java
deleted file mode 100644
index 0a14ccd..0000000
--- a/src/java/com/android/internal/telephony/SimultaneousCallingTracker.java
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.Message;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyRegistryManager;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.flags.FeatureFlags;
-import com.android.internal.telephony.imsphone.ImsPhone;
-import com.android.internal.telephony.subscription.SubscriptionManagerService;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.stream.Collectors;
-
-public class SimultaneousCallingTracker {
- private static SimultaneousCallingTracker sInstance = null;
- private final Context mContext;
-
- /**
- * A dynamic map of all voice capable {@link Phone} objects mapped to the set of {@link Phone}
- * objects each {@link Phone} has a compatible user association with. To be considered
- * compatible based on user association, both must be associated with the same
- * {@link android.os.UserHandle} or both must be unassociated.
- */
- private Map<Phone, Set<Phone>> mVoiceCapablePhoneMap = new HashMap<>();
-
- @VisibleForTesting
- public boolean isDeviceSimultaneousCallingCapable = false;
- public Set<Listener> mListeners = new CopyOnWriteArraySet<>();
- private final PhoneConfigurationManager mPhoneConfigurationManager;
- private final Handler mHandler;
-
- /**
- * A dynamic map of all the Phone IDs mapped to the set of {@link Phone} objects each
- * {@link Phone} supports simultaneous calling (DSDA) with.
- */
- private Map<Integer, Set<Phone>> mSimultaneousCallPhoneSupportMap = new HashMap<>();
- private static final String LOG_TAG = "SimultaneousCallingTracker";
- protected static final int EVENT_SUBSCRIPTION_CHANGED = 101;
- protected static final int EVENT_PHONE_CAPABILITY_CHANGED = 102;
- protected static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 103;
- protected static final int EVENT_DEVICE_CONFIG_CHANGED = 104;
- protected static final int EVENT_IMS_REGISTRATION_CHANGED = 105;
-
- /** Feature flags */
- @NonNull
- private final FeatureFlags mFeatureFlags;
-
- /**
- * Init method to instantiate the object
- * Should only be called once.
- */
- public static SimultaneousCallingTracker init(Context context,
- @NonNull FeatureFlags featureFlags) {
- if (sInstance == null) {
- sInstance = new SimultaneousCallingTracker(context, featureFlags);
- } else {
- Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
- }
- return sInstance;
- }
-
- /**
- * Constructor.
- * @param context context needed to send broadcast.
- */
- private SimultaneousCallingTracker(Context context, @NonNull FeatureFlags featureFlags) {
- mContext = context;
- mFeatureFlags = featureFlags;
- mHandler = new ConfigManagerHandler();
- mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
- mPhoneConfigurationManager.addListener(mPhoneConfigurationManagerListener);
- PhoneConfigurationManager.registerForMultiSimConfigChange(mHandler,
- EVENT_MULTI_SIM_CONFIG_CHANGED, null);
- TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)
- context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
- telephonyRegistryManager.addOnSubscriptionsChangedListener(
- mSubscriptionsChangedListener, new HandlerExecutor(mHandler));
- }
-
- /**
- * Static method to get instance.
- */
- public static SimultaneousCallingTracker getInstance() {
- if (sInstance == null) {
- Log.wtf(LOG_TAG, "getInstance null");
- }
-
- return sInstance;
- }
-
- /**
- * Handler class to handle callbacks
- */
- private final class ConfigManagerHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- if (!mFeatureFlags.simultaneousCallingIndications()) { return; }
- Log.v(LOG_TAG, "Received EVENT " + msg.what);
- switch (msg.what) {
- case EVENT_PHONE_CAPABILITY_CHANGED -> {
- checkSimultaneousCallingDeviceCapability();
- }
- case EVENT_SUBSCRIPTION_CHANGED -> {
- updatePhoneMapAndSimultaneousCallSupportMap();
- }
- case EVENT_MULTI_SIM_CONFIG_CHANGED -> {
- int activeModemCount = (int) ((AsyncResult) msg.obj).result;
- if (activeModemCount > 1) {
- // SSIM --> MSIM: recalculate simultaneous calling supported combinations
- updatePhoneMapAndSimultaneousCallSupportMap();
- } else {
- // MSIM --> SSIM: remove all simultaneous calling supported combinations
- disableSimultaneousCallingSupport();
- handleSimultaneousCallingSupportChanged();
- }
- }
- case EVENT_DEVICE_CONFIG_CHANGED, EVENT_IMS_REGISTRATION_CHANGED -> {
- updateSimultaneousCallSupportMap();
- }
- default -> Log.i(LOG_TAG, "Received unknown event: " + msg.what);
- }
- }
- }
-
- /**
- * Listener interface for events related to the {@link SimultaneousCallingTracker}.
- */
- public interface Listener {
- /**
- * Inform Telecom that the simultaneous calling subscription support map may have changed.
- *
- * @param simultaneousCallSubSupportMap Map of all voice capable subscription IDs mapped to
- * a set containing the subscription IDs which that
- * subscription is DSDA compatible with.
- */
- public void onSimultaneousCallingSupportChanged(Map<Integer,
- Set<Integer>> simultaneousCallSubSupportMap);
- }
-
- /**
- * Base listener implementation.
- */
- public abstract static class ListenerBase implements SimultaneousCallingTracker.Listener {
- @Override
- public void onSimultaneousCallingSupportChanged(Map<Integer,
- Set<Integer>> simultaneousCallSubSupportMap) {}
- }
-
- /**
- * Assign a listener to be notified of state changes.
- *
- * @param listener A listener.
- */
- public void addListener(Listener listener) {
- if (mFeatureFlags.simultaneousCallingIndications()) {
- mListeners.add(listener);
- }
- }
-
- /**
- * Removes a listener.
- *
- * @param listener A listener.
- */
- public final void removeListener(Listener listener) {
- if (mFeatureFlags.simultaneousCallingIndications()) {
- mListeners.remove(listener);
- }
- }
-
- /**
- * Listener for listening to events in the {@link android.telephony.TelephonyRegistryManager}
- */
- private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener =
- new SubscriptionManager.OnSubscriptionsChangedListener() {
- @Override
- public void onSubscriptionsChanged() {
- if (!mHandler.hasMessages(EVENT_SUBSCRIPTION_CHANGED)) {
- mHandler.sendEmptyMessage(EVENT_SUBSCRIPTION_CHANGED);
- }
- }
- };
-
- /**
- * Listener for listening to events in the {@link PhoneConfigurationManager}.
- */
- private final PhoneConfigurationManager.Listener mPhoneConfigurationManagerListener =
- new PhoneConfigurationManager.Listener() {
- @Override
- public void onPhoneCapabilityChanged() {
- if (!mHandler.hasMessages(EVENT_PHONE_CAPABILITY_CHANGED)) {
- mHandler.sendEmptyMessage(EVENT_PHONE_CAPABILITY_CHANGED);
- }
- }
- @Override
- public void onDeviceConfigChanged() {
- if (!mHandler.hasMessages(EVENT_DEVICE_CONFIG_CHANGED)) {
- mHandler.sendEmptyMessage(EVENT_DEVICE_CONFIG_CHANGED);
- }
- }
- };
-
- private void checkSimultaneousCallingDeviceCapability() {
- if (mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousVoiceConnections() > 1) {
- isDeviceSimultaneousCallingCapable = true;
- mPhoneConfigurationManager.registerForSimultaneousCellularCallingSlotsChanged(
- this::onSimultaneousCellularCallingSlotsChanged);
- }
- }
-
- /**
- *
- * @param subId to get the slots supporting simultaneous calling with
- * @return the set of subId's that support simultaneous calling with the param subId
- */
- public Set<Integer> getSubIdsSupportingSimultaneousCalling(int subId) {
- if (!isDeviceSimultaneousCallingCapable) {
- Log.v(LOG_TAG, "Device is not simultaneous calling capable");
- return Collections.emptySet();
- }
- for (int phoneId : mSimultaneousCallPhoneSupportMap.keySet()) {
- if (PhoneFactory.getPhone(phoneId).getSubId() == subId) {
- Set<Integer> subIdsSupportingSimultaneousCalling = new HashSet<>();
- for (Phone phone : mSimultaneousCallPhoneSupportMap.get(phoneId)) {
- subIdsSupportingSimultaneousCalling.add(phone.getSubId());
- }
- Log.d(LOG_TAG, "getSlotsSupportingSimultaneousCalling for subId=" + subId +
- "; subIdsSupportingSimultaneousCalling=[" +
- getStringFromSet(subIdsSupportingSimultaneousCalling) + "].");
- return subIdsSupportingSimultaneousCalling;
- }
- }
- Log.e(LOG_TAG, "getSlotsSupportingSimultaneousCalling: Subscription ID not found in"
- + " the map of voice capable phones.");
- return Collections.emptySet();
- }
-
- private void updatePhoneMapAndSimultaneousCallSupportMap() {
- if (!isDeviceSimultaneousCallingCapable) {
- Log.d(LOG_TAG, "Ignoring updatePhoneMapAndSimultaneousCallSupportMap since device "
- + "is not DSDA capable.");
- return;
- }
- unregisterForImsRegistrationChanges(mVoiceCapablePhoneMap);
- mVoiceCapablePhoneMap = generateVoiceCapablePhoneMapBasedOnUserAssociation();
- Log.i(LOG_TAG, "updatePhoneMapAndSimultaneousCallSupportMap: mVoiceCapablePhoneMap.size = "
- + mVoiceCapablePhoneMap.size());
- registerForImsRegistrationChanges(mVoiceCapablePhoneMap);
- updateSimultaneousCallSupportMap();
- }
-
- private void updateSimultaneousCallSupportMap() {
- if (!isDeviceSimultaneousCallingCapable) {
- Log.d(LOG_TAG, "Ignoring updateSimultaneousCallSupportMap since device is not DSDA"
- + "capable.");
- return;
- }
- mSimultaneousCallPhoneSupportMap =
- generateSimultaneousCallSupportMap(mVoiceCapablePhoneMap);
- handleSimultaneousCallingSupportChanged();
- }
-
- /**
- * The simultaneous cellular calling slots have changed.
- * @param slotIds The Set of slotIds that have simultaneous cellular calling.
- */
- private void onSimultaneousCellularCallingSlotsChanged(Set<Integer> slotIds) {
- //Cellular calling slots have changed - regenerate simultaneous calling support map:
- updateSimultaneousCallSupportMap();
- }
-
- private void disableSimultaneousCallingSupport() {
- if (!isDeviceSimultaneousCallingCapable) {
- Log.d(LOG_TAG, "Ignoring updateSimultaneousCallSupportMap since device is not DSDA"
- + "capable.");
- return;
- }
- unregisterForImsRegistrationChanges(mVoiceCapablePhoneMap);
-
- // In Single-SIM mode, simultaneous calling is not supported at all:
- mSimultaneousCallPhoneSupportMap.clear();
- mVoiceCapablePhoneMap.clear();
- }
-
- /**
- * Registers a listener to receive IMS registration changes for all phones in the phoneMap.
- *
- * @param phoneMap Map of voice capable phones mapped to the set of phones each has a compatible
- * user association with.
- */
- private void registerForImsRegistrationChanges(Map<Phone, Set<Phone>> phoneMap) {
- for (Phone phone : phoneMap.keySet()) {
- ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
- if (imsPhone != null) {
- Log.v(LOG_TAG, "registerForImsRegistrationChanges: registering phoneId = " +
- phone.getPhoneId());
- imsPhone.registerForImsRegistrationChanges(mHandler,
- EVENT_IMS_REGISTRATION_CHANGED, null);
- } else {
- Log.v(LOG_TAG, "registerForImsRegistrationChanges: phone not recognized as "
- + "ImsPhone: phoneId = " + phone.getPhoneId());
- }
- }
- }
-
- /**
- * Unregisters the listener to stop receiving IMS registration changes for all phones in the
- * phoneMap.
- *
- * @param phoneMap Map of voice capable phones mapped to the set of phones each has a compatible
- * user association with.
- */
- private void unregisterForImsRegistrationChanges(Map<Phone, Set<Phone>> phoneMap) {
- for (Phone phone : phoneMap.keySet()) {
- ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
- if (imsPhone != null) {
- imsPhone.unregisterForImsRegistrationChanges(mHandler);
- }
- }
- }
-
- /**
- * Generates mVoiceCapablePhoneMap by iterating through {@link PhoneFactory#getPhones()} and
- * checking whether each {@link Phone} corresponds to a valid and voice capable subscription.
- * Maps the voice capable phones to the other voice capable phones that have compatible user
- * associations
- */
- private Map<Phone, Set<Phone>> generateVoiceCapablePhoneMapBasedOnUserAssociation() {
- Map<Phone, Set<Phone>> voiceCapablePhoneMap = new HashMap<>(3);
-
- // Generate a map of phone slots that corresponds to valid and voice capable subscriptions:
- Phone[] allPhones = PhoneFactory.getPhones();
- for (Phone phone : allPhones) {
- int subId = phone.getSubId();
- SubscriptionInfo subInfo =
- SubscriptionManagerService.getInstance().getSubscriptionInfo(subId);
-
- if (mFeatureFlags.dataOnlyCellularService() &&
- subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID && subInfo != null &&
- subInfo.getServiceCapabilities()
- .contains(SubscriptionManager.SERVICE_CAPABILITY_VOICE)) {
- Log.v(LOG_TAG, "generateVoiceCapablePhoneMapBasedOnUserAssociation: adding "
- + "phoneId = " + phone.getPhoneId());
- voiceCapablePhoneMap.put(phone, new HashSet<>(3));
- }
- }
-
- Map<Phone, Set<Phone>> userAssociationPhoneMap = new HashMap<>(3);
- // Map the voice capable phones to the others that have compatible user associations:
- for (Phone phone1 : voiceCapablePhoneMap.keySet()) {
- Set<Phone> phone1UserAssociationCompatiblePhones = new HashSet<>(3);
- for (Phone phone2 : voiceCapablePhoneMap.keySet()) {
- if (phone1.getPhoneId() == phone2.getPhoneId()) { continue; }
- if (phonesHaveSameUserAssociation(phone1, phone2)) {
- phone1UserAssociationCompatiblePhones.add(phone2);
- }
- }
- userAssociationPhoneMap.put(phone1, phone1UserAssociationCompatiblePhones);
- }
-
- return userAssociationPhoneMap;
- }
-
- private Map<Integer, Set<Phone>> generateSimultaneousCallSupportMap(
- Map<Phone, Set<Phone>> phoneMap) {
- Map<Integer, Set<Phone>> simultaneousCallSubSupportMap = new HashMap<>(3);
-
- // Initially populate simultaneousCallSubSupportMap based on the passed in phoneMap:
- for (Phone phone : phoneMap.keySet()) {
- simultaneousCallSubSupportMap.put(phone.getPhoneId(),
- new HashSet<>(phoneMap.get(phone)));
- }
-
- // Remove phone combinations that don't support simultaneous calling from the support map:
- for (Phone phone : phoneMap.keySet()) {
- if (phone.isImsRegistered()) {
- if (mPhoneConfigurationManager.isVirtualDsdaEnabled() ||
- phone.isImsServiceSimultaneousCallingSupportCapable(mContext)) {
- // Check if the transport types of each phone support simultaneous IMS calling:
- int phone1TransportType = ((ImsPhone) phone.getImsPhone()).getTransportType();
- if (phone1TransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
- // The transport type of this phone is WLAN so all combos are supported:
- continue;
- }
- for (Phone phone2 : phoneMap.keySet()) {
- if (phone.getPhoneId() == phone2.getPhoneId()) { continue; }
- if (!phonesSupportSimultaneousCallingViaCellularOrWlan(phone, phone2)) {
- simultaneousCallSubSupportMap.get(phone.getPhoneId()).remove(phone2);
- }
- }
- } else {
- // IMS is registered, vDSDA is disabled, but IMS is not DSDA capable so
- // clear the map for this phone:
- simultaneousCallSubSupportMap.get(phone.getPhoneId()).clear();
- }
- } else {
- // Check if this phone supports simultaneous cellular calling with other phones:
- for (Phone phone2 : phoneMap.keySet()) {
- if (phone.getPhoneId() == phone2.getPhoneId()) { continue; }
- if (!phonesSupportSimultaneousCallingViaCellularOrWlan(phone, phone2)) {
- simultaneousCallSubSupportMap.get(phone.getPhoneId()).remove(phone2);
- }
- }
- }
- }
- Log.v(LOG_TAG, "generateSimultaneousCallSupportMap: returning "
- + "simultaneousCallSubSupportMap = " +
- getStringFromMap(simultaneousCallSubSupportMap));
- return simultaneousCallSubSupportMap;
- }
-
- /**
- * Determines whether the {@link Phone} instances have compatible user associations. To be
- * considered compatible based on user association, both must be associated with the same
- * {@link android.os.UserHandle} or both must be unassociated.
- */
- private boolean phonesHaveSameUserAssociation(Phone phone1, Phone phone2) {
- return Objects.equals(phone1.getUserHandle(), phone2.getUserHandle());
- }
-
- private boolean phonesSupportCellularSimultaneousCalling(Phone phone1, Phone phone2) {
- Set<Integer> slotsSupportingSimultaneousCellularCalls =
- mPhoneConfigurationManager.getSlotsSupportingSimultaneousCellularCalls();
- Log.v(LOG_TAG, "phonesSupportCellularSimultaneousCalling: modem returned slots = " +
- getStringFromSet(slotsSupportingSimultaneousCellularCalls));
- if (slotsSupportingSimultaneousCellularCalls.contains(phone1.getPhoneId()) &&
- slotsSupportingSimultaneousCellularCalls.contains(phone2.getPhoneId())) {
- return true;
- };
- return false;
- }
-
- private boolean phonesSupportSimultaneousCallingViaCellularOrWlan(Phone phone1, Phone phone2) {
- int phone2TransportType =
- ((ImsPhone) phone2.getImsPhone()).getTransportType();
- return phone2TransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN ||
- phonesSupportCellularSimultaneousCalling(phone1, phone2);
- }
-
- private void handleSimultaneousCallingSupportChanged() {
- try {
- Log.v(LOG_TAG, "handleSimultaneousCallingSupportChanged");
- // Convert mSimultaneousCallPhoneSupportMap to a map of each subId to a set of the
- // subIds it supports simultaneous calling with:
- Map<Integer, Set<Integer>> simultaneousCallSubscriptionIdMap = new HashMap<>();
- for (Integer phoneId : mSimultaneousCallPhoneSupportMap.keySet()) {
- Phone phone = PhoneFactory.getPhone(phoneId);
- if (phone == null) {
- Log.wtf(LOG_TAG, "handleSimultaneousCallingSupportChanged: phoneId=" +
- phoneId + " not found.");
- return;
- }
- int subId = phone.getSubId();
- Set<Integer> supportedSubscriptionIds = new HashSet<>(3);
- for (Phone p : mSimultaneousCallPhoneSupportMap.get(phoneId)) {
- supportedSubscriptionIds.add(p.getSubId());
- }
- simultaneousCallSubscriptionIdMap.put(subId, supportedSubscriptionIds);
- }
-
- // Notify listeners that simultaneous calling support has changed:
- for (Listener l : mListeners) {
- l.onSimultaneousCallingSupportChanged(simultaneousCallSubscriptionIdMap);
- }
- } catch (Exception e) {
- Log.w(LOG_TAG, "handleVideoCapabilitiesChanged: Exception = " + e);
- }
- }
-
- private String getStringFromMap(Map<Integer, Set<Phone>> phoneMap) {
- StringBuilder sb = new StringBuilder();
- for (Map.Entry<Integer, Set<Phone>> entry : phoneMap.entrySet()) {
- sb.append("Phone ID=");
- sb.append(entry.getKey());
- sb.append(" - Simultaneous calling compatible phone IDs=[");
- sb.append(entry.getValue().stream().map(Phone::getPhoneId).map(String::valueOf)
- .collect(Collectors.joining(", ")));
- sb.append("]; ");
- }
- return sb.toString();
- }
-
- private String getStringFromSet(Set<Integer> integerSet) {
- return integerSet.stream().map(String::valueOf).collect(Collectors.joining(","));
- }
-}
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index a6bb1d6..f4f632e 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony.imsphone;
-import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
import static android.telephony.ims.ImsManager.EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE;
import static android.telephony.ims.ImsManager.EXTRA_WFC_REGISTRATION_FAILURE_TITLE;
import static android.telephony.ims.RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED;
@@ -289,8 +288,6 @@
private final RegistrantList mSilentRedialRegistrants = new RegistrantList();
- private final RegistrantList mImsRegistrationUpdateRegistrants = new RegistrantList();
-
private final LocalLog mRegLocalLog = new LocalLog(64);
private TelephonyMetrics mMetrics;
@@ -314,7 +311,6 @@
private @RegistrationManager.SuggestedAction int mImsRegistrationSuggestedAction;
private @ImsRegistrationImplBase.ImsRegistrationTech int mImsDeregistrationTech =
REGISTRATION_TECH_NONE;
- private @AccessNetworkConstants.TransportType int mTransportType = TRANSPORT_TYPE_INVALID;
private int mImsRegistrationCapabilities;
private boolean mNotifiedRegisteredState;
@@ -1666,14 +1662,6 @@
}
}
- public void registerForImsRegistrationChanges(Handler h, int what, Object obj) {
- mImsRegistrationUpdateRegistrants.addUnique(h, what, obj);
- }
-
- public void unregisterForImsRegistrationChanges(Handler h) {
- mImsRegistrationUpdateRegistrants.remove(h);
- }
-
@Override
public void registerForSilentRedial(Handler h, int what, Object obj) {
mSilentRedialRegistrants.addUnique(h, what, obj);
@@ -2480,7 +2468,7 @@
int subId = getSubId();
if (SubscriptionManager.isValidSubscriptionId(subId)) {
updateImsRegistrationInfo(REGISTRATION_STATE_NOT_REGISTERED,
- REGISTRATION_TECH_NONE, SUGGESTED_ACTION_NONE, TRANSPORT_TYPE_INVALID);
+ REGISTRATION_TECH_NONE, SUGGESTED_ACTION_NONE);
}
}
@@ -2488,13 +2476,13 @@
ImsRegistrationCallbackHelper.ImsRegistrationUpdate() {
@Override
public void handleImsRegistered(@NonNull ImsRegistrationAttributes attributes) {
- int imsTransportType = attributes.getTransportType();
+ int imsRadioTech = attributes.getTransportType();
if (DBG) {
- logd("handleImsRegistered: onImsMmTelConnected imsTransportType="
- + AccessNetworkConstants.transportTypeToString(imsTransportType));
+ logd("handleImsRegistered: onImsMmTelConnected imsRadioTech="
+ + AccessNetworkConstants.transportTypeToString(imsRadioTech));
}
- mRegLocalLog.log("handleImsRegistered: onImsMmTelConnected imsTransportType="
- + AccessNetworkConstants.transportTypeToString(imsTransportType));
+ mRegLocalLog.log("handleImsRegistered: onImsMmTelConnected imsRadioTech="
+ + AccessNetworkConstants.transportTypeToString(imsRadioTech));
setServiceState(ServiceState.STATE_IN_SERVICE);
getDefaultPhone().setImsRegistrationState(true);
mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.CONNECTED, null);
@@ -2502,10 +2490,7 @@
mImsNrSaModeHandler.onImsRegistered(
attributes.getRegistrationTechnology(), attributes.getFeatureTags());
updateImsRegistrationInfo(REGISTRATION_STATE_REGISTERED,
- attributes.getRegistrationTechnology(), SUGGESTED_ACTION_NONE,
- imsTransportType);
- AsyncResult ar = new AsyncResult(null, null, null);
- mImsRegistrationUpdateRegistrants.notifyRegistrants(ar);
+ attributes.getRegistrationTechnology(), SUGGESTED_ACTION_NONE);
}
@Override
@@ -2521,8 +2506,6 @@
mMetrics.writeOnImsConnectionState(mPhoneId, ImsConnectionState.State.PROGRESSING,
null);
mImsStats.onImsRegistering(imsRadioTech);
- AsyncResult ar = new AsyncResult(null, null, null);
- mImsRegistrationUpdateRegistrants.notifyRegistrants(ar);
}
@Override
@@ -2557,15 +2540,13 @@
}
}
updateImsRegistrationInfo(REGISTRATION_STATE_NOT_REGISTERED,
- imsRadioTech, suggestedModemAction, TRANSPORT_TYPE_INVALID);
+ imsRadioTech, suggestedModemAction);
if (mFeatureFlags.clearCachedImsPhoneNumberWhenDeviceLostImsRegistration()) {
// Clear the phone number from P-Associated-Uri
setCurrentSubscriberUris(null);
clearPhoneNumberForSourceIms();
}
- AsyncResult ar = new AsyncResult(null, null, null);
- mImsRegistrationUpdateRegistrants.notifyRegistrants(ar);
}
@Override
@@ -2704,11 +2685,6 @@
return mImsStats;
}
- /** Returns the {@link AccessNetworkConstants.TransportType} used to register this IMS phone. */
- public @AccessNetworkConstants.TransportType int getTransportType() {
- return mTransportType;
- }
-
/** Sets the {@link ImsStats} mock for this IMS phone during unit testing. */
@VisibleForTesting
public void setImsStats(ImsStats imsStats) {
@@ -2759,8 +2735,7 @@
private void updateImsRegistrationInfo(
@RegistrationManager.ImsRegistrationState int regState,
@ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech,
- @RegistrationManager.SuggestedAction int suggestedAction,
- @AccessNetworkConstants.TransportType int transportType) {
+ @RegistrationManager.SuggestedAction int suggestedAction) {
if (regState == mImsRegistrationState) {
// In NOT_REGISTERED state, the current PLMN can be blocked with a suggested action.
@@ -2786,7 +2761,6 @@
mDefaultPhone.mCi.updateImsRegistrationInfo(regState, imsRadioTech, 0,
mImsRegistrationCapabilities, null);
mImsRegistrationTech = imsRadioTech;
- mTransportType = transportType;
mNotifiedRegisteredState = true;
return;
}
@@ -2794,7 +2768,6 @@
mImsRegistrationState = regState;
mImsRegistrationTech = imsRadioTech;
- mTransportType = transportType;
mImsRegistrationSuggestedAction = suggestedAction;
if (regState == REGISTRATION_STATE_NOT_REGISTERED) {
mImsDeregistrationTech = imsRadioTech;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimultaneousCallingTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SimultaneousCallingTrackerTest.java
deleted file mode 100644
index d3fde34..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/SimultaneousCallingTrackerTest.java
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Message;
-import android.os.UserHandle;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.ModemInfo;
-import android.telephony.PhoneCapability;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyRegistryManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.telephony.flags.FeatureFlags;
-import com.android.internal.telephony.imsphone.ImsPhone;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class SimultaneousCallingTrackerTest extends TelephonyTest {
- // Mocked classes
- Handler mHandler;
- CommandsInterface mMockCi0;
- CommandsInterface mMockCi1;
- CommandsInterface mMockCi2;
- private Phone mPhone1; // mPhone as phone 0 is already defined in TelephonyTest.
- private Phone mPhone2;
- private SubscriptionInfo mSubInfo;
- private ImsPhone mImsPhone;
- private ImsPhone mImsPhone1;
- private ImsPhone mImsPhone2;
- PhoneConfigurationManager.MockableInterface mMi;
- private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 1;
- private static final PhoneCapability STATIC_DSDA_CAPABILITY;
- private static final Set<Integer> STATIC_SERVICE_CAPABILITIES;
-
- static {
- ModemInfo modemInfo1 = new ModemInfo(0, 0, true, true);
- ModemInfo modemInfo2 = new ModemInfo(1, 0, true, true);
-
- List<ModemInfo> logicalModemList = new ArrayList<>();
- logicalModemList.add(modemInfo1);
- logicalModemList.add(modemInfo2);
- int[] deviceNrCapabilities = new int[0];
-
- STATIC_DSDA_CAPABILITY = new PhoneCapability(2, 1, logicalModemList, false,
- deviceNrCapabilities);
-
- STATIC_SERVICE_CAPABILITIES = new HashSet<>(1);
- STATIC_SERVICE_CAPABILITIES.add(SubscriptionManager.SERVICE_CAPABILITY_VOICE);
- }
- PhoneConfigurationManager mPcm;
- SimultaneousCallingTracker mSct;
-
- private FeatureFlags mFeatureFlags;
- private TelephonyRegistryManager mMockRegistryManager;
-
- @Before
- public void setUp() throws Exception {
- super.setUp(getClass().getSimpleName());
- mHandler = mock(Handler.class);
- mMockCi0 = mock(CommandsInterface.class);
- mMockCi1 = mock(CommandsInterface.class);
- mMockCi2 = mock(CommandsInterface.class);
- mFeatureFlags = mock(FeatureFlags.class);
- mPhone1 = mock(Phone.class);
- mPhone2 = mock(Phone.class);
- mImsPhone = mock(ImsPhone.class);
- mImsPhone1 = mock(ImsPhone.class);
- mImsPhone2 = mock(ImsPhone.class);
- mSubInfo = mock(SubscriptionInfo.class);
- doReturn(mImsPhone).when(mPhone).getImsPhone();
- doReturn(mImsPhone1).when(mPhone1).getImsPhone();
- doReturn(mImsPhone2).when(mPhone2).getImsPhone();
- mMi = mock(PhoneConfigurationManager.MockableInterface.class);
- mPhone.mCi = mMockCi0;
- mCT.mCi = mMockCi0;
- mPhone1.mCi = mMockCi1;
- mPhone2.mCi = mMockCi2;
- doReturn(0).when(mPhone).getPhoneId();
- doReturn(10).when(mPhone).getSubId();
- doReturn(1).when(mPhone1).getPhoneId();
- // This will be updated to 11 during each test in order to trigger onSubscriptionChanged:
- doReturn(110).when(mPhone1).getSubId();
- doReturn(2).when(mPhone2).getPhoneId();
- doReturn(12).when(mPhone2).getSubId();
- doReturn(STATIC_SERVICE_CAPABILITIES).when(mSubInfo).getServiceCapabilities();
- doReturn(mSubInfo).when(mSubscriptionManagerService)
- .getSubscriptionInfo(any(Integer.class));
- doReturn(RIL.RADIO_HAL_VERSION_2_2).when(mMockRadioConfigProxy).getVersion();
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
- doReturn(true).when(mFeatureFlags).dataOnlyCellularService();
- mMockRegistryManager = mContext.getSystemService(TelephonyRegistryManager.class);
- }
-
- @After
- public void tearDown() throws Exception {
- mPcm = null;
- mSct = null;
- mPhone1 = null;
- mPhone2 = null;
- super.tearDown();
- }
-
- /**
- * @param numOfSim the current number of SIM subscriptions
- */
- private void init(int numOfSim) throws Exception {
- doReturn(numOfSim).when(mTelephonyManager).getActiveModemCount();
- replaceInstance(SimultaneousCallingTracker.class, "sInstance", null, null);
- replaceInstance(PhoneConfigurationManager.class, "sInstance", null, null);
- switch (numOfSim) {
- case 0 -> mPhones = new Phone[]{};
- case 1 -> mPhones = new Phone[]{mPhone};
- case 2 -> mPhones = new Phone[]{mPhone, mPhone1};
- case 3 -> mPhones = new Phone[]{mPhone, mPhone1, mPhone2};
- }
- replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
- mPcm = PhoneConfigurationManager.init(mContext, mFeatureFlags);
- mSct = SimultaneousCallingTracker.init(mContext, mFeatureFlags);
- replaceInstance(PhoneConfigurationManager.class, "mMi", mPcm, mMi);
- processAllMessages();
- }
-
- private void setRebootRequiredForConfigSwitch(boolean rebootRequired) {
- doReturn(rebootRequired).when(mMi).isRebootRequiredForModemConfigChange();
- }
-
- private void setAndVerifyStaticCapability(PhoneCapability capability) {
- mPcm.getCurrentPhoneCapability();
- ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
- verify(mMockRadioConfig).getPhoneCapability(captor.capture());
- Message msg = captor.getValue();
- AsyncResult.forMessage(msg, capability, null);
- msg.sendToTarget();
- processAllMessages();
-
- assertEquals(capability, mPcm.getStaticPhoneCapability());
- assertTrue(mSct.isDeviceSimultaneousCallingCapable);
-
- }
-
- private void setAndVerifySlotsSupportingSimultaneousCellularCalling(int[] enabledLogicalSlots) {
- ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
- verify(mMockRadioConfig).updateSimultaneousCallingSupport(captor.capture());
- Message msg = captor.getValue();
- AsyncResult.forMessage(msg, enabledLogicalSlots, null);
- msg.sendToTarget();
- processAllMessages();
-
- HashSet<Integer> expectedSlots = new HashSet<>();
- for (int i : enabledLogicalSlots) { expectedSlots.add(i); }
- assertEquals(expectedSlots, mPcm.getSlotsSupportingSimultaneousCellularCalls());
- }
-
- private void updateSubId(Phone phone, int newSubId) {
- ArgumentCaptor<SubscriptionManager.OnSubscriptionsChangedListener> cBCaptorList =
- ArgumentCaptor.forClass(SubscriptionManager.OnSubscriptionsChangedListener.class);
- verify(mMockRegistryManager, times(2))
- .addOnSubscriptionsChangedListener(cBCaptorList.capture(), any());
-
- // Change sub ID mapping
- doReturn(newSubId).when(phone).getSubId();
- List<SubscriptionManager.OnSubscriptionsChangedListener> listeners =
- cBCaptorList.getAllValues();
- listeners.get(0).onSubscriptionsChanged();
- listeners.get(1).onSubscriptionsChanged();
- processAllMessages();
- }
-
- /**
- * Test that simultaneous calling is not supported when the device is only capable of a max
- * active voice count of 1.
- */
- @Test
- @SmallTest
- public void testDeviceNotSimultaneousCallingCapable() throws Exception {
- init(1);
- assertFalse(mSct.isDeviceSimultaneousCallingCapable);
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(10).size());
- }
-
- /**
- * Test that simultaneous calling is not supported when the subscriptions have different user
- * associations.
- */
- @Test
- @SmallTest
- public void testDifferentUserAssociations_SimultaneousCallingDisabled() throws Exception {
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
-
- //Assign each phone to a different user which should disable simultaneous calling:
- doReturn(new UserHandle(123)).when(mPhone).getUserHandle();
- doReturn(new UserHandle(321)).when(mPhone1).getUserHandle();
-
- init(2);
- setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
-
- int[] enabledLogicalSlots = {0, 1};
- setAndVerifySlotsSupportingSimultaneousCellularCalling(enabledLogicalSlots);
-
- // Trigger onSubscriptionsChanged by updating the subscription ID of a phone slot:
- updateSubId(mPhone1, 11);
-
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(10).size());
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(11).size());
- }
-
- /**
- * Test that simultaneous calling is not supported when IMS is not registered and cellular
- * simultaneous calling is only supported for one SIM subscription.
- */
- @Test
- @SmallTest
- public void testCellularDSDANotSupported_SimultaneousCallingDisabled() throws Exception {
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
-
- init(2);
- setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
-
- // Have the modem inform telephony that only phone slot 0 supports DSDA:
- int[] enabledLogicalSlots = {0};
- setAndVerifySlotsSupportingSimultaneousCellularCalling(enabledLogicalSlots);
-
- // Trigger onSubscriptionsChanged by updating the subscription ID of a phone slot:
- updateSubId(mPhone1, 11);
-
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(10).size());
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(11).size());
- }
-
- /**
- * Test that simultaneous calling is supported when IMS is not registered and cellular
- * simultaneous calling is supported for both SIM subscription.
- */
- @Test
- @SmallTest
- public void testCellularDSDASupported_SimultaneousCallingEnabled() throws Exception {
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
-
- init(2);
- setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
-
- int[] enabledLogicalSlots = {0, 1};
- setAndVerifySlotsSupportingSimultaneousCellularCalling(enabledLogicalSlots);
-
- // Trigger onSubscriptionsChanged by updating the subscription ID of a phone slot:
- updateSubId(mPhone1, 11);
-
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(10).contains(11));
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(11).contains(10));
- }
-
- /**
- * Test that simultaneous calling is supported when IMS is not registered and cellular
- * simultaneous calling is supported for both SIM subscription. Then test that simultaneous
- * calling is not supported after a multi SIM config change to single-SIM.
- */
- @Test
- @SmallTest
- public void testSingleSimSwitch_SimultaneousCallingDisabled() throws Exception {
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
-
- init(2);
- setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
-
- int[] enabledLogicalSlots = {0, 1};
- setAndVerifySlotsSupportingSimultaneousCellularCalling(enabledLogicalSlots);
-
- // Trigger onSubscriptionsChanged by updating the subscription ID of a phone slot:
- updateSubId(mPhone1, 11);
-
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(10).contains(11));
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(11).contains(10));
-
- // Register for multi SIM config change.
- mPcm.registerForMultiSimConfigChange(mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
- verify(mHandler, never()).sendMessageAtTime(any(), anyLong());
-
- // Switch to single sim.
- setRebootRequiredForConfigSwitch(false);
- mPcm.switchMultiSimConfig(1);
- ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
- verify(mMockRadioConfig).setNumOfLiveModems(eq(1), captor.capture());
-
- // Send message back to indicate switch success.
- Message message = captor.getValue();
- AsyncResult.forMessage(message, null, null);
- message.sendToTarget();
- processAllMessages();
-
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(10).size());
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(11).size());
- }
-
- /**
- * Test that simultaneous calling is not supported when IMS is registered, vDSDA is disabled,
- * but ImsService#CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING is not set.
- */
- @Test
- @SmallTest
- public void testImsDSDANotSupported_SimultaneousCallingDisabled() throws Exception {
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
- doReturn(true).when(mPhone).isImsRegistered();
- doReturn(true).when(mPhone1).isImsRegistered();
- doReturn(false).when(mPhone)
- .isImsServiceSimultaneousCallingSupportCapable(any(Context.class));
- doReturn(false).when(mPhone1)
- .isImsServiceSimultaneousCallingSupportCapable(any(Context.class));
-
- init(2);
- setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
-
- int[] enabledLogicalSlots = {0, 1};
- setAndVerifySlotsSupportingSimultaneousCellularCalling(enabledLogicalSlots);
-
- // Trigger onSubscriptionsChanged by updating the subscription ID of a phone slot:
- updateSubId(mPhone1, 11);
-
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(10).size());
- assertEquals(0, mSct.getSubIdsSupportingSimultaneousCalling(11).size());
- }
-
- /**
- * Test that simultaneous calling is supported when IMS is registered, vDSDA is enabled,
- * and the IMS transport type of each SIM subscription is WLAN.
- */
- //TODO: Implement a way to set vDSDAEnabled to true and then re-enable this test
- @Ignore
- @Test
- @SmallTest
- public void testImsVDSDAEnabledTransportTypeWLAN_SimultaneousCallingEnabled() throws Exception {
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
- doReturn(true).when(mPhone).isImsRegistered();
- doReturn(true).when(mPhone1).isImsRegistered();
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mImsPhone).getTransportType();
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mImsPhone1).getTransportType();
-
- init(2);
- setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
-
- int[] enabledLogicalSlots = {0};
- setAndVerifySlotsSupportingSimultaneousCellularCalling(enabledLogicalSlots);
-
- // Trigger onSubscriptionsChanged by updating the subscription ID of a phone slot:
- updateSubId(mPhone1, 11);
-
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(10).contains(11));
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(11).contains(10));
- }
-
- /**
- * Test that simultaneous calling is supported when IMS is registered, vDSDA is disabled,
- * ImsService#CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING is set and the IMS transport type of each
- * SIM subscription is WLAN.
- */
- @Test
- @SmallTest
- public void testImsVDSDADisabledTransportTypeWLAN_SimultaneousCallingEnabled()
- throws Exception {
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
- doReturn(true).when(mPhone).isImsRegistered();
- doReturn(true).when(mPhone1).isImsRegistered();
- doReturn(true).when(mPhone)
- .isImsServiceSimultaneousCallingSupportCapable(any(Context.class));
- doReturn(true).when(mPhone1)
- .isImsServiceSimultaneousCallingSupportCapable(any(Context.class));
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mImsPhone).getTransportType();
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mImsPhone1).getTransportType();
-
- init(2);
- setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
-
- int[] enabledLogicalSlots = {0, 1};
- setAndVerifySlotsSupportingSimultaneousCellularCalling(enabledLogicalSlots);
-
- // Trigger onSubscriptionsChanged by updating the subscription ID of a phone slot:
- updateSubId(mPhone1, 11);
-
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(10).contains(11));
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(11).contains(10));
- }
-
- /**
- * Test that simultaneous calling is supported between all subs in the following 3-SIM case:
- * SIM A: IMS Unregistered, vDSDA Disabled
- * SIM B: IMS WWAN Registered, vDSDA Disabled, CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING not set
- * SIM C: IMS WLAN Registered, vDSDA Disabled, CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING set
- */
- @Test
- @SmallTest
- public void testThreeSimCase_SimultaneousCallingEnabled() throws Exception {
- doReturn(true).when(mFeatureFlags).simultaneousCallingIndications();
- doReturn(false).when(mPhone).isImsRegistered();
- doReturn(true).when(mPhone1).isImsRegistered();
- doReturn(true).when(mPhone2).isImsRegistered();
- doReturn(true).when(mPhone1)
- .isImsServiceSimultaneousCallingSupportCapable(any(Context.class));
- doReturn(true).when(mPhone2)
- .isImsServiceSimultaneousCallingSupportCapable(any(Context.class));
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mImsPhone1).getTransportType();
- doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mImsPhone2).getTransportType();
-
- init(3);
- setAndVerifyStaticCapability(STATIC_DSDA_CAPABILITY);
-
- int[] enabledLogicalSlots = {0, 1};
- setAndVerifySlotsSupportingSimultaneousCellularCalling(enabledLogicalSlots);
-
- // Trigger onSubscriptionsChanged by updating the subscription ID of a phone slot:
- updateSubId(mPhone1, 11);
-
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(10)
- .containsAll(Arrays.asList(11,12)));
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(11)
- .containsAll(Arrays.asList(10,12)));
- assertTrue(mSct.getSubIdsSupportingSimultaneousCalling(12)
- .containsAll(Arrays.asList(10,11)));
- }
-}