Loading src/java/com/android/internal/telephony/PhoneConfigurationManager.java +93 −2 Original line number Original line Diff line number Diff line Loading @@ -43,8 +43,10 @@ import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.telephony.Rlog; import com.android.telephony.Rlog; import java.util.HashMap; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map; import java.util.NoSuchElementException; import java.util.NoSuchElementException; import java.util.Set; /** /** * This class manages phone's configuration which defines the potential capability (static) of the * This class manages phone's configuration which defines the potential capability (static) of the Loading @@ -65,10 +67,14 @@ public class PhoneConfigurationManager { private static final int EVENT_GET_MODEM_STATUS_DONE = 102; private static final int EVENT_GET_MODEM_STATUS_DONE = 102; private static final int EVENT_GET_PHONE_CAPABILITY_DONE = 103; private static final int EVENT_GET_PHONE_CAPABILITY_DONE = 103; private static final int EVENT_DEVICE_CONFIG_CHANGED = 104; private static final int EVENT_DEVICE_CONFIG_CHANGED = 104; private static final int EVENT_GET_SIMULTANEOUS_CALLING_SUPPORT_DONE = 105; private static final int EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED = 106; private static PhoneConfigurationManager sInstance = null; private static PhoneConfigurationManager sInstance = null; private final Context mContext; private final Context mContext; private PhoneCapability mStaticCapability; private PhoneCapability mStaticCapability; private Set<Integer> mSlotsSupportingSimultaneousCellularCalls = new HashSet<>(); private final RadioConfig mRadioConfig; private final RadioConfig mRadioConfig; private final Handler mHandler; private final Handler mHandler; // mPhones is obtained from PhoneFactory and can have phones corresponding to inactive modems as // mPhones is obtained from PhoneFactory and can have phones corresponding to inactive modems as Loading Loading @@ -152,18 +158,36 @@ public class PhoneConfigurationManager { } } } } // If virtual DSDA is enabled for this UE, then updates maxActiveVoiceSubscriptions to 2. /** * If virtual DSDA is enabled for this UE, then increase maxActiveVoiceSubscriptions to 2. */ private PhoneCapability maybeUpdateMaxActiveVoiceSubscriptions( private PhoneCapability maybeUpdateMaxActiveVoiceSubscriptions( final PhoneCapability staticCapability) { final PhoneCapability staticCapability) { if (staticCapability.getLogicalModemList().size() > 1 && mVirtualDsdaEnabled) { if (staticCapability.getLogicalModemList().size() > 1 && mVirtualDsdaEnabled) { // Since we already initialized maxActiveVoiceSubscriptions to the count the // modem is capable of, vDSDA is only able to increase that count via this method. We do // not allow vDSDA to decrease maxActiveVoiceSubscriptions: int updatedMaxActiveVoiceSubscriptions = Math.max(staticCapability.getMaxActiveVoiceSubscriptions(), 2); return new PhoneCapability.Builder(staticCapability) return new PhoneCapability.Builder(staticCapability) .setMaxActiveVoiceSubscriptions(2) .setMaxActiveVoiceSubscriptions(updatedMaxActiveVoiceSubscriptions) .build(); .build(); } else { } else { return staticCapability; return staticCapability; } } } } private void maybeEnableCellularDSDASupport() { if (mRadioConfig != null && mRadioConfig.getRadioConfigProxy(null) .getVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_2_2) && getPhoneCount() > 1 && mStaticCapability.getMaxActiveVoiceSubscriptions() > 1) { updateSimultaneousCallingSupport(); mRadioConfig.registerForSimultaneousCallingSupportStatusChanged(mHandler, EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED, null); } } /** /** * Static method to get instance. * Static method to get instance. */ */ Loading Loading @@ -223,6 +247,7 @@ public class PhoneConfigurationManager { if (ar != null && ar.exception == null) { if (ar != null && ar.exception == null) { mStaticCapability = (PhoneCapability) ar.result; mStaticCapability = (PhoneCapability) ar.result; notifyCapabilityChanged(); notifyCapabilityChanged(); maybeEnableCellularDSDASupport(); } else { } else { log(msg.what + " failure. Not getting phone capability." + ar.exception); log(msg.what + " failure. Not getting phone capability." + ar.exception); } } Loading @@ -236,6 +261,41 @@ public class PhoneConfigurationManager { mVirtualDsdaEnabled = isVirtualDsdaEnabled; mVirtualDsdaEnabled = isVirtualDsdaEnabled; } } break; break; case EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED: case EVENT_GET_SIMULTANEOUS_CALLING_SUPPORT_DONE: log("Received EVENT_SLOTS_SUPPORTING_SIMULTANEOUS_CALL_CHANGED/DONE"); if (getPhoneCount() < 2) { if (!mSlotsSupportingSimultaneousCellularCalls.isEmpty()) { mSlotsSupportingSimultaneousCellularCalls.clear(); } break; } ar = (AsyncResult) msg.obj; if (ar != null && ar.exception == null) { int[] returnedIntArray = (int[]) ar.result; if (!mSlotsSupportingSimultaneousCellularCalls.isEmpty()) { mSlotsSupportingSimultaneousCellularCalls.clear(); } int maxValidPhoneSlot = getPhoneCount() - 1; for (int i : returnedIntArray) { if (i < 0 || i > maxValidPhoneSlot) { loge("Invalid slot supporting DSDA =" + i + ". Disabling DSDA."); mSlotsSupportingSimultaneousCellularCalls.clear(); break; } mSlotsSupportingSimultaneousCellularCalls.add(i); } // Ensure the slots supporting cellular DSDA does not exceed the phone count if (mSlotsSupportingSimultaneousCellularCalls.size() > getPhoneCount()) { loge("Invalid size of DSDA slots. Disabling cellular DSDA."); mSlotsSupportingSimultaneousCellularCalls.clear(); break; } } else { log(msg.what + " failure. Not getting logical slots that support " + "simultaneous calling." + ar.exception); } break; default: default: log("Unknown event: " + msg.what); log("Unknown event: " + msg.what); } } Loading Loading @@ -341,6 +401,27 @@ public class PhoneConfigurationManager { return mTelephonyManager.getActiveModemCount(); return mTelephonyManager.getActiveModemCount(); } } @VisibleForTesting public Set<Integer> getSlotsSupportingSimultaneousCellularCalls() { return mSlotsSupportingSimultaneousCellularCalls; } /** * Get the current the list of logical slots supporting simultaneous cellular calling from the * modem based on current network conditions. */ @VisibleForTesting public void updateSimultaneousCallingSupport() { log("updateSimultaneousCallingSupport: sending the request for " + "getting the list of logical slots supporting simultaneous cellular calling"); Message callback = Message.obtain( mHandler, EVENT_GET_SIMULTANEOUS_CALLING_SUPPORT_DONE); mRadioConfig.updateSimultaneousCallingSupport(callback); log("updateSimultaneousCallingSupport: " + "mSlotsSupportingSimultaneousCellularCalls = " + mSlotsSupportingSimultaneousCellularCalls); } /** /** * get static overall phone capabilities for all phones. * get static overall phone capabilities for all phones. */ */ Loading Loading @@ -446,6 +527,16 @@ public class PhoneConfigurationManager { phone.mCi.onSlotActiveStatusChange(SubscriptionManager.isValidPhoneId(phoneId)); phone.mCi.onSlotActiveStatusChange(SubscriptionManager.isValidPhoneId(phoneId)); } } if (numOfActiveModems > 1) { // Check if cellular DSDA is supported. If it is, then send a request to the // modem to refresh the list of SIM slots that currently support DSDA based on // current network conditions maybeEnableCellularDSDASupport(); } else { // The number of active modems is 0 or 1, disable cellular DSDA: mSlotsSupportingSimultaneousCellularCalls.clear(); } // When the user enables DSDS mode, the default VOICE and SMS subId should be switched // When the user enables DSDS mode, the default VOICE and SMS subId should be switched // to "No Preference". Doing so will sync the network/sim settings and telephony. // to "No Preference". Doing so will sync the network/sim settings and telephony. // (see b/198123192) // (see b/198123192) Loading src/java/com/android/internal/telephony/RILUtils.java +17 −6 Original line number Original line Diff line number Diff line Loading @@ -98,6 +98,7 @@ import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_NEIGHB import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_RADIO_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_RADIO_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIMULTANEOUS_CALLING_SUPPORT; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_STATUS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_STATUS; Loading Loading @@ -273,6 +274,7 @@ import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESTRICTED_S import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RIL_CONNECTED; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RIL_CONNECTED; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RINGBACK_TONE; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RINGBACK_TONE; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIGNAL_STRENGTH; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIGNAL_STRENGTH; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIMULTANEOUS_CALLING_SUPPORT_CHANGED; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_REFRESH; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_REFRESH; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_SMS_STORAGE_FULL; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_SMS_STORAGE_FULL; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SLICING_CONFIG_CHANGED; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SLICING_CONFIG_CHANGED; Loading Loading @@ -4381,14 +4383,20 @@ public class RILUtils { public static PhoneCapability convertHalPhoneCapability(int[] deviceNrCapabilities, Object o) { public static PhoneCapability convertHalPhoneCapability(int[] deviceNrCapabilities, Object o) { int maxActiveVoiceCalls = 0; int maxActiveVoiceCalls = 0; int maxActiveData = 0; int maxActiveData = 0; int maxActiveInternetData = 0; boolean validationBeforeSwitchSupported = false; boolean validationBeforeSwitchSupported = false; List<ModemInfo> logicalModemList = new ArrayList<>(); List<ModemInfo> logicalModemList = new ArrayList<>(); if (o instanceof android.hardware.radio.config.PhoneCapability) { if (o instanceof android.hardware.radio.config.PhoneCapability) { final android.hardware.radio.config.PhoneCapability phoneCapability = final android.hardware.radio.config.PhoneCapability phoneCapability = (android.hardware.radio.config.PhoneCapability) o; (android.hardware.radio.config.PhoneCapability) o; maxActiveData = phoneCapability.maxActiveData; maxActiveData = phoneCapability.maxActiveData; maxActiveInternetData = phoneCapability.maxActiveInternetData; // If the maxActiveVoice field has been set, use that value. Otherwise, default to the // legacy behavior and rely on the maxActiveInternetData field: if (phoneCapability.maxActiveVoice == android.hardware.radio.config.PhoneCapability.UNKNOWN) { maxActiveVoiceCalls = phoneCapability.maxActiveInternetData; } else { maxActiveVoiceCalls = phoneCapability.maxActiveVoice; } validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported; validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported; for (int modemId : phoneCapability.logicalModemIds) { for (int modemId : phoneCapability.logicalModemIds) { logicalModemList.add(new ModemInfo(modemId)); logicalModemList.add(new ModemInfo(modemId)); Loading @@ -4397,16 +4405,15 @@ public class RILUtils { final android.hardware.radio.config.V1_1.PhoneCapability phoneCapability = final android.hardware.radio.config.V1_1.PhoneCapability phoneCapability = (android.hardware.radio.config.V1_1.PhoneCapability) o; (android.hardware.radio.config.V1_1.PhoneCapability) o; maxActiveData = phoneCapability.maxActiveData; maxActiveData = phoneCapability.maxActiveData; maxActiveInternetData = phoneCapability.maxActiveInternetData; // maxActiveInternetData defines how many logical modems can have internet PDN // connections simultaneously. For L+L DSDS modem it’s 1, and for DSDA modem it’s 2. maxActiveVoiceCalls = phoneCapability.maxActiveInternetData; validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported; validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported; for (android.hardware.radio.config.V1_1.ModemInfo modemInfo : for (android.hardware.radio.config.V1_1.ModemInfo modemInfo : phoneCapability.logicalModemList) { phoneCapability.logicalModemList) { logicalModemList.add(new ModemInfo(modemInfo.modemId)); logicalModemList.add(new ModemInfo(modemInfo.modemId)); } } } } // maxActiveInternetData defines how many logical modems can have internet PDN connections // simultaneously. For L+L DSDS modem it’s 1, and for DSDA modem it’s 2. maxActiveVoiceCalls = maxActiveInternetData; return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList, return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList, validationBeforeSwitchSupported, deviceNrCapabilities); validationBeforeSwitchSupported, deviceNrCapabilities); } } Loading Loading @@ -5128,6 +5135,8 @@ public class RILUtils { return "SET_LOCATION_PRIVACY_SETTING"; return "SET_LOCATION_PRIVACY_SETTING"; case RIL_REQUEST_GET_LOCATION_PRIVACY_SETTING: case RIL_REQUEST_GET_LOCATION_PRIVACY_SETTING: return "GET_LOCATION_PRIVACY_SETTING"; return "GET_LOCATION_PRIVACY_SETTING"; case RIL_REQUEST_GET_SIMULTANEOUS_CALLING_SUPPORT: return "GET_SIMULTANEOUS_CALLING_SUPPORT"; default: default: return "<unknown request " + request + ">"; return "<unknown request " + request + ">"; } } Loading Loading @@ -5273,6 +5282,8 @@ public class RILUtils { return "UNSOL_TRIGGER_IMS_DEREGISTRATION"; return "UNSOL_TRIGGER_IMS_DEREGISTRATION"; case RIL_UNSOL_IMEI_MAPPING_CHANGED: case RIL_UNSOL_IMEI_MAPPING_CHANGED: return "UNSOL_IMEI_MAPPING_CHANGED"; return "UNSOL_IMEI_MAPPING_CHANGED"; case RIL_UNSOL_SIMULTANEOUS_CALLING_SUPPORT_CHANGED: return "UNSOL_SIMULTANEOUS_CALLING_SUPPORT_CHANGED"; default: default: return "<unknown response " + response + ">"; return "<unknown response " + response + ">"; } } Loading src/java/com/android/internal/telephony/RadioConfig.java +39 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static com.android.internal.telephony.RILConstants.RADIO_NOT_AVAILABLE; import static com.android.internal.telephony.RILConstants.REQUEST_NOT_SUPPORTED; import static com.android.internal.telephony.RILConstants.REQUEST_NOT_SUPPORTED; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIMULTANEOUS_CALLING_SUPPORT; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SLOT_STATUS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SLOT_STATUS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_PREFERRED_DATA_MODEM; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_PREFERRED_DATA_MODEM; Loading Loading @@ -79,6 +80,8 @@ public class RadioConfig extends Handler { protected Registrant mSimSlotStatusRegistrant; protected Registrant mSimSlotStatusRegistrant; protected Registrant mSimultaneousCallingSupportStatusRegistrant; private boolean isMobileDataCapable(Context context) { private boolean isMobileDataCapable(Context context) { final TelephonyManager tm = context.getSystemService(TelephonyManager.class); final TelephonyManager tm = context.getSystemService(TelephonyManager.class); return tm != null && tm.isDataCapable(); return tm != null && tm.isDataCapable(); Loading Loading @@ -477,6 +480,34 @@ public class RadioConfig extends Handler { } } } } /** * Wrapper function for IRadioConfig.getSimultaneousCallingSupport(). */ public void updateSimultaneousCallingSupport(Message result) { RadioConfigProxy proxy = getRadioConfigProxy(null); if (proxy.isEmpty()) return; if (proxy.getVersion().less(RIL.RADIO_HAL_VERSION_2_2)) { if (result != null) { AsyncResult.forMessage(result, null, CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED)); result.sendToTarget(); } return; } RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIMULTANEOUS_CALLING_SUPPORT, result, mDefaultWorkSource); if (DBG) { logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)); } try { proxy.updateSimultaneousCallingSupport(rr.mSerial); } catch (RemoteException | RuntimeException e) { resetProxyAndRequestList("updateSimultaneousCallingSupport", e); } } /** /** * Wrapper function for IRadioConfig.getPhoneCapability(). * Wrapper function for IRadioConfig.getPhoneCapability(). */ */ Loading Loading @@ -565,6 +596,14 @@ public class RadioConfig extends Handler { } } } } /** * Register a handler to get SIM slots that support simultaneous calling changed notifications. */ public void registerForSimultaneousCallingSupportStatusChanged(Handler h, int what, Object obj) { mSimultaneousCallingSupportStatusRegistrant = new Registrant(h, what, obj); } /** /** * Register a handler to get SIM slot status changed notifications. * Register a handler to get SIM slot status changed notifications. */ */ Loading src/java/com/android/internal/telephony/RadioConfigIndicationAidl.java +15 −0 Original line number Original line Diff line number Diff line Loading @@ -17,12 +17,14 @@ package com.android.internal.telephony; package com.android.internal.telephony; import android.os.AsyncResult; import android.os.AsyncResult; import android.os.RemoteException; import android.os.Trace; import android.os.Trace; import com.android.internal.telephony.uicc.IccSlotStatus; import com.android.internal.telephony.uicc.IccSlotStatus; import com.android.telephony.Rlog; import com.android.telephony.Rlog; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; /** /** * This class is the AIDL implementation of IRadioConfigIndication interface. * This class is the AIDL implementation of IRadioConfigIndication interface. Loading Loading @@ -51,6 +53,19 @@ public class RadioConfigIndicationAidl extends } } } } /** * Indication that the logical slots that support simultaneous calling has changed. */ @Override public void onSimultaneousCallingSupportChanged(int[] enabledLogicalSlots) { ArrayList<Integer> ret = RILUtils.primitiveArrayToArrayList(enabledLogicalSlots); logd("onSimultaneousCallingSupportChanged: enabledLogicalSlots = " + ret); if (mRadioConfig.mSimultaneousCallingSupportStatusRegistrant != null) { mRadioConfig.mSimultaneousCallingSupportStatusRegistrant.notifyRegistrant( new AsyncResult(null, ret, null)); } } private static void logd(String log) { private static void logd(String log) { Rlog.d(TAG, "[UNSL]< " + log); Rlog.d(TAG, "[UNSL]< " + log); Trace.instantForTrack(Trace.TRACE_TAG_NETWORK, "RIL", log); Trace.instantForTrack(Trace.TRACE_TAG_NETWORK, "RIL", log); Loading src/java/com/android/internal/telephony/RadioConfigProxy.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -224,6 +224,16 @@ public class RadioConfigProxy { } } } } /** * Wrapper function for IRadioConfig.getSimultaneousCallingSupport() */ public void updateSimultaneousCallingSupport(int serial) throws RemoteException { if (isAidl()) { getAidl().getSimultaneousCallingSupport(serial); } // Only supported on AIDL. } /** /** * Wrapper function for using IRadioConfig.setNumOfLiveModems(int32_t serial, * Wrapper function for using IRadioConfig.setNumOfLiveModems(int32_t serial, * byte numOfLiveModems) to switch between single-sim and multi-sim. * byte numOfLiveModems) to switch between single-sim and multi-sim. Loading Loading
src/java/com/android/internal/telephony/PhoneConfigurationManager.java +93 −2 Original line number Original line Diff line number Diff line Loading @@ -43,8 +43,10 @@ import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.telephony.Rlog; import com.android.telephony.Rlog; import java.util.HashMap; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Map; import java.util.NoSuchElementException; import java.util.NoSuchElementException; import java.util.Set; /** /** * This class manages phone's configuration which defines the potential capability (static) of the * This class manages phone's configuration which defines the potential capability (static) of the Loading @@ -65,10 +67,14 @@ public class PhoneConfigurationManager { private static final int EVENT_GET_MODEM_STATUS_DONE = 102; private static final int EVENT_GET_MODEM_STATUS_DONE = 102; private static final int EVENT_GET_PHONE_CAPABILITY_DONE = 103; private static final int EVENT_GET_PHONE_CAPABILITY_DONE = 103; private static final int EVENT_DEVICE_CONFIG_CHANGED = 104; private static final int EVENT_DEVICE_CONFIG_CHANGED = 104; private static final int EVENT_GET_SIMULTANEOUS_CALLING_SUPPORT_DONE = 105; private static final int EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED = 106; private static PhoneConfigurationManager sInstance = null; private static PhoneConfigurationManager sInstance = null; private final Context mContext; private final Context mContext; private PhoneCapability mStaticCapability; private PhoneCapability mStaticCapability; private Set<Integer> mSlotsSupportingSimultaneousCellularCalls = new HashSet<>(); private final RadioConfig mRadioConfig; private final RadioConfig mRadioConfig; private final Handler mHandler; private final Handler mHandler; // mPhones is obtained from PhoneFactory and can have phones corresponding to inactive modems as // mPhones is obtained from PhoneFactory and can have phones corresponding to inactive modems as Loading Loading @@ -152,18 +158,36 @@ public class PhoneConfigurationManager { } } } } // If virtual DSDA is enabled for this UE, then updates maxActiveVoiceSubscriptions to 2. /** * If virtual DSDA is enabled for this UE, then increase maxActiveVoiceSubscriptions to 2. */ private PhoneCapability maybeUpdateMaxActiveVoiceSubscriptions( private PhoneCapability maybeUpdateMaxActiveVoiceSubscriptions( final PhoneCapability staticCapability) { final PhoneCapability staticCapability) { if (staticCapability.getLogicalModemList().size() > 1 && mVirtualDsdaEnabled) { if (staticCapability.getLogicalModemList().size() > 1 && mVirtualDsdaEnabled) { // Since we already initialized maxActiveVoiceSubscriptions to the count the // modem is capable of, vDSDA is only able to increase that count via this method. We do // not allow vDSDA to decrease maxActiveVoiceSubscriptions: int updatedMaxActiveVoiceSubscriptions = Math.max(staticCapability.getMaxActiveVoiceSubscriptions(), 2); return new PhoneCapability.Builder(staticCapability) return new PhoneCapability.Builder(staticCapability) .setMaxActiveVoiceSubscriptions(2) .setMaxActiveVoiceSubscriptions(updatedMaxActiveVoiceSubscriptions) .build(); .build(); } else { } else { return staticCapability; return staticCapability; } } } } private void maybeEnableCellularDSDASupport() { if (mRadioConfig != null && mRadioConfig.getRadioConfigProxy(null) .getVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_2_2) && getPhoneCount() > 1 && mStaticCapability.getMaxActiveVoiceSubscriptions() > 1) { updateSimultaneousCallingSupport(); mRadioConfig.registerForSimultaneousCallingSupportStatusChanged(mHandler, EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED, null); } } /** /** * Static method to get instance. * Static method to get instance. */ */ Loading Loading @@ -223,6 +247,7 @@ public class PhoneConfigurationManager { if (ar != null && ar.exception == null) { if (ar != null && ar.exception == null) { mStaticCapability = (PhoneCapability) ar.result; mStaticCapability = (PhoneCapability) ar.result; notifyCapabilityChanged(); notifyCapabilityChanged(); maybeEnableCellularDSDASupport(); } else { } else { log(msg.what + " failure. Not getting phone capability." + ar.exception); log(msg.what + " failure. Not getting phone capability." + ar.exception); } } Loading @@ -236,6 +261,41 @@ public class PhoneConfigurationManager { mVirtualDsdaEnabled = isVirtualDsdaEnabled; mVirtualDsdaEnabled = isVirtualDsdaEnabled; } } break; break; case EVENT_SIMULTANEOUS_CALLING_SUPPORT_CHANGED: case EVENT_GET_SIMULTANEOUS_CALLING_SUPPORT_DONE: log("Received EVENT_SLOTS_SUPPORTING_SIMULTANEOUS_CALL_CHANGED/DONE"); if (getPhoneCount() < 2) { if (!mSlotsSupportingSimultaneousCellularCalls.isEmpty()) { mSlotsSupportingSimultaneousCellularCalls.clear(); } break; } ar = (AsyncResult) msg.obj; if (ar != null && ar.exception == null) { int[] returnedIntArray = (int[]) ar.result; if (!mSlotsSupportingSimultaneousCellularCalls.isEmpty()) { mSlotsSupportingSimultaneousCellularCalls.clear(); } int maxValidPhoneSlot = getPhoneCount() - 1; for (int i : returnedIntArray) { if (i < 0 || i > maxValidPhoneSlot) { loge("Invalid slot supporting DSDA =" + i + ". Disabling DSDA."); mSlotsSupportingSimultaneousCellularCalls.clear(); break; } mSlotsSupportingSimultaneousCellularCalls.add(i); } // Ensure the slots supporting cellular DSDA does not exceed the phone count if (mSlotsSupportingSimultaneousCellularCalls.size() > getPhoneCount()) { loge("Invalid size of DSDA slots. Disabling cellular DSDA."); mSlotsSupportingSimultaneousCellularCalls.clear(); break; } } else { log(msg.what + " failure. Not getting logical slots that support " + "simultaneous calling." + ar.exception); } break; default: default: log("Unknown event: " + msg.what); log("Unknown event: " + msg.what); } } Loading Loading @@ -341,6 +401,27 @@ public class PhoneConfigurationManager { return mTelephonyManager.getActiveModemCount(); return mTelephonyManager.getActiveModemCount(); } } @VisibleForTesting public Set<Integer> getSlotsSupportingSimultaneousCellularCalls() { return mSlotsSupportingSimultaneousCellularCalls; } /** * Get the current the list of logical slots supporting simultaneous cellular calling from the * modem based on current network conditions. */ @VisibleForTesting public void updateSimultaneousCallingSupport() { log("updateSimultaneousCallingSupport: sending the request for " + "getting the list of logical slots supporting simultaneous cellular calling"); Message callback = Message.obtain( mHandler, EVENT_GET_SIMULTANEOUS_CALLING_SUPPORT_DONE); mRadioConfig.updateSimultaneousCallingSupport(callback); log("updateSimultaneousCallingSupport: " + "mSlotsSupportingSimultaneousCellularCalls = " + mSlotsSupportingSimultaneousCellularCalls); } /** /** * get static overall phone capabilities for all phones. * get static overall phone capabilities for all phones. */ */ Loading Loading @@ -446,6 +527,16 @@ public class PhoneConfigurationManager { phone.mCi.onSlotActiveStatusChange(SubscriptionManager.isValidPhoneId(phoneId)); phone.mCi.onSlotActiveStatusChange(SubscriptionManager.isValidPhoneId(phoneId)); } } if (numOfActiveModems > 1) { // Check if cellular DSDA is supported. If it is, then send a request to the // modem to refresh the list of SIM slots that currently support DSDA based on // current network conditions maybeEnableCellularDSDASupport(); } else { // The number of active modems is 0 or 1, disable cellular DSDA: mSlotsSupportingSimultaneousCellularCalls.clear(); } // When the user enables DSDS mode, the default VOICE and SMS subId should be switched // When the user enables DSDS mode, the default VOICE and SMS subId should be switched // to "No Preference". Doing so will sync the network/sim settings and telephony. // to "No Preference". Doing so will sync the network/sim settings and telephony. // (see b/198123192) // (see b/198123192) Loading
src/java/com/android/internal/telephony/RILUtils.java +17 −6 Original line number Original line Diff line number Diff line Loading @@ -98,6 +98,7 @@ import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_NEIGHB import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_RADIO_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_RADIO_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIMULTANEOUS_CALLING_SUPPORT; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_STATUS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_STATUS; Loading Loading @@ -273,6 +274,7 @@ import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESTRICTED_S import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RIL_CONNECTED; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RIL_CONNECTED; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RINGBACK_TONE; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RINGBACK_TONE; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIGNAL_STRENGTH; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIGNAL_STRENGTH; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIMULTANEOUS_CALLING_SUPPORT_CHANGED; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_REFRESH; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_REFRESH; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_SMS_STORAGE_FULL; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_SMS_STORAGE_FULL; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SLICING_CONFIG_CHANGED; import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SLICING_CONFIG_CHANGED; Loading Loading @@ -4381,14 +4383,20 @@ public class RILUtils { public static PhoneCapability convertHalPhoneCapability(int[] deviceNrCapabilities, Object o) { public static PhoneCapability convertHalPhoneCapability(int[] deviceNrCapabilities, Object o) { int maxActiveVoiceCalls = 0; int maxActiveVoiceCalls = 0; int maxActiveData = 0; int maxActiveData = 0; int maxActiveInternetData = 0; boolean validationBeforeSwitchSupported = false; boolean validationBeforeSwitchSupported = false; List<ModemInfo> logicalModemList = new ArrayList<>(); List<ModemInfo> logicalModemList = new ArrayList<>(); if (o instanceof android.hardware.radio.config.PhoneCapability) { if (o instanceof android.hardware.radio.config.PhoneCapability) { final android.hardware.radio.config.PhoneCapability phoneCapability = final android.hardware.radio.config.PhoneCapability phoneCapability = (android.hardware.radio.config.PhoneCapability) o; (android.hardware.radio.config.PhoneCapability) o; maxActiveData = phoneCapability.maxActiveData; maxActiveData = phoneCapability.maxActiveData; maxActiveInternetData = phoneCapability.maxActiveInternetData; // If the maxActiveVoice field has been set, use that value. Otherwise, default to the // legacy behavior and rely on the maxActiveInternetData field: if (phoneCapability.maxActiveVoice == android.hardware.radio.config.PhoneCapability.UNKNOWN) { maxActiveVoiceCalls = phoneCapability.maxActiveInternetData; } else { maxActiveVoiceCalls = phoneCapability.maxActiveVoice; } validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported; validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported; for (int modemId : phoneCapability.logicalModemIds) { for (int modemId : phoneCapability.logicalModemIds) { logicalModemList.add(new ModemInfo(modemId)); logicalModemList.add(new ModemInfo(modemId)); Loading @@ -4397,16 +4405,15 @@ public class RILUtils { final android.hardware.radio.config.V1_1.PhoneCapability phoneCapability = final android.hardware.radio.config.V1_1.PhoneCapability phoneCapability = (android.hardware.radio.config.V1_1.PhoneCapability) o; (android.hardware.radio.config.V1_1.PhoneCapability) o; maxActiveData = phoneCapability.maxActiveData; maxActiveData = phoneCapability.maxActiveData; maxActiveInternetData = phoneCapability.maxActiveInternetData; // maxActiveInternetData defines how many logical modems can have internet PDN // connections simultaneously. For L+L DSDS modem it’s 1, and for DSDA modem it’s 2. maxActiveVoiceCalls = phoneCapability.maxActiveInternetData; validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported; validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported; for (android.hardware.radio.config.V1_1.ModemInfo modemInfo : for (android.hardware.radio.config.V1_1.ModemInfo modemInfo : phoneCapability.logicalModemList) { phoneCapability.logicalModemList) { logicalModemList.add(new ModemInfo(modemInfo.modemId)); logicalModemList.add(new ModemInfo(modemInfo.modemId)); } } } } // maxActiveInternetData defines how many logical modems can have internet PDN connections // simultaneously. For L+L DSDS modem it’s 1, and for DSDA modem it’s 2. maxActiveVoiceCalls = maxActiveInternetData; return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList, return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList, validationBeforeSwitchSupported, deviceNrCapabilities); validationBeforeSwitchSupported, deviceNrCapabilities); } } Loading Loading @@ -5128,6 +5135,8 @@ public class RILUtils { return "SET_LOCATION_PRIVACY_SETTING"; return "SET_LOCATION_PRIVACY_SETTING"; case RIL_REQUEST_GET_LOCATION_PRIVACY_SETTING: case RIL_REQUEST_GET_LOCATION_PRIVACY_SETTING: return "GET_LOCATION_PRIVACY_SETTING"; return "GET_LOCATION_PRIVACY_SETTING"; case RIL_REQUEST_GET_SIMULTANEOUS_CALLING_SUPPORT: return "GET_SIMULTANEOUS_CALLING_SUPPORT"; default: default: return "<unknown request " + request + ">"; return "<unknown request " + request + ">"; } } Loading Loading @@ -5273,6 +5282,8 @@ public class RILUtils { return "UNSOL_TRIGGER_IMS_DEREGISTRATION"; return "UNSOL_TRIGGER_IMS_DEREGISTRATION"; case RIL_UNSOL_IMEI_MAPPING_CHANGED: case RIL_UNSOL_IMEI_MAPPING_CHANGED: return "UNSOL_IMEI_MAPPING_CHANGED"; return "UNSOL_IMEI_MAPPING_CHANGED"; case RIL_UNSOL_SIMULTANEOUS_CALLING_SUPPORT_CHANGED: return "UNSOL_SIMULTANEOUS_CALLING_SUPPORT_CHANGED"; default: default: return "<unknown response " + response + ">"; return "<unknown response " + response + ">"; } } Loading
src/java/com/android/internal/telephony/RadioConfig.java +39 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static com.android.internal.telephony.RILConstants.RADIO_NOT_AVAILABLE; import static com.android.internal.telephony.RILConstants.REQUEST_NOT_SUPPORTED; import static com.android.internal.telephony.RILConstants.REQUEST_NOT_SUPPORTED; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIMULTANEOUS_CALLING_SUPPORT; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SLOT_STATUS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SLOT_STATUS; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_PREFERRED_DATA_MODEM; import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_PREFERRED_DATA_MODEM; Loading Loading @@ -79,6 +80,8 @@ public class RadioConfig extends Handler { protected Registrant mSimSlotStatusRegistrant; protected Registrant mSimSlotStatusRegistrant; protected Registrant mSimultaneousCallingSupportStatusRegistrant; private boolean isMobileDataCapable(Context context) { private boolean isMobileDataCapable(Context context) { final TelephonyManager tm = context.getSystemService(TelephonyManager.class); final TelephonyManager tm = context.getSystemService(TelephonyManager.class); return tm != null && tm.isDataCapable(); return tm != null && tm.isDataCapable(); Loading Loading @@ -477,6 +480,34 @@ public class RadioConfig extends Handler { } } } } /** * Wrapper function for IRadioConfig.getSimultaneousCallingSupport(). */ public void updateSimultaneousCallingSupport(Message result) { RadioConfigProxy proxy = getRadioConfigProxy(null); if (proxy.isEmpty()) return; if (proxy.getVersion().less(RIL.RADIO_HAL_VERSION_2_2)) { if (result != null) { AsyncResult.forMessage(result, null, CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED)); result.sendToTarget(); } return; } RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIMULTANEOUS_CALLING_SUPPORT, result, mDefaultWorkSource); if (DBG) { logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)); } try { proxy.updateSimultaneousCallingSupport(rr.mSerial); } catch (RemoteException | RuntimeException e) { resetProxyAndRequestList("updateSimultaneousCallingSupport", e); } } /** /** * Wrapper function for IRadioConfig.getPhoneCapability(). * Wrapper function for IRadioConfig.getPhoneCapability(). */ */ Loading Loading @@ -565,6 +596,14 @@ public class RadioConfig extends Handler { } } } } /** * Register a handler to get SIM slots that support simultaneous calling changed notifications. */ public void registerForSimultaneousCallingSupportStatusChanged(Handler h, int what, Object obj) { mSimultaneousCallingSupportStatusRegistrant = new Registrant(h, what, obj); } /** /** * Register a handler to get SIM slot status changed notifications. * Register a handler to get SIM slot status changed notifications. */ */ Loading
src/java/com/android/internal/telephony/RadioConfigIndicationAidl.java +15 −0 Original line number Original line Diff line number Diff line Loading @@ -17,12 +17,14 @@ package com.android.internal.telephony; package com.android.internal.telephony; import android.os.AsyncResult; import android.os.AsyncResult; import android.os.RemoteException; import android.os.Trace; import android.os.Trace; import com.android.internal.telephony.uicc.IccSlotStatus; import com.android.internal.telephony.uicc.IccSlotStatus; import com.android.telephony.Rlog; import com.android.telephony.Rlog; import java.util.ArrayList; import java.util.ArrayList; import java.util.Arrays; /** /** * This class is the AIDL implementation of IRadioConfigIndication interface. * This class is the AIDL implementation of IRadioConfigIndication interface. Loading Loading @@ -51,6 +53,19 @@ public class RadioConfigIndicationAidl extends } } } } /** * Indication that the logical slots that support simultaneous calling has changed. */ @Override public void onSimultaneousCallingSupportChanged(int[] enabledLogicalSlots) { ArrayList<Integer> ret = RILUtils.primitiveArrayToArrayList(enabledLogicalSlots); logd("onSimultaneousCallingSupportChanged: enabledLogicalSlots = " + ret); if (mRadioConfig.mSimultaneousCallingSupportStatusRegistrant != null) { mRadioConfig.mSimultaneousCallingSupportStatusRegistrant.notifyRegistrant( new AsyncResult(null, ret, null)); } } private static void logd(String log) { private static void logd(String log) { Rlog.d(TAG, "[UNSL]< " + log); Rlog.d(TAG, "[UNSL]< " + log); Trace.instantForTrack(Trace.TRACE_TAG_NETWORK, "RIL", log); Trace.instantForTrack(Trace.TRACE_TAG_NETWORK, "RIL", log); Loading
src/java/com/android/internal/telephony/RadioConfigProxy.java +10 −0 Original line number Original line Diff line number Diff line Loading @@ -224,6 +224,16 @@ public class RadioConfigProxy { } } } } /** * Wrapper function for IRadioConfig.getSimultaneousCallingSupport() */ public void updateSimultaneousCallingSupport(int serial) throws RemoteException { if (isAidl()) { getAidl().getSimultaneousCallingSupport(serial); } // Only supported on AIDL. } /** /** * Wrapper function for using IRadioConfig.setNumOfLiveModems(int32_t serial, * Wrapper function for using IRadioConfig.setNumOfLiveModems(int32_t serial, * byte numOfLiveModems) to switch between single-sim and multi-sim. * byte numOfLiveModems) to switch between single-sim and multi-sim. Loading