Merge "Refactoring of CrossSimRedialingController for plug-in architecture" into main
diff --git a/Android.bp b/Android.bp
index 43897cb..7ab0990 100644
--- a/Android.bp
+++ b/Android.bp
@@ -46,6 +46,7 @@
"nist-sip",
"service-entitlement",
"telephony_flags_core_java_lib",
+ "android.permission.flags-aconfig-java",
],
srcs: [
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index eef01fa..7e56e8b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -619,17 +619,6 @@
</intent-filter>
</activity>
- <activity android:name=".settings.BandMode"
- android:label="@string/band_mode_title"
- android:exported="true"
- android:theme="@style/Theme.AppCompat.DayNight">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.VOICE_LAUNCH" />
- </intent-filter>
- </activity>
-
<provider
android:name="ServiceStateProvider"
android:authorities="service-state"
diff --git a/OWNERS b/OWNERS
index 2c7aed3..53b9401 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,5 @@
include platform/frameworks/opt/telephony:/OWNERS
per-file *SimPhonebookProvider* = file:platform/packages/apps/Contacts:/OWNERS
+
+per-file config.xml=hwangoo@google.com,forestchoi@google.com,avinashmp@google.com,mkoon@google.com,seheele@google.com,radhikaagrawal@google.com
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 6675ae7..992f1b2 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -596,7 +596,7 @@
<string name="failedToImportSingleContactMsg" msgid="228095510489830266">"Uvoz kontakta nije uspio"</string>
<string name="hac_mode_title" msgid="4127986689621125468">"Slušni aparat"</string>
<string name="hac_mode_summary" msgid="7774989500136009881">"Uključite kompatibilnost za slušni aparat"</string>
- <string name="rtt_mode_title" msgid="3075948111362818043">"Pozivanje sa slanjem SMS-ova u stvarnom vremenu (RTT)"</string>
+ <string name="rtt_mode_title" msgid="3075948111362818043">"Poziv sa SMS-ovima u stvarnom vremenu (RTT)"</string>
<string name="rtt_mode_summary" msgid="8631541375609989562">"Dozvolite razmjenu poruka tokom glasovnog poziva"</string>
<string name="rtt_mode_more_information" msgid="587500128658756318">"RTT pomaže pozivaocima koji su gluhi, imaju probleme sa sluhom ili govorom te onima kojima treba više od samog glasa.<br> <a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>>Saznajte više</a>\n <br><br> - RTT pozivi se pohranjuju kao transkripti poruka\n <br> - RTT nije dostupan za video pozive"</string>
<string name="no_rtt_when_roaming" msgid="5268008247378355389">"Napomena: RTT nije dostupan u romingu"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index a9dd327..58f2670 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -596,9 +596,9 @@
<string name="failedToImportSingleContactMsg" msgid="228095510489830266">"Kontaktpersonen kunne ikke importeres"</string>
<string name="hac_mode_title" msgid="4127986689621125468">"Høreapparater"</string>
<string name="hac_mode_summary" msgid="7774989500136009881">"Slå høreapparatskompatibilitet til"</string>
- <string name="rtt_mode_title" msgid="3075948111362818043">"Opkald via sms i realtid"</string>
+ <string name="rtt_mode_title" msgid="3075948111362818043">"Opkald via beskeder i realtid"</string>
<string name="rtt_mode_summary" msgid="8631541375609989562">"Tillad afsendelse af sms-beskeder i et taleopkald"</string>
- <string name="rtt_mode_more_information" msgid="587500128658756318">"Sms i realtid hjælper personer, som er døve, hørehæmmede, talehandicappede, eller som har brug for mere end bare tale, med at foretage opkald.<br> <a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>>Få flere oplysninger</a>\n <br><br> – Opkald via sms i realtid gemmes som en beskedtransskription\n <br> – Sms i realtid er ikke tilgængeligt til videoopkald"</string>
+ <string name="rtt_mode_more_information" msgid="587500128658756318">"Beskeder i realtid hjælper personer, som er døve, hørehæmmede, talehandicappede, eller som har brug for mere end bare tale, med at foretage opkald.<br> <a href=<xliff:g id="URL">http://support.google.com/mobile?p=telephony_rtt</xliff:g>>Få flere oplysninger</a>\n <br><br> – Opkald via beskeder i realtid gemmes som en beskedtransskription\n <br> – Beskeder i realtid er ikke tilgængeligt til videoopkald"</string>
<string name="no_rtt_when_roaming" msgid="5268008247378355389">"Bemærk! RTT er ikke tilgængeligt under roaming"</string>
<string-array name="tty_mode_entries">
<item msgid="3238070884803849303">"TTY fra"</item>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 5d03fe8..4f8e559 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -314,7 +314,7 @@
<string name="video_calling_settings_title" msgid="342829454913266078">"वाहक वीडियो कॉलिंग"</string>
<string name="gsm_umts_options" msgid="4968446771519376808">"GSM/UMTS विकल्प"</string>
<string name="cdma_options" msgid="3669592472226145665">"CDMA विकल्प"</string>
- <string name="throttle_data_usage" msgid="1944145350660420711">"डेटा उपयोग"</string>
+ <string name="throttle_data_usage" msgid="1944145350660420711">"डेटा खर्च"</string>
<string name="throttle_current_usage" msgid="7483859109708658613">"वर्तमान अवधि में उपयोग किया गया डेटा"</string>
<string name="throttle_time_frame" msgid="1813452485948918791">"डेटा उपयोग अवधि"</string>
<string name="throttle_rate" msgid="7641913901133634905">"डेटा दर नीति"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 7bd3d32..3fca1ed 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -385,9 +385,9 @@
<string name="enable_disable_lafs" msgid="7448060358300805661">"Жергиликтүү аэропорттун учуу тартиби"</string>
<string name="lafs_enable" msgid="3125783406052655690">"Жергиликтүү аэропорттун учуу тартиби иштетилген"</string>
<string name="lafs_disable" msgid="7326815066813851447">"Жергиликтүү аэропорттун учуу тартиби өчүрүлгөн"</string>
- <string name="enable_disable_restaurants" msgid="3873247081569423019">"Ресторандар"</string>
- <string name="restaurants_enable" msgid="5810452674239139572">"Ресторандар иштетилген"</string>
- <string name="restaurants_disable" msgid="2733507854548413505">"Ресторандар өчүрүлгөн"</string>
+ <string name="enable_disable_restaurants" msgid="3873247081569423019">"Тамактануучу жайлар"</string>
+ <string name="restaurants_enable" msgid="5810452674239139572">"Тамактануучу жайлар иштетилген"</string>
+ <string name="restaurants_disable" msgid="2733507854548413505">"Тамактануучу жайлар өчүрүлгөн"</string>
<string name="enable_disable_lodgings" msgid="7849168585821435109">"Турак жайлар"</string>
<string name="lodgings_enable" msgid="2020598411398609514">"Турак жайлар иштетилген"</string>
<string name="lodgings_disable" msgid="5145649659459722661">"Турак жайлар өчүрүлгөн"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index f8bef4a..90165b8 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -908,7 +908,7 @@
<string name="radio_info_smsc_update_label" msgid="5141996256097115753">"Atjaunināt"</string>
<string name="radio_info_smsc_refresh_label" msgid="8409923721451604560">"Atsvaidzināt"</string>
<string name="radio_info_toggle_dns_check_label" msgid="1394078554927787350">"Pārslēgt DNS pārbaudi"</string>
- <string name="oem_radio_info_label" msgid="2914167475119997456">"OEM raksturīga informācija/iestatījumi"</string>
+ <string name="oem_radio_info_label" msgid="2914167475119997456">"OAR raksturīga informācija/iestatījumi"</string>
<string name="radio_info_endc_available" msgid="2983767110681230019">"EN-DC pieejamība (NSA):"</string>
<string name="radio_info_dcnr_restricted" msgid="7147511536420148173">"DCNR ierobežojums (NSA):"</string>
<string name="radio_info_nr_available" msgid="3383388088451237182">"NR pieejamība (NSA):"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index ba65302..dcfa364 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -318,6 +318,25 @@
<string-array name="thermal_mitigation_allowlisted_packages" translatable="false">
</string-array>
+ <!-- Array of carriers that don't care about NGRAN's preference in the preferred emergency
+ network scan list after SIM is removed. -->
+ <integer-array name="config_carriers_ignore_ngran_preference_when_sim_removed">
+ <!-- 001-01 Test SIM -->
+ <item>1911</item>
+ </integer-array>
+
+ <!-- Array of countries that active SIM is needed for emergency calls. Values should be
+ ISO3166 country codes in lowercase. -->
+ <string-array name="config_countries_require_sim_for_emergency" translatable="false">
+ <!-- b/177967010 -->
+ <item>jp</item>
+ <!-- b/230443699 -->
+ <item>in</item>
+ <item>sg</item>
+ <!-- b/198393826 -->
+ <item>de</item>
+ </string-array>
+
<!-- Flag specifying whether the AOSP domain selection is enabled or
the device should fallback to the modem based domain selection architecture. -->
<bool name="config_enable_aosp_domain_selection">false</bool>
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 73b61b6..daf3aa2 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -489,7 +489,7 @@
public void updatePhoneStateListeners(boolean isRefresh, int updateType, int subIdToUpdate) {
List<SubscriptionInfo> subInfos = SubscriptionManagerService.getInstance()
.getActiveSubscriptionInfoList(mApplication.getOpPackageName(),
- mApplication.getAttributionTag());
+ mApplication.getAttributionTag(), true/*isForAllProfile*/);
// Sort sub id list based on slot id, so that CFI/MWI notifications will be updated for
// slot 0 first then slot 1. This is needed to ensure that when CFI or MWI is enabled for
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 518003f..3cd9a8b 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -64,6 +64,8 @@
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.internal.telephony.flags.FeatureFlags;
+import com.android.internal.telephony.flags.FeatureFlagsImpl;
import com.android.internal.telephony.util.NotificationChannelController;
import com.android.phone.settings.VoicemailSettingsActivity;
@@ -146,6 +148,9 @@
// maps each subId to selected network operator name.
private SparseArray<String> mSelectedNetworkOperatorName = new SparseArray<>();
+ // feature flags
+ private final FeatureFlags mFeatureFlags;
+
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -177,6 +182,7 @@
mSubscriptionManager = SubscriptionManager.from(mContext);
mTelecomManager = app.getSystemService(TelecomManager.class);
mTelephonyManager = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
+ mFeatureFlags = new FeatureFlagsImpl();
}
/**
@@ -828,6 +834,12 @@
* @param subId The subscription ID
*/
void updateNetworkSelection(int serviceState, int subId) {
+ if (!mFeatureFlags.dismissNetworkSelectionNotificationOnSimDisable()) {
+ updateNetworkSelectionForFeatureDisabled(serviceState, subId);
+ return;
+ }
+
+ // for dismissNetworkSelectionNotificationOnSimDisable feature enabled.
int phoneId = SubscriptionManager.getPhoneId(subId);
Phone phone = SubscriptionManager.isValidPhoneId(phoneId) ?
PhoneFactory.getPhone(phoneId) : PhoneFactory.getDefaultPhone();
@@ -868,6 +880,62 @@
clearUpNetworkSelectionNotificationParam(subId);
}
} else {
+ if (DBG) {
+ log("updateNetworkSelection()... state = " + serviceState
+ + " not updating network due to invalid subId " + subId);
+ }
+ dismissNetworkSelectionNotificationForInactiveSubId();
+ }
+ }
+ }
+
+ /**
+ * Update notification about no service of user selected operator.
+ * For dismissNetworkSelectionNotificationOnSimDisable feature disabled.
+ *
+ * @param serviceState Phone service state
+ * @param subId The subscription ID
+ */
+ private void updateNetworkSelectionForFeatureDisabled(int serviceState, int subId) {
+ int phoneId = SubscriptionManager.getPhoneId(subId);
+ Phone phone = SubscriptionManager.isValidPhoneId(phoneId)
+ ? PhoneFactory.getPhone(phoneId) : PhoneFactory.getDefaultPhone();
+ if (TelephonyCapabilities.supportsNetworkSelection(phone)) {
+ if (SubscriptionManager.isValidSubscriptionId(subId)) {
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ String selectedNetworkOperatorName =
+ sp.getString(Phone.NETWORK_SELECTION_NAME_KEY + subId, "");
+ // get the shared preference of network_selection.
+ // empty is auto mode, otherwise it is the operator alpha name
+ // in case there is no operator name, check the operator numeric
+ if (TextUtils.isEmpty(selectedNetworkOperatorName)) {
+ selectedNetworkOperatorName =
+ sp.getString(Phone.NETWORK_SELECTION_KEY + subId, "");
+ }
+ boolean isManualSelection;
+ // if restoring manual selection is controlled by framework, then get network
+ // selection from shared preference, otherwise get from real network indicators.
+ boolean restoreSelection = !mContext.getResources().getBoolean(
+ com.android.internal.R.bool.skip_restoring_network_selection);
+ if (restoreSelection) {
+ isManualSelection = !TextUtils.isEmpty(selectedNetworkOperatorName);
+ } else {
+ isManualSelection = phone.getServiceStateTracker().mSS.getIsManualSelection();
+ }
+
+ if (DBG) {
+ log("updateNetworkSelection()..." + "state = " + serviceState + " new network "
+ + (isManualSelection ? selectedNetworkOperatorName : ""));
+ }
+
+ if (isManualSelection) {
+ mSelectedNetworkOperatorName.put(subId, selectedNetworkOperatorName);
+ shouldShowNotification(serviceState, subId);
+ } else {
+ dismissNetworkSelectionNotification(subId);
+ clearUpNetworkSelectionNotificationParam(subId);
+ }
+ } else {
if (DBG) log("updateNetworkSelection()..." + "state = " +
serviceState + " not updating network due to invalid subId " + subId);
dismissNetworkSelectionNotificationForInactiveSubId();
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 4773a83..0cb95c5 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -17,6 +17,7 @@
package com.android.phone;
import android.annotation.IntDef;
+import android.annotation.Nullable;
import android.app.Activity;
import android.app.KeyguardManager;
import android.app.ProgressDialog;
@@ -49,6 +50,7 @@
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyLocalConnection;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Log;
@@ -217,6 +219,14 @@
*/
private ArraySet<String> mShownNotificationReasons = new ArraySet<>();
+ // For reorganize_roaming_notification feature disabled.
+ @RoamingNotification
+ private int mPrevRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
+
+ // For reorganize_roaming_notification feature disabled.
+ /** Operator numerics for which we've shown is-roaming notifications. **/
+ private ArraySet<String> mPrevRoamingOperatorNumerics = new ArraySet<>();
+
private WakeState mWakeState = WakeState.SLEEP;
private PowerManager mPowerManager;
@@ -240,6 +250,8 @@
// fine or coarse location since we only use ServiceState for
private PhoneAppCallback[] mTelephonyCallbacks;
+ private FeatureFlags mFeatureFlags;
+
private class PhoneAppCallback extends TelephonyCallback implements
TelephonyCallback.ServiceStateListener {
private final int mSubId;
@@ -385,11 +397,19 @@
//TODO: handle message here;
break;
case EVENT_DATA_ROAMING_SETTINGS_CHANGED:
- updateDataRoamingStatus(
- ROAMING_NOTIFICATION_REASON_DATA_ROAMING_SETTING_CHANGED);
+ if (mFeatureFlags.reorganizeRoamingNotification()) {
+ updateDataRoamingStatus(
+ ROAMING_NOTIFICATION_REASON_DATA_ROAMING_SETTING_CHANGED);
+ } else {
+ updateDataRoamingStatusForFeatureDisabled(null);
+ }
break;
case EVENT_MOBILE_DATA_SETTINGS_CHANGED:
- updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DATA_SETTING_CHANGED);
+ if (mFeatureFlags.reorganizeRoamingNotification()) {
+ updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DATA_SETTING_CHANGED);
+ } else {
+ updateDataRoamingStatusForFeatureDisabled(null);
+ }
break;
case EVENT_CARRIER_CONFIG_CHANGED:
int subId = (Integer) msg.obj;
@@ -480,8 +500,8 @@
getResources().getBoolean(R.bool.config_enable_aosp_domain_selection));
// Initialize the telephony framework
- FeatureFlags featureFlags = new FeatureFlagsImpl();
- PhoneFactory.makeDefaultPhones(this, featureFlags);
+ mFeatureFlags = new FeatureFlagsImpl();
+ PhoneFactory.makeDefaultPhones(this, mFeatureFlags);
// Initialize the DomainSelectionResolver after creating the Phone instance
// to check the Radio HAL version.
@@ -539,7 +559,7 @@
// Create the SatelliteController singleton, which acts as a backend service for
// {@link android.telephony.satellite.SatelliteManager}.
- SatelliteController.make(this, featureFlags);
+ SatelliteController.make(this, mFeatureFlags);
// Create an instance of CdmaPhoneCallState and initialize it to IDLE
cdmaPhoneCallState = new CdmaPhoneCallState();
@@ -554,7 +574,7 @@
mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
- phoneMgr = PhoneInterfaceManager.init(this, featureFlags);
+ phoneMgr = PhoneInterfaceManager.init(this, mFeatureFlags);
imsRcsController = ImsRcsController.init(this);
@@ -599,12 +619,16 @@
intentFilter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
registerReceiver(mReceiver, intentFilter);
- int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
- if (SubscriptionManager.isValidSubscriptionId(defaultDataSubId)) {
- if (VDBG) Log.v(LOG_TAG, "Loaded initial default data sub: " + defaultDataSubId);
- mDefaultDataSubId = defaultDataSubId;
- registerSettingsObserver();
- updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED);
+ if (mFeatureFlags.loadDdsOnCreate()) {
+ int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
+ if (SubscriptionManager.isValidSubscriptionId(defaultDataSubId)) {
+ if (VDBG) {
+ Log.v(LOG_TAG, "Loaded initial default data sub: " + defaultDataSubId);
+ }
+ mDefaultDataSubId = defaultDataSubId;
+ registerSettingsObserver();
+ updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED);
+ }
}
PhoneConfigurationManager.registerForMultiSimConfigChange(
@@ -808,7 +832,11 @@
/** Clear fields on power off radio **/
private void clearCacheOnRadioOff() {
// Re-show is-roaming notifications after APM mode
- mShownNotificationReasons.clear();
+ if (mFeatureFlags.reorganizeRoamingNotification()) {
+ mShownNotificationReasons.clear();
+ } else {
+ mPrevRoamingOperatorNumerics.clear();
+ }
}
private void setRadioPowerOn() {
@@ -905,7 +933,11 @@
} else if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
// Roaming status could be overridden by carrier config, so we need to update it.
if (VDBG) Log.v(LOG_TAG, "carrier config changed.");
- updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED);
+ if (mFeatureFlags.reorganizeRoamingNotification()) {
+ updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED);
+ } else {
+ updateDataRoamingStatusForFeatureDisabled(null);
+ }
updateLimitedSimFunctionForDualSim();
int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
@@ -920,7 +952,12 @@
registerSettingsObserver();
Phone phone = getPhone(mDefaultDataSubId);
if (phone != null) {
- updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED);
+ if (mFeatureFlags.reorganizeRoamingNotification()) {
+ updateDataRoamingStatus(
+ ROAMING_NOTIFICATION_REASON_DEFAULT_DATA_SUBS_CHANGED);
+ } else {
+ updateDataRoamingStatusForFeatureDisabled(null);
+ }
}
}
}
@@ -936,7 +973,11 @@
+ mDefaultDataSubId + ", ss roaming=" + serviceState.getDataRoaming());
}
if (subId == mDefaultDataSubId) {
- updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_SERVICE_STATE_CHANGED);
+ if (mFeatureFlags.reorganizeRoamingNotification()) {
+ updateDataRoamingStatus(ROAMING_NOTIFICATION_REASON_SERVICE_STATE_CHANGED);
+ } else {
+ updateDataRoamingStatusForFeatureDisabled(serviceState.getOperatorNumeric());
+ }
}
}
@@ -1021,16 +1062,14 @@
&& reason == ROAMING_NOTIFICATION_REASON_CARRIER_CONFIG_CHANGED) {
mShownNotificationReasons.add(callingReason);
}
- boolean isShowRoamingNotificationEnabled = getCarrierConfigForSubId(mDefaultDataSubId)
- .getBoolean(CarrierConfigManager
- .KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL);
+ boolean shouldShowRoamingNotification = shouldShowRoamingNotification(roamingNumeric);
// No need to show it again if we never cancelled it explicitly.
if (getCurrentRoamingNotification() == ROAMING_NOTIFICATION_CONNECTED) {
return;
}
// Inform users that roaming charges may apply.
- if (!shownInThisNumeric && !shownForThisReason && isShowRoamingNotificationEnabled) {
+ if (!shownInThisNumeric && !shownForThisReason && shouldShowRoamingNotification) {
updateDataRoamingNotification(ROAMING_NOTIFICATION_CONNECTED);
} else {
// Don't show roaming notification if we've already shown for this MccMnc or
@@ -1038,7 +1077,7 @@
Log.d(LOG_TAG, "Skip roaming connected notification since already"
+ " shownInThisNumeric:" + shownInThisNumeric
+ " shownForThisReason:" + shownForThisReason
- + " isShowRoamingNotificationEnabled:" + isShowRoamingNotificationEnabled);
+ + " shouldShowRoamingNotification:" + shouldShowRoamingNotification);
// Dismiss notification if the other notification is shown.
if (getCurrentRoamingNotification() != ROAMING_NOTIFICATION_NO_NOTIFICATION) {
updateDataRoamingNotification(ROAMING_NOTIFICATION_NO_NOTIFICATION);
@@ -1083,6 +1122,87 @@
return mCurrentRoamingNotification;
}
+ // For reorganize_roaming_notification feature disabled.
+ /**
+ * When roaming, if mobile data cannot be established due to data roaming not enabled, we need
+ * to notify the user so they can enable it through settings. Vise versa if the condition
+ * changes, we need to dismiss the notification.
+ * @param roamingOperatorNumeric The operator numeric for the current roaming. {@code null} if
+ * the current roaming operator numeric didn't change.
+ */
+ private void updateDataRoamingStatusForFeatureDisabled(
+ @Nullable String roamingOperatorNumeric) {
+ if (VDBG) Log.v(LOG_TAG, "updateDataRoamingStatusForFeatureDisabled");
+ Phone phone = getPhone(mDefaultDataSubId);
+ if (phone == null) {
+ Log.w(LOG_TAG, "Can't get phone with sub id = " + mDefaultDataSubId);
+ return;
+ }
+
+ boolean dataAllowed;
+ boolean notAllowedDueToRoamingOff;
+ List<DataDisallowedReason> reasons = phone.getDataNetworkController()
+ .getInternetDataDisallowedReasons();
+ dataAllowed = reasons.isEmpty();
+ notAllowedDueToRoamingOff = (reasons.size() == 1
+ && reasons.contains(DataDisallowedReason.ROAMING_DISABLED));
+ mDataRoamingNotifLog.log("dataAllowed=" + dataAllowed + ", reasons=" + reasons
+ + ", roamingOperatorNumeric=" + roamingOperatorNumeric);
+ if (VDBG) {
+ Log.v(LOG_TAG, "dataAllowed=" + dataAllowed + ", reasons=" + reasons
+ + ", roamingOperatorNumeric=" + roamingOperatorNumeric);
+ }
+
+ if (!dataAllowed && notAllowedDueToRoamingOff) {
+ // Don't show roaming notification if we've already shown for this MccMnc
+ if (roamingOperatorNumeric != null
+ && !mPrevRoamingOperatorNumerics.add(roamingOperatorNumeric)) {
+ Log.d(LOG_TAG, "Skip roaming disconnected notification since already shown in "
+ + "MccMnc " + roamingOperatorNumeric);
+ return;
+ }
+ // No need to show it again if we never cancelled it explicitly.
+ if (mPrevRoamingNotification == ROAMING_NOTIFICATION_DISCONNECTED) return;
+ // If the only reason of no data is data roaming disabled, then we notify the user
+ // so the user can turn on data roaming.
+ mPrevRoamingNotification = ROAMING_NOTIFICATION_DISCONNECTED;
+ Log.d(LOG_TAG, "Show roaming disconnected notification");
+ mDataRoamingNotifLog.log("Show roaming off.");
+ Message msg = mHandler.obtainMessage(EVENT_DATA_ROAMING_DISCONNECTED);
+ msg.arg1 = mDefaultDataSubId;
+ msg.sendToTarget();
+ } else if (dataAllowed && dataIsNowRoaming(mDefaultDataSubId)) {
+ if (!shouldShowRoamingNotification(roamingOperatorNumeric)) {
+ Log.d(LOG_TAG, "Skip showing roaming connected notification.");
+ return;
+ }
+ // Don't show roaming notification if we've already shown for this MccMnc
+ if (roamingOperatorNumeric != null
+ && !mPrevRoamingOperatorNumerics.add(roamingOperatorNumeric)) {
+ Log.d(LOG_TAG, "Skip roaming connected notification since already shown in "
+ + "MccMnc " + roamingOperatorNumeric);
+ return;
+ }
+ // No need to show it again if we never cancelled it explicitly, or carrier config
+ // indicates this is not needed.
+ if (mPrevRoamingNotification == ROAMING_NOTIFICATION_CONNECTED) return;
+ mPrevRoamingNotification = ROAMING_NOTIFICATION_CONNECTED;
+ Log.d(LOG_TAG, "Show roaming connected notification");
+ mDataRoamingNotifLog.log("Show roaming on.");
+ Message msg = mHandler.obtainMessage(EVENT_DATA_ROAMING_CONNECTED);
+ msg.arg1 = mDefaultDataSubId;
+ msg.sendToTarget();
+ } else if (mPrevRoamingNotification != ROAMING_NOTIFICATION_NO_NOTIFICATION) {
+ // Otherwise we either 1) we are not roaming or 2) roaming is off but ROAMING_DISABLED
+ // is not the only data disable reason. In this case we dismiss the notification we
+ // showed earlier.
+ mPrevRoamingNotification = ROAMING_NOTIFICATION_NO_NOTIFICATION;
+ Log.d(LOG_TAG, "Dismiss roaming notification");
+ mDataRoamingNotifLog.log("Hide. data allowed=" + dataAllowed);
+ mHandler.sendEmptyMessage(EVENT_DATA_ROAMING_OK);
+ }
+ }
+
/**
*
* @param subId to check roaming on
@@ -1092,6 +1212,46 @@
return getPhone(subId).getServiceState().getDataRoaming();
}
+ private boolean shouldShowRoamingNotification(String roamingNumeric) {
+ PersistableBundle config = getCarrierConfigForSubId(mDefaultDataSubId);
+ boolean showRoamingNotification = config.getBoolean(
+ CarrierConfigManager.KEY_SHOW_DATA_CONNECTED_ROAMING_NOTIFICATION_BOOL);
+
+ if (TextUtils.isEmpty(roamingNumeric) || !mFeatureFlags.hideRoamingIcon()) {
+ Log.d(LOG_TAG, "shouldShowRoamingNotification: roamingNumeric=" + roamingNumeric
+ + ", hideRoaming=" + mFeatureFlags.hideRoamingIcon());
+ return showRoamingNotification;
+ }
+
+ String[] includedMccMncs = config.getStringArray(CarrierConfigManager
+ .KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_INCLUDED_MCC_MNCS_STRING_ARRAY);
+ if (includedMccMncs != null) {
+ for (String mccMnc : includedMccMncs) {
+ if (roamingNumeric.equals(mccMnc)) {
+ Log.d(LOG_TAG, "shouldShowRoamingNotification: show for MCC/MNC " + mccMnc);
+ return showRoamingNotification;
+ }
+ }
+ }
+
+ String[] excludedMccs = config.getStringArray(CarrierConfigManager
+ .KEY_DATA_CONNECTED_ROAMING_NOTIFICATION_EXCLUDED_MCCS_STRING_ARRAY);
+ String roamingMcc = roamingNumeric.length() < 3 ? "" : roamingNumeric.substring(0, 3);
+ if (excludedMccs != null && !TextUtils.isEmpty(roamingMcc)) {
+ for (String mcc : excludedMccs) {
+ if (roamingMcc.equals(mcc)) {
+ Log.d(LOG_TAG, "shouldShowRoamingNotification: ignore for MCC " + mcc);
+ return false;
+ }
+ }
+ }
+
+ if (showRoamingNotification) {
+ Log.d(LOG_TAG, "shouldShowRoamingNotification: show for numeric " + roamingNumeric);
+ }
+ return showRoamingNotification;
+ }
+
private void updateLimitedSimFunctionForDualSim() {
if (DBG) Log.d(LOG_TAG, "updateLimitedSimFunctionForDualSim");
// check conditions to display limited SIM function notification under dual SIM
@@ -1179,7 +1339,19 @@
IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " ");
pw.println("------- PhoneGlobals -------");
pw.increaseIndent();
- pw.println("mCurrentRoamingNotification=" + mCurrentRoamingNotification);
+ pw.println("FeatureFlags:");
+ pw.increaseIndent();
+ pw.println("loadDdsOnCreate=" + mFeatureFlags.loadDdsOnCreate());
+ pw.println("reorganizeRoamingNotification="
+ + mFeatureFlags.reorganizeRoamingNotification());
+ pw.println("dismissNetworkSelectionNotificationOnSimDisable="
+ + mFeatureFlags.dismissNetworkSelectionNotificationOnSimDisable());
+ pw.decreaseIndent();
+ if (mFeatureFlags.reorganizeRoamingNotification()) {
+ pw.println("mCurrentRoamingNotification=" + mCurrentRoamingNotification);
+ } else {
+ pw.println("mPrevRoamingNotification=" + mPrevRoamingNotification);
+ }
pw.println("mDefaultDataSubId=" + mDefaultDataSubId);
pw.println("isSmsCapable=" + TelephonyManager.from(this).isSmsCapable());
pw.println("mDataRoamingNotifLog:");
@@ -1220,7 +1392,11 @@
mDomainSelectionService.dump(fd, pw, args);
}
pw.decreaseIndent();
- pw.println("mShownNotificationReasons=" + mShownNotificationReasons);
+ if (mFeatureFlags.reorganizeRoamingNotification()) {
+ pw.println("mShownNotificationReasons=" + mShownNotificationReasons);
+ } else {
+ pw.println("mPrevRoamingOperatorNumerics:" + mPrevRoamingOperatorNumerics);
+ }
pw.println("------- End PhoneGlobals -------");
}
}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 4e673d8..1937658 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -17,6 +17,7 @@
package com.android.phone;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.permission.flags.Flags.opEnableMobileDataByUser;
import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
@@ -147,6 +148,7 @@
import android.telephony.ims.stub.ImsConfigImplBase;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.telephony.satellite.INtnSignalStrengthCallback;
+import android.telephony.satellite.ISatelliteCapabilitiesCallback;
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.ISatelliteProvisionStateCallback;
import android.telephony.satellite.ISatelliteStateCallback;
@@ -8049,7 +8051,7 @@
*/
private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
return getSubscriptionManagerService().getActiveSubscriptionInfoList(
- mApp.getOpPackageName(), mApp.getAttributionTag());
+ mApp.getOpPackageName(), mApp.getAttributionTag(), true/*isForAllProfile*/);
}
private ActivityStatsTechSpecificInfo[] mLastModemActivitySpecificInfo = null;
@@ -8828,6 +8830,12 @@
enforceModifyPermission();
}
+ if (reason == TelephonyManager.DATA_ENABLED_REASON_USER && enabled
+ && null != callingPackage && opEnableMobileDataByUser()) {
+ mAppOps.noteOp(AppOpsManager.OPSTR_ENABLE_MOBILE_DATA_BY_USER, Binder.getCallingUid(),
+ callingPackage, null, null);
+ }
+
final long identity = Binder.clearCallingIdentity();
try {
Phone phone = getPhone(subId);
@@ -12559,7 +12567,8 @@
* Unregisters for NTN signal strength changed from satellite modem.
* If callback was not registered before, the request will be ignored.
*
- * @param subId The subId of the subscription to unregister for provision state changed.
+ * @param subId The subId of the subscription to unregister for listening NTN signal strength
+ * changed event.
* @param callback The callback that was passed to
* {@link #registerForNtnSignalStrengthChanged(int, INtnSignalStrengthCallback)}
*
@@ -12578,6 +12587,50 @@
}
/**
+ * Registers for satellite capabilities change event from the satellite service.
+ *
+ * @param subId The subId of the subscription to request for.
+ * @param callback The callback to handle the satellite capabilities changed event.
+ *
+ * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ */
+ @Override
+ @SatelliteManager.SatelliteResult public int registerForSatelliteCapabilitiesChanged(
+ int subId, @NonNull ISatelliteCapabilitiesCallback callback) {
+ enforceSatelliteCommunicationPermission("registerForSatelliteCapabilitiesChanged");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return mSatelliteController.registerForSatelliteCapabilitiesChanged(subId, callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
+ * Unregisters for satellite capabilities change event from the satellite service.
+ * If callback was not registered before, the request will be ignored.
+ *
+ * @param subId The subId of the subscription to unregister for satellite capabilities change.
+ * @param callback The callback that was passed to.
+ * {@link #registerForSatelliteCapabilitiesChanged(int, ISatelliteCapabilitiesCallback)}.
+ *
+ * @throws SecurityException if the caller doesn't have required permission.
+ */
+ @Override
+ public void unregisterForSatelliteCapabilitiesChanged(
+ int subId, @NonNull ISatelliteCapabilitiesCallback callback) {
+ enforceSatelliteCommunicationPermission("unregisterForSatelliteCapabilitiesChanged");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mSatelliteController.unregisterForSatelliteCapabilitiesChanged(subId, callback);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ /**
* This API can be used by only CTS to update satellite vendor service package name.
*
* @param servicePackageName The package name of the satellite vendor service.
@@ -12667,6 +12720,56 @@
}
/**
+ * This API can be used in only testing to override connectivity status in monitoring emergency
+ * calls and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.
+ *
+ * @param handoverType The type of handover from emergency call to satellite messaging. Use one
+ * of the following values to enable the override:
+ * 0 - EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS
+ * 1 - EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911
+ * To disable the override, use -1 for handoverType.
+ * @param delaySeconds The event EVENT_DISPLAY_EMERGENCY_MESSAGE will be sent to Dialer
+ * delaySeconds after the emergency call starts.
+ * @return {@code true} if the handover type is set successfully, {@code false} otherwise.
+ */
+ public boolean setEmergencyCallToSatelliteHandoverType(int handoverType, int delaySeconds) {
+ Log.d(LOG_TAG, "setEmergencyCallToSatelliteHandoverType - " + handoverType);
+ TelephonyPermissions.enforceShellOnly(
+ Binder.getCallingUid(), "setEmergencyCallToSatelliteHandoverType");
+ TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+ "setEmergencyCallToSatelliteHandoverType");
+ return mSatelliteController.setEmergencyCallToSatelliteHandoverType(
+ handoverType, delaySeconds);
+ }
+
+ /**
+ * This API can be used by only CTS to override the cached value for the device overlay config
+ * value : config_send_satellite_datagram_to_modem_in_demo_mode, which determines whether
+ * outgoing satellite datagrams should be sent to modem in demo mode.
+ *
+ * @param shouldSendToModemInDemoMode Whether send datagram in demo mode should be sent to
+ * satellite modem or not.
+ *
+ * @return {@code true} if the operation is successful, {@code false} otherwise.
+ */
+ public boolean setShouldSendDatagramToModemInDemoMode(boolean shouldSendToModemInDemoMode) {
+ if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
+ Log.d(LOG_TAG, "shouldSendDatagramToModemInDemoMode: oemEnabledSatelliteFlag is "
+ + "disabled");
+ return false;
+ }
+ Log.d(LOG_TAG, "setShouldSendDatagramToModemInDemoMode");
+ TelephonyPermissions.enforceShellOnly(
+ Binder.getCallingUid(), "setShouldSendDatagramToModemInDemoMode");
+ TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+ "setShouldSendDatagramToModemInDemoMode");
+ return mSatelliteController.setShouldSendDatagramToModemInDemoMode(
+ shouldSendToModemInDemoMode);
+ }
+
+ /**
* Check whether the caller (or self, if not processing an IPC) can read device identifiers.
*
* <p>This method behaves in one of the following ways:
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 1ee48c4..5986a7c 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -189,6 +189,10 @@
"set-satellite-pointing-ui-class-name";
private static final String SET_SATELLITE_DEVICE_ALIGNED_TIMEOUT_DURATION =
"set-satellite-device-aligned-timeout-duration";
+ private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
+ "set-emergency-call-to-satellite-handover-type";
+ private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
+ "set-should-send-datagram-to-modem-in-demo-mode";
private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
+ "'*', '#' or '+') needs to be specified after -a in the command ";
@@ -380,6 +384,10 @@
return handleSetSatellitePointingUiClassNameCommand();
case SET_SATELLITE_DEVICE_ALIGNED_TIMEOUT_DURATION:
return handleSettSatelliteDeviceAlignedTimeoutDuration();
+ case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
+ return handleSetEmergencyCallToSatelliteHandoverType();
+ case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
+ return handleSetShouldSendDatagramToModemInDemoMode();
default: {
return handleDefaultCommands(cmd);
}
@@ -779,6 +787,14 @@
pw.println(" launch. If no option is specified, it will launch the default.");
pw.println(" -c: the satellite pointing UI app class name that Telephony will");
pw.println(" launch.");
+ pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
+ pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
+ pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
+ pw.println(" Options are:");
+ pw.println(" -t: the emergency call to satellite handover type.");
+ pw.println(" If no option is specified, override is disabled.");
+ pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
+ pw.println(" If no option is specified, there is no delay in sending the event.");
}
private void onHelpImei() {
@@ -3217,6 +3233,55 @@
return 0;
}
+ private int handleSetEmergencyCallToSatelliteHandoverType() {
+ PrintWriter errPw = getErrPrintWriter();
+ int handoverType = -1;
+ int delaySeconds = 0;
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "-t": {
+ try {
+ handoverType = Integer.parseInt(getNextArgRequired());
+ } catch (NumberFormatException e) {
+ errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
+ + " for handoverType");
+ return -1;
+ }
+ break;
+ }
+ case "-d": {
+ try {
+ delaySeconds = Integer.parseInt(getNextArgRequired());
+ } catch (NumberFormatException e) {
+ errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
+ + " for delaySeconds");
+ return -1;
+ }
+ break;
+ }
+ }
+ }
+ Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
+ + handoverType + ", delaySeconds=" + delaySeconds);
+
+ try {
+ boolean result =
+ mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
+ if (VDBG) {
+ Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
+ }
+ getOutPrintWriter().println(result);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
+ + ", error = " + e.getMessage());
+ errPw.println("Exception: " + e.getMessage());
+ return -1;
+ }
+ return 0;
+ }
+
private int handleSetSatelliteListeningTimeoutDuration() {
PrintWriter errPw = getErrPrintWriter();
long timeoutMillis = 0;
@@ -3281,6 +3346,54 @@
return 0;
}
+ private int handleSetShouldSendDatagramToModemInDemoMode() {
+ PrintWriter errPw = getErrPrintWriter();
+ String opt;
+ boolean shouldSendToDemoMode;
+
+ if ((opt = getNextArg()) == null) {
+ errPw.println(
+ "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
+ + " Invalid Argument");
+ return -1;
+ } else {
+ switch (opt) {
+ case "true": {
+ shouldSendToDemoMode = true;
+ break;
+ }
+ case "false": {
+ shouldSendToDemoMode = false;
+ break;
+ }
+ default:
+ errPw.println(
+ "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
+ + " Invalid Argument");
+ return -1;
+ }
+ }
+
+ Log.d(LOG_TAG,
+ "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
+
+ try {
+ boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
+ shouldSendToDemoMode);
+ if (VDBG) {
+ Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
+ + result);
+ }
+ getOutPrintWriter().println(false);
+ } catch (RemoteException e) {
+ Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
+ + "), error = " + e.getMessage());
+ errPw.println("Exception: " + e.getMessage());
+ return -1;
+ }
+ return 0;
+ }
+
private int handleCarrierRestrictionStatusCommand() {
try {
String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 8cb36d9..48169a2 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -19,8 +19,8 @@
import static android.telephony.CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL;
import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
-import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
+import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
import static com.android.internal.telephony.flags.Flags.carrierEnabledSatelliteFlag;
import android.annotation.NonNull;
@@ -1389,7 +1389,7 @@
// one and causing UI Jank.
boolean noActiveSimCard = SubscriptionManagerService.getInstance()
.getActiveSubInfoCount(phone.getContext().getOpPackageName(),
- phone.getContext().getAttributionTag()) == 0;
+ phone.getContext().getAttributionTag(), true/*isForAllProfile*/) == 0;
// If there's no active sim card and the device is in emergency mode, use E account.
addExistingConnection(mPhoneUtilsProxy.makePstnPhoneAccountHandleWithPrefix(
phone, "", isEmergencyNumber && noActiveSimCard), repConnection);
@@ -4184,11 +4184,11 @@
private void handleEmergencyCallStartedForSatelliteSOSMessageRecommender(
@NonNull TelephonyConnection connection, @NonNull Phone phone) {
if (mSatelliteSOSMessageRecommender == null) {
- mSatelliteSOSMessageRecommender = new SatelliteSOSMessageRecommender(
+ mSatelliteSOSMessageRecommender = new SatelliteSOSMessageRecommender(phone.getContext(),
phone.getContext().getMainLooper());
}
connection.addTelephonyConnectionListener(mEmergencyConnectionSatelliteListener);
- mSatelliteSOSMessageRecommender.onEmergencyCallStarted(connection, phone);
+ mSatelliteSOSMessageRecommender.onEmergencyCallStarted(connection);
}
/**
diff --git a/src/com/android/services/telephony/domainselection/CarrierConfigHelper.java b/src/com/android/services/telephony/domainselection/CarrierConfigHelper.java
new file mode 100644
index 0000000..d39a6b7
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/CarrierConfigHelper.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2023 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.services.telephony.domainselection;
+
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.NGRAN;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.os.SystemProperties;
+import android.preference.PreferenceManager;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.phone.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/** Helper class to cache carrier configurations. */
+public class CarrierConfigHelper extends Handler {
+ private static final String TAG = "CarrierConfigHelper";
+ private static final boolean DBG = (SystemProperties.getInt("ro.debuggable", 0) == 1);
+
+ @VisibleForTesting
+ public static final String KEY_VONR_EMERGENCY_SUPPORT = "vonr_emergency_support";
+
+ private final Context mContext;
+ private final CarrierConfigManager mConfigManager;
+ private final TelephonyManager mTelephonyManager;
+ private final ArrayMap<Integer, Boolean> mVoNrSupported = new ArrayMap<>();
+
+ private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
+ (slotIndex, subId, carrierId, specificCarrierId) -> onCarrierConfigurationChanged(
+ slotIndex, subId, carrierId);
+
+ // For test purpose only
+ private final SharedPreferences mSharedPreferences;
+
+ private List<Integer> mIgnoreNrWhenSimRemoved = null;
+
+ /**
+ * Creates an instance.
+ *
+ * @param context The Context this is associated with.
+ * @param looper The Looper to run the CarrierConfigHelper.
+ */
+ public CarrierConfigHelper(@NonNull Context context, @NonNull Looper looper) {
+ this(context, looper, null);
+ }
+
+ /**
+ * Creates an instance.
+ *
+ * @param context The Context this is associated with.
+ * @param looper The Looper to run the CarrierConfigHelper.
+ * @param sharedPreferences The SharedPreferences instance.
+ */
+ @VisibleForTesting
+ public CarrierConfigHelper(@NonNull Context context, @NonNull Looper looper,
+ @Nullable SharedPreferences sharedPreferences) {
+ super(looper);
+
+ mContext = context;
+ mTelephonyManager = context.getSystemService(TelephonyManager.class);
+ mConfigManager = context.getSystemService(CarrierConfigManager.class);
+ mConfigManager.registerCarrierConfigChangeListener(this::post,
+ mCarrierConfigChangeListener);
+ mSharedPreferences = sharedPreferences;
+
+ readFromSharedPreference();
+ readResourceConfiguration();
+ }
+
+ /**
+ * Returns whether VoNR emergency was supported with the last valid subscription.
+ *
+ * @param slotIndex The SIM slot index.
+ * @return true if VoNR emergency was supported with the last valid subscription.
+ * Otherwise, false.
+ */
+ public boolean isVoNrEmergencySupported(int slotIndex) {
+ return mVoNrSupported.get(Integer.valueOf(slotIndex));
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ default:
+ super.handleMessage(msg);
+ break;
+ }
+ }
+
+ private void readFromSharedPreference() {
+ mVoNrSupported.clear();
+ int modemCount = mTelephonyManager.getActiveModemCount();
+ SharedPreferences sp = (mSharedPreferences != null) ? mSharedPreferences
+ : PreferenceManager.getDefaultSharedPreferences(mContext);
+ for (int i = 0; i < modemCount; i++) {
+ Boolean savedConfig = Boolean.valueOf(
+ sp.getBoolean(KEY_VONR_EMERGENCY_SUPPORT + i, false));
+ mVoNrSupported.put(Integer.valueOf(i), savedConfig);
+ Log.i(TAG, "readFromSharedPreference slot=" + i + ", " + savedConfig);
+ }
+ }
+
+ private void onCarrierConfigurationChanged(int slotIndex, int subId, int carrierId) {
+ Log.i(TAG, "onCarrierConfigurationChanged slotIndex=" + slotIndex
+ + ", subId=" + subId + ", carrierId=" + carrierId);
+
+ if (slotIndex < 0
+ || !SubscriptionManager.isValidSubscriptionId(subId)
+ || mTelephonyManager.getSimState(slotIndex) != TelephonyManager.SIM_STATE_READY) {
+ return;
+ }
+
+ PersistableBundle b = mConfigManager.getConfigForSubId(subId,
+ KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY);
+ if (b.isEmpty()) {
+ Log.e(TAG, "onCarrierConfigurationChanged empty result");
+ return;
+ }
+
+ if (!CarrierConfigManager.isConfigForIdentifiedCarrier(b)) {
+ Log.i(TAG, "onCarrierConfigurationChanged not carrier specific configuration");
+ return;
+ }
+
+ int[] imsRatsConfig = b.getIntArray(
+ KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY);
+ if (imsRatsConfig == null) imsRatsConfig = new int[0];
+ boolean carrierConfig = false;
+ for (int i = 0; i < imsRatsConfig.length; i++) {
+ if (imsRatsConfig[i] == NGRAN) {
+ carrierConfig = true;
+ break;
+ }
+ }
+ if (mIgnoreNrWhenSimRemoved.contains(carrierId)) carrierConfig = false;
+
+ Boolean savedConfig = mVoNrSupported.get(Integer.valueOf(slotIndex));
+ if (carrierConfig == savedConfig) {
+ return;
+ }
+
+ mVoNrSupported.put(Integer.valueOf(slotIndex), Boolean.valueOf(carrierConfig));
+
+ SharedPreferences sp = (mSharedPreferences != null) ? mSharedPreferences
+ : PreferenceManager.getDefaultSharedPreferences(mContext);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.putBoolean(KEY_VONR_EMERGENCY_SUPPORT + slotIndex, carrierConfig);
+ editor.apply();
+
+ Log.i(TAG, "onCarrierConfigurationChanged preference updated slotIndex=" + slotIndex
+ + ", supported=" + carrierConfig);
+ }
+
+ private void readResourceConfiguration() {
+ try {
+ mIgnoreNrWhenSimRemoved = Arrays.stream(mContext.getResources().getIntArray(
+ R.array.config_carriers_ignore_ngran_preference_when_sim_removed))
+ .boxed().collect(Collectors.toList());
+ } catch (Resources.NotFoundException nfe) {
+ Log.e(TAG, "readResourceConfiguration exception=" + nfe);
+ } catch (NullPointerException npe) {
+ Log.e(TAG, "readResourceConfiguration exception=" + npe);
+ }
+ if (mIgnoreNrWhenSimRemoved == null) {
+ mIgnoreNrWhenSimRemoved = new ArrayList<Integer>();
+ }
+ Log.i(TAG, "readResourceConfiguration ignoreNrWhenSimRemoved=" + mIgnoreNrWhenSimRemoved);
+ }
+
+ /** Destroys the instance. */
+ public void destroy() {
+ if (DBG) Log.d(TAG, "destroy");
+ mConfigManager.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener);
+ }
+}
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index ae0ca29..3d6a4d1 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -57,6 +57,7 @@
import android.annotation.NonNull;
import android.content.Context;
+import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
@@ -89,6 +90,7 @@
import android.util.LocalLog;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.phone.R;
import java.util.ArrayList;
import java.util.Arrays;
@@ -117,17 +119,7 @@
private static final LocalLog sLocalLog = new LocalLog(LOG_SIZE);
- private static final ArrayList<String> sAllowOnlyWithSimReady = new ArrayList<>();
-
- static {
- // b/177967010, JP
- sAllowOnlyWithSimReady.add("jp"); // Japan
- // b/198393826, DE
- sAllowOnlyWithSimReady.add("de"); // Germany
- // b/230443699, IN and SG
- sAllowOnlyWithSimReady.add("in"); // India
- sAllowOnlyWithSimReady.add("sg"); // Singapore
- }
+ private static List<String> sSimReadyAllowList;
/**
* Network callback used to determine whether Wi-Fi is connected or not.
@@ -218,12 +210,14 @@
private final PowerManager.WakeLock mPartialWakeLock;
private final CrossSimRedialingController mCrossSimRedialingController;
+ private final CarrierConfigHelper mCarrierConfigHelper;
/** Constructor. */
public EmergencyCallDomainSelector(Context context, int slotId, int subId,
@NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
@NonNull DestroyListener destroyListener,
- @NonNull CrossSimRedialingController csrController) {
+ @NonNull CrossSimRedialingController csrController,
+ @NonNull CarrierConfigHelper carrierConfigHelper) {
super(context, slotId, subId, looper, imsStateTracker, destroyListener, TAG);
mImsStateTracker.addBarringInfoListener(this);
@@ -233,6 +227,7 @@
mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mCrossSimRedialingController = csrController;
+ mCarrierConfigHelper = carrierConfigHelper;
acquireWakeLock();
}
@@ -449,6 +444,7 @@
private void startDomainSelection() {
logi("startDomainSelection modemCount=" + mModemCount);
+ readResourceConfiguration();
updateCarrierConfiguration();
mDomainSelectionRequested = true;
startCrossStackTimer();
@@ -503,11 +499,7 @@
b.getIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY);
mImsRoamRatsConfig = b.getIntArray(
KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY);
- if (!SubscriptionManager.isValidSubscriptionId(getSubId())) {
- // Default configuration includes only EUTRAN . In case of no SIM, add NGRAN.
- mImsRatsConfig = new int[] { EUTRAN, NGRAN };
- mImsRoamRatsConfig = new int[] { EUTRAN, NGRAN };
- }
+ maybeModifyImsRats();
mCsRatsConfig =
b.getIntArray(KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY);
@@ -577,6 +569,42 @@
}
}
+ /** Adds NGRAN if SIM is absent or locked and the last valid subscription supported NGRAN. */
+ private void maybeModifyImsRats() {
+ if (mCarrierConfigHelper.isVoNrEmergencySupported(getSlotId())
+ && !isSimReady() && mImsRatsConfig.length < 2) {
+ // Default configuration includes only EUTRAN.
+ mImsRatsConfig = new int[] { EUTRAN, NGRAN };
+ mImsRoamRatsConfig = new int[] { EUTRAN, NGRAN };
+ }
+ }
+
+ /**
+ * Caches the resource configuration.
+ */
+ private void readResourceConfiguration() {
+ if (sSimReadyAllowList != null) return;
+ try {
+ sSimReadyAllowList = Arrays.asList(mContext.getResources().getStringArray(
+ R.array.config_countries_require_sim_for_emergency));
+ } catch (Resources.NotFoundException nfe) {
+ loge("readResourceConfiguration exception=" + nfe);
+ } catch (NullPointerException npe) {
+ loge("readResourceConfiguration exception=" + npe);
+ } finally {
+ if (sSimReadyAllowList == null) {
+ sSimReadyAllowList = new ArrayList<String>();
+ }
+ }
+ logi("readResourceConfiguration simReadyCountries=" + sSimReadyAllowList);
+ }
+
+ /** For test purpose only */
+ @VisibleForTesting
+ public void clearResourceConfiguration() {
+ sSimReadyAllowList = null;
+ }
+
private void selectDomain() {
// State updated right after creation.
if (!mDomainSelectionRequested) return;
@@ -829,6 +857,11 @@
}
}
+ // Adds NGRAN at the end of the list if SIM is absent or locked and NGRAN is not included.
+ if (!isSimReady() && !preferredNetworks.contains(NGRAN)) {
+ preferredNetworks.add(NGRAN);
+ }
+
return preferredNetworks;
}
@@ -1335,7 +1368,7 @@
}
String iso = regResult.getIso();
- if (sAllowOnlyWithSimReady.contains(iso)) {
+ if (sSimReadyAllowList.contains(iso)) {
TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
int simState = tm.getSimState(getSlotId());
if (simState != TelephonyManager.SIM_STATE_READY) {
diff --git a/src/com/android/services/telephony/domainselection/OWNERS b/src/com/android/services/telephony/domainselection/OWNERS
new file mode 100644
index 0000000..b9112be
--- /dev/null
+++ b/src/com/android/services/telephony/domainselection/OWNERS
@@ -0,0 +1,8 @@
+# automatically inherit owners from fw/opt/telephony
+
+hwangoo@google.com
+forestchoi@google.com
+avinashmp@google.com
+mkoon@google.com
+seheele@google.com
+radhikaagrawal@google.com
diff --git a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
index 3a8fc86..de2d752 100644
--- a/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
+++ b/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionService.java
@@ -17,6 +17,7 @@
package com.android.services.telephony.domainselection;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
@@ -71,7 +72,8 @@
@SelectorType int selectorType, boolean isEmergency, @NonNull Looper looper,
@NonNull ImsStateTracker imsStateTracker,
@NonNull DomainSelectorBase.DestroyListener listener,
- @NonNull CrossSimRedialingController crossSimRedialingController);
+ @NonNull CrossSimRedialingController crossSimRedialingController,
+ @NonNull CarrierConfigHelper carrierConfigHelper);
}
private static final class DefaultDomainSelectorFactory implements DomainSelectorFactory {
@@ -80,7 +82,8 @@
@SelectorType int selectorType, boolean isEmergency, @NonNull Looper looper,
@NonNull ImsStateTracker imsStateTracker,
@NonNull DomainSelectorBase.DestroyListener listener,
- @NonNull CrossSimRedialingController crossSimRedialingController) {
+ @NonNull CrossSimRedialingController crossSimRedialingController,
+ @NonNull CarrierConfigHelper carrierConfigHelper) {
DomainSelectorBase selector = null;
logi("create-DomainSelector: slotId=" + slotId + ", subId=" + subId
@@ -91,7 +94,8 @@
case SELECTOR_TYPE_CALLING:
if (isEmergency) {
selector = new EmergencyCallDomainSelector(context, slotId, subId, looper,
- imsStateTracker, listener, crossSimRedialingController);
+ imsStateTracker, listener, crossSimRedialingController,
+ carrierConfigHelper);
} else {
selector = new NormalCallDomainSelector(context, slotId, subId, looper,
imsStateTracker, listener);
@@ -195,15 +199,17 @@
private final DomainSelectorFactory mDomainSelectorFactory;
private Handler mServiceHandler;
private CrossSimRedialingController mCrossSimRedialingController;
+ private CarrierConfigHelper mCarrierConfigHelper;
public TelephonyDomainSelectionService(Context context) {
- this(context, ImsStateTracker::new, new DefaultDomainSelectorFactory());
+ this(context, ImsStateTracker::new, new DefaultDomainSelectorFactory(), null);
}
@VisibleForTesting
public TelephonyDomainSelectionService(Context context,
@NonNull ImsStateTrackerFactory imsStateTrackerFactory,
- @NonNull DomainSelectorFactory domainSelectorFactory) {
+ @NonNull DomainSelectorFactory domainSelectorFactory,
+ @Nullable CarrierConfigHelper carrierConfigHelper) {
mContext = context;
mImsStateTrackerFactory = imsStateTrackerFactory;
mDomainSelectorFactory = domainSelectorFactory;
@@ -225,6 +231,8 @@
}
mCrossSimRedialingController = new CrossSimRedialingController(context, getLooper());
+ mCarrierConfigHelper = (carrierConfigHelper != null)
+ ? carrierConfigHelper : new CarrierConfigHelper(context, getLooper());
logi("TelephonyDomainSelectionService created");
}
@@ -268,6 +276,11 @@
mCrossSimRedialingController = null;
}
+ if (mCarrierConfigHelper != null) {
+ mCarrierConfigHelper.destroy();
+ mCarrierConfigHelper = null;
+ }
+
if (mServiceHandler != null) {
mServiceHandler.getLooper().quit();
mServiceHandler = null;
@@ -290,7 +303,7 @@
ImsStateTracker ist = getImsStateTracker(slotId);
DomainSelectorBase selector = mDomainSelectorFactory.create(mContext, slotId, subId,
selectorType, isEmergency, getLooper(), ist, mDestroyListener,
- mCrossSimRedialingController);
+ mCrossSimRedialingController, mCarrierConfigHelper);
if (selector != null) {
// Ensures that ImsStateTracker is started before selecting the domain if not started
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml
index 90a6f94..0753b82 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteTestApp.xml
@@ -68,7 +68,7 @@
android:id="@+id/TestSatelliteWrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingRight="4dp"
+ android:paddingEnd="4dp"
android:text="@string/TestSatelliteWrapper"/>
</LinearLayout>
</LinearLayout>
diff --git a/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml b/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
index 3365bb9..c136ce7 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
@@ -21,78 +21,84 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
- android:paddingLeft="4dp">
+ android:paddingStart="4dp">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_weight="0"
+ android:textColor="@android:color/holo_blue_dark"
+ android:textSize="20dp"
+ android:text="Satellite Wrapper Test"/>
+ <Button
+ android:id="@+id/requestNtnSignalStrength"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/requestNtnSignalStrength"/>
+ <Button
+ android:id="@+id/registerForNtnSignalStrengthChanged"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/registerForNtnSignalStrengthChanged"/>
+ <Button
+ android:id="@+id/unregisterForNtnSignalStrengthChanged"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/unregisterForNtnSignalStrengthChanged"/>
+ <Button
+ android:id="@+id/isOnlyNonTerrestrialNetworkSubscription"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/isOnlyNonTerrestrialNetworkSubscription"/>
+ <Button
+ android:id="@+id/registerForSatelliteCapabilitiesChanged"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/registerForSatelliteCapabilitiesChanged"/>
+ <Button
+ android:id="@+id/unregisterForSatelliteCapabilitiesChanged"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dp"
+ android:text="@string/unregisterForSatelliteCapabilitiesChanged"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical" >
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="0"
+ android:orientation="horizontal">
+ <Button
+ android:id="@+id/Back"
+ android:onClick="Back"
android:textColor="@android:color/holo_blue_dark"
- android:textSize="20dp"
- android:text="Satellite Wrapper Test"/>
- <Button
- android:id="@+id/requestNtnSignalStrength"
- android:layout_width="match_parent"
+ android:layout_marginTop="10dp"
+ android:layout_marginBottom="10dp"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
+ android:layout_weight="1"
android:paddingRight="4dp"
- android:text="@string/requestNtnSignalStrength"/>
+ android:text="@string/Back"/>
<Button
- android:id="@+id/registerForNtnSignalStrengthChanged"
- android:layout_width="match_parent"
+ android:id="@+id/ClearLog"
+ android:onClick="ClearLog"
+ android:textColor="@android:color/holo_blue_dark"
+ android:layout_marginTop="10dp"
+ android:layout_marginBottom="10dp"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
+ android:layout_weight="1"
android:paddingRight="4dp"
- android:text="@string/registerForNtnSignalStrengthChanged"/>
- <Button
- android:id="@+id/unregisterForNtnSignalStrengthChanged"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingRight="4dp"
- android:text="@string/unregisterForNtnSignalStrengthChanged"/>
- <Button
- android:id="@+id/isOnlyNonTerrestrialNetworkSubscription"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingRight="4dp"
- android:text="@string/isOnlyNonTerrestrialNetworkSubscription"/>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <Button
- android:id="@+id/Back"
- android:onClick="Back"
- android:textColor="@android:color/holo_blue_dark"
- android:layout_marginTop="10dp"
- android:layout_marginBottom="10dp"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingRight="4dp"
- android:text="@string/Back"/>
- <Button
- android:id="@+id/ClearLog"
- android:onClick="ClearLog"
- android:textColor="@android:color/holo_blue_dark"
- android:layout_marginTop="10dp"
- android:layout_marginBottom="10dp"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:paddingRight="4dp"
- android:text="@string/ClearLog"/>
- </LinearLayout>
- <ListView
- android:id="@+id/logListView"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:capitalize="characters"
- android:textColor="@android:color/holo_blue_light"
- android:layout_centerVertical="true"
- android:textSize="8dp" />
+ android:text="@string/ClearLog"/>
</LinearLayout>
+ <ListView
+ android:id="@+id/logListView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:capitalize="characters"
+ android:textColor="@android:color/holo_blue_light"
+ android:layout_centerVertical="true"
+ android:textSize="8dp" />
</LinearLayout>
diff --git a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
index 5ab2475..8ebe5f3 100644
--- a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
+++ b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
@@ -62,6 +62,8 @@
<string name="registerForNtnSignalStrengthChanged">registerForNtnSignalStrengthChanged</string>
<string name="unregisterForNtnSignalStrengthChanged">unregisterForNtnSignalStrengthChanged</string>
<string name="isOnlyNonTerrestrialNetworkSubscription">isOnlyNonTerrestrialNetworkSubscription</string>
+ <string name="registerForSatelliteCapabilitiesChanged">registerForSatelliteCapabilitiesChanged</string>
+ <string name="unregisterForSatelliteCapabilitiesChanged">unregisterForSatelliteCapabilitiesChanged</string>
<string name="Back">Back</string>
<string name="ClearLog">Clear Log</string>
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
index 13b31f3..20efecb 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
@@ -25,6 +25,7 @@
import android.telephony.SubscriptionManager;
import android.telephony.satellite.wrapper.NtnSignalStrengthCallbackWrapper;
import android.telephony.satellite.wrapper.NtnSignalStrengthWrapper;
+import android.telephony.satellite.wrapper.SatelliteCapabilitiesCallbackWrapper;
import android.telephony.satellite.wrapper.SatelliteManagerWrapper;
import android.util.Log;
import android.view.View;
@@ -51,7 +52,9 @@
private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
private SatelliteManagerWrapper mSatelliteManagerWrapper;
private NtnSignalStrengthCallback mNtnSignalStrengthCallback = null;
+ private SatelliteCapabilitiesCallbackWrapper mSatelliteCapabilitiesCallback;
private SubscriptionManager mSubscriptionManager;
+
private ListView mLogListView;
@Override
@@ -69,6 +72,10 @@
.setOnClickListener(this::unregisterForNtnSignalStrengthChanged);
findViewById(R.id.isOnlyNonTerrestrialNetworkSubscription)
.setOnClickListener(this::isOnlyNonTerrestrialNetworkSubscription);
+ findViewById(R.id.registerForSatelliteCapabilitiesChanged)
+ .setOnClickListener(this::registerForSatelliteCapabilitiesChanged);
+ findViewById(R.id.unregisterForSatelliteCapabilitiesChanged)
+ .setOnClickListener(this::unregisterForSatelliteCapabilitiesChanged);
findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
@@ -99,10 +106,17 @@
protected void onDestroy() {
super.onDestroy();
- if (mSatelliteManagerWrapper != null && mNtnSignalStrengthCallback != null) {
- Log.d(TAG, "unregisterForNtnSignalStrengthChanged()");
- mSatelliteManagerWrapper.unregisterForNtnSignalStrengthChanged(
- mNtnSignalStrengthCallback);
+ if (mSatelliteManagerWrapper != null) {
+ if (mNtnSignalStrengthCallback != null) {
+ Log.d(TAG, "unregisterForNtnSignalStrengthChanged()");
+ mSatelliteManagerWrapper.unregisterForNtnSignalStrengthChanged(
+ mNtnSignalStrengthCallback);
+ }
+ if (mSatelliteCapabilitiesCallback != null) {
+ Log.d(TAG, "unregisterForSatelliteCapabilitiesChanged()");
+ mSatelliteManagerWrapper.unregisterForSatelliteCapabilitiesChanged(
+ mSatelliteCapabilitiesCallback);
+ }
}
}
@@ -191,6 +205,42 @@
}
}
+ private void registerForSatelliteCapabilitiesChanged(View view) {
+ addLogMessage("registerForSatelliteCapabilitiesChanged");
+ Log.d(TAG, "registerForSatelliteCapabilitiesChanged()");
+ if (mSatelliteCapabilitiesCallback == null) {
+ mSatelliteCapabilitiesCallback =
+ SatelliteCapabilities -> {
+ String message = "Received SatelliteCapabillities : "
+ + SatelliteCapabilities;
+ Log.d(TAG, message);
+ runOnUiThread(() -> addLogMessage(message));
+ };
+ }
+
+ int result = mSatelliteManagerWrapper.registerForSatelliteCapabilitiesChanged(mExecutor,
+ mSatelliteCapabilitiesCallback);
+ if (result != SatelliteManagerWrapper.SATELLITE_RESULT_SUCCESS) {
+ String onError = translateResultCodeToString(result);
+ Log.d(TAG, onError);
+ addLogMessage(onError);
+ mSatelliteCapabilitiesCallback = null;
+ }
+ }
+
+ private void unregisterForSatelliteCapabilitiesChanged(View view) {
+ addLogMessage("unregisterForSatelliteCapabilitiesChanged");
+ Log.d(TAG, "unregisterForSatelliteCapabilitiesChanged()");
+ if (mSatelliteCapabilitiesCallback != null) {
+ mSatelliteManagerWrapper.unregisterForSatelliteCapabilitiesChanged(
+ mSatelliteCapabilitiesCallback);
+ mSatelliteCapabilitiesCallback = null;
+ addLogMessage("mSatelliteCapabilitiesCallback was unregistered");
+ } else {
+ addLogMessage("mSatelliteCapabilitiesCallback is null, ignored.");
+ }
+ }
+
public class NtnSignalStrengthCallback implements NtnSignalStrengthCallbackWrapper {
@Override
public void onNtnSignalStrengthChanged(
diff --git a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
index bea4271..150703d 100644
--- a/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
+++ b/tests/src/com/android/phone/PhoneInterfaceManagerTest.java
@@ -34,6 +34,8 @@
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
+import android.permission.flags.Flags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.telephony.RadioAccessFamily;
import android.telephony.TelephonyManager;
@@ -48,6 +50,7 @@
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -73,6 +76,8 @@
@Mock
private SubscriptionManagerService mSubscriptionManagerService;
+ @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
@UiThreadTest
public void setUp() throws Exception {
@@ -286,4 +291,72 @@
mPhoneInterfaceManager.getCarrierRestrictionStatus(mIIntegerConsumer,
"com.test.package");
}
+
+ @Test
+ public void notifyEnableDataWithAppOps_enableByUser_doNoteOp() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER);
+ String packageName = "INVALID_PACKAGE";
+ String error = "";
+ try {
+ mPhoneInterfaceManager.setDataEnabledForReason(1,
+ TelephonyManager.DATA_ENABLED_REASON_USER, true, packageName);
+ } catch (SecurityException expected) {
+ // The test doesn't have access to note the op, but we're just interested that it makes
+ // the attempt.
+ error = expected.getMessage();
+ }
+
+ String appop = "ENABLE_MOBILE_DATA_BY_USER";
+ assertTrue("expected error to contain " + packageName + " but it didn't: " + error,
+ error.contains(packageName));
+ assertTrue("expected error to contain " + appop + " but it didn't: " + error,
+ error.contains(appop));
+ }
+
+ @Test
+ public void notifyEnableDataWithAppOps_enableByCarrier_doNotNoteOp() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER);
+ String packageName = "INVALID_PACKAGE";
+ String error = "";
+ try {
+ mPhoneInterfaceManager.setDataEnabledForReason(1,
+ TelephonyManager.DATA_ENABLED_REASON_CARRIER, true, packageName);
+ } catch (SecurityException expected) {
+ // The test doesn't have access to note the op, but we're just interested that it makes
+ // the attempt.
+ error = expected.getMessage();
+ }
+ assertEquals("Expected error to be empty, was " + error, error, "");
+ }
+
+ @Test
+ public void notifyEnableDataWithAppOps_disableByUser_doNotNoteOp() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER);
+ String packageName = "INVALID_PACKAGE";
+ String error = "";
+ try {
+ mPhoneInterfaceManager.setDataEnabledForReason(1,
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, packageName);
+ } catch (SecurityException expected) {
+ // The test doesn't have access to note the op, but we're just interested that it makes
+ // the attempt.
+ error = expected.getMessage();
+ }
+ assertEquals("Expected error to be empty, was " + error, error, "");
+ }
+
+ @Test
+ public void notifyEnableDataWithAppOps_noPackageNameAndEnableByUser_doNotnoteOp() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER);
+ String error = "";
+ try {
+ mPhoneInterfaceManager.setDataEnabledForReason(1,
+ TelephonyManager.DATA_ENABLED_REASON_USER, false, null);
+ } catch (SecurityException expected) {
+ // The test doesn't have access to note the op, but we're just interested that it makes
+ // the attempt.
+ error = expected.getMessage();
+ }
+ assertEquals("Expected error to be empty, was " + error, error, "");
+ }
}
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index 1110341..653b492 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -303,7 +303,7 @@
mTestConnectionService, mEmergencyStateTracker);
replaceInstance(TelephonyConnectionService.class, "mSatelliteSOSMessageRecommender",
mTestConnectionService, mSatelliteSOSMessageRecommender);
- doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), any());
+ doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
doNothing().when(mSatelliteSOSMessageRecommender).onEmergencyCallConnectionStateChanged(
anyString(), anyInt());
doReturn(CompletableFuture.completedFuture(NOT_DISCONNECTED))
@@ -1335,7 +1335,7 @@
// This shouldn't happen
fail();
}
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
}
/**
@@ -1447,7 +1447,7 @@
// This shouldn't happen
fail();
}
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), any());
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
}
/**
@@ -2128,7 +2128,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2158,7 +2158,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2189,7 +2189,7 @@
verify(mEmergencyStateTracker, times(1))
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
verify(mDomainSelectionResolver, times(0))
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyCallDomainSelectionConnection, times(0))
@@ -2285,7 +2285,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2326,7 +2326,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2367,7 +2367,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2664,7 +2664,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2705,7 +2705,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -2969,7 +2969,7 @@
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
// dialing is canceled
mTestConnectionService.onLocalHangup(c);
@@ -3037,7 +3037,7 @@
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
verify(mEmergencyStateTracker)
.startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
- verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+ verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any());
verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
verify(mPhone0).dial(anyString(), any(), any());
@@ -3229,7 +3229,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
- verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any(), any());
+ verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
@@ -3254,7 +3254,7 @@
verify(mDomainSelectionResolver)
.getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
- verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any(), any());
+ verify(mSatelliteSOSMessageRecommender, never()).onEmergencyCallStarted(any());
ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
diff --git a/tests/src/com/android/services/telephony/domainselection/CarrierConfigHelperTest.java b/tests/src/com/android/services/telephony/domainselection/CarrierConfigHelperTest.java
new file mode 100644
index 0000000..5d4fe17
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/CarrierConfigHelperTest.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2023 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.services.telephony.domainselection;
+
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.NGRAN;
+import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertNotNull;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.testing.TestableLooper;
+import android.util.Log;
+
+import com.android.TestContext;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Unit tests for CarrierConfigHelper
+ */
+public class CarrierConfigHelperTest {
+ private static final String TAG = "CarrierConfigHelperTest";
+
+ private static final int SLOT_0 = 0;
+ private static final int SLOT_1 = 1;
+ private static final int SUB_1 = 1;
+ private static final int TEST_SIM_CARRIER_ID = 1911;
+
+ @Mock private Context mContext;
+ @Mock private SharedPreferences mSharedPreferences;
+ @Mock private SharedPreferences.Editor mEditor;
+ @Mock private Resources mResources;
+
+ private HandlerThread mHandlerThread;
+ private TestableLooper mLooper;
+ private CarrierConfigHelper mCarrierConfigHelper;
+ private CarrierConfigManager mCarrierConfigManager;
+ private TelephonyManager mTelephonyManager;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mContext = new TestContext() {
+ @Override
+ public String getSystemServiceName(Class<?> serviceClass) {
+ if (serviceClass == TelephonyManager.class) {
+ return Context.TELEPHONY_SERVICE;
+ } else if (serviceClass == CarrierConfigManager.class) {
+ return Context.CARRIER_CONFIG_SERVICE;
+ }
+ return super.getSystemServiceName(serviceClass);
+ }
+
+ @Override
+ public String getOpPackageName() {
+ return "";
+ }
+
+ @Override
+ public Resources getResources() {
+ return mResources;
+ }
+ };
+
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ mHandlerThread = new HandlerThread("CarrierConfigHelperTest");
+ mHandlerThread.start();
+
+ try {
+ mLooper = new TestableLooper(mHandlerThread.getLooper());
+ } catch (Exception e) {
+ logd("Unable to create looper from handler.");
+ }
+
+ doReturn(mEditor).when(mSharedPreferences).edit();
+
+ mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
+ mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+ doReturn(2).when(mTelephonyManager).getActiveModemCount();
+ doReturn(TelephonyManager.SIM_STATE_READY)
+ .when(mTelephonyManager).getSimState(anyInt());
+
+ doReturn(new int[] { TEST_SIM_CARRIER_ID }).when(mResources).getIntArray(anyInt());
+
+ mCarrierConfigHelper = new CarrierConfigHelper(mContext, mHandlerThread.getLooper(),
+ mSharedPreferences);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (mCarrierConfigHelper != null) {
+ mCarrierConfigHelper.destroy();
+ mCarrierConfigHelper = null;
+ }
+
+ if (mLooper != null) {
+ mLooper.destroy();
+ mLooper = null;
+ }
+ }
+
+ @Test
+ public void testInit() throws Exception {
+ ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+ ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+ ArgumentCaptor<Executor> executorCaptor = ArgumentCaptor.forClass(Executor.class);
+
+ verify(mCarrierConfigManager).registerCarrierConfigChangeListener(executorCaptor.capture(),
+ callbackCaptor.capture());
+ assertNotNull(executorCaptor.getValue());
+ assertNotNull(callbackCaptor.getValue());
+ assertFalse(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_0));
+ }
+
+ @Test
+ public void testCarrierConfigNotApplied() throws Exception {
+ ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+ ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+
+ verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+ callbackCaptor.capture());
+
+ CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
+
+ assertNotNull(callback);
+
+ // NR is included but carrier config is not applied.
+ PersistableBundle b = getPersistableBundle(new int[] { EUTRAN, NGRAN }, false);
+ doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
+ callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
+
+ assertFalse(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_0));
+ }
+
+ @Test
+ public void testCarrierConfigApplied() throws Exception {
+ ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+ ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+
+ verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+ callbackCaptor.capture());
+
+ CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
+
+ assertNotNull(callback);
+
+ // NR is included and carrier config is applied.
+ PersistableBundle b = getPersistableBundle(new int[] { EUTRAN, NGRAN }, true);
+ doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
+ callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
+
+ assertTrue(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_0));
+ assertFalse(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_1));
+
+ verify(mEditor).putBoolean(eq(CarrierConfigHelper.KEY_VONR_EMERGENCY_SUPPORT + SLOT_0),
+ eq(true));
+
+ // NR is not included and carrier config is applied.
+ b = getPersistableBundle(new int[] { EUTRAN }, true);
+ doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
+ callback.onCarrierConfigChanged(SLOT_0, SUB_1, 0, 0);
+
+ assertFalse(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_0));
+
+ verify(mEditor).putBoolean(eq(CarrierConfigHelper.KEY_VONR_EMERGENCY_SUPPORT + SLOT_0),
+ eq(false));
+ }
+
+ @Test
+ public void testCarrierConfigInvalidSubId() throws Exception {
+ ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+ ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+
+ verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+ callbackCaptor.capture());
+
+ CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
+
+ assertNotNull(callback);
+
+ // NR is included and carrier config is applied.
+ PersistableBundle b = getPersistableBundle(new int[] { EUTRAN, NGRAN }, true);
+ doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
+
+ // Invalid subscription
+ callback.onCarrierConfigChanged(SLOT_0, SubscriptionManager.INVALID_SUBSCRIPTION_ID, 0, 0);
+
+ assertFalse(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_0));
+ }
+
+ @Test
+ public void testRestoreFromSharedPreferences() throws Exception {
+ doReturn(true).when(mSharedPreferences).getBoolean(anyString(), anyBoolean());
+ mCarrierConfigHelper = new CarrierConfigHelper(mContext, mHandlerThread.getLooper(),
+ mSharedPreferences);
+
+ assertTrue(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_0));
+ }
+
+ @Test
+ public void testCarrierIgnoreNrWhenSimRemoved() throws Exception {
+ ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> callbackCaptor =
+ ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
+
+ verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+ callbackCaptor.capture());
+
+ CarrierConfigManager.CarrierConfigChangeListener callback = callbackCaptor.getValue();
+
+ assertNotNull(callback);
+
+ // NR is included and carrier config for TEST SIM is applied.
+ PersistableBundle b = getPersistableBundle(new int[] { EUTRAN, NGRAN }, true);
+ doReturn(b).when(mCarrierConfigManager).getConfigForSubId(anyInt(), anyString());
+ callback.onCarrierConfigChanged(SLOT_0, SUB_1, TEST_SIM_CARRIER_ID, 0);
+
+ // NR is ignored.
+ assertFalse(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_0));
+ assertFalse(mCarrierConfigHelper.isVoNrEmergencySupported(SLOT_1));
+ }
+
+ private static PersistableBundle getPersistableBundle(int[] imsRats, boolean applied) {
+ PersistableBundle bundle = new PersistableBundle();
+ bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY, imsRats);
+ bundle.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, applied);
+ return bundle;
+ }
+
+ private static void logd(String str) {
+ Log.d(TAG, str);
+ }
+}
diff --git a/tests/src/com/android/services/telephony/domainselection/CrossSimRedialingControllerTest.java b/tests/src/com/android/services/telephony/domainselection/CrossSimRedialingControllerTest.java
index 6d85562..2ed91b8 100644
--- a/tests/src/com/android/services/telephony/domainselection/CrossSimRedialingControllerTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/CrossSimRedialingControllerTest.java
@@ -73,8 +73,6 @@
private static final String TELECOM_CALL_ID1 = "TC1";
private static final String TEST_EMERGENCY_NUMBER = "911";
- @Mock private CarrierConfigManager mCarrierConfigManager;
- @Mock private TelephonyManager mTelephonyManager;
@Mock private EmergencyCallDomainSelector mEcds;
@Mock private CrossSimRedialingController.EmergencyNumberHelper mEmergencyNumberHelper;
@@ -83,6 +81,8 @@
private HandlerThread mHandlerThread;
private TestableLooper mLooper;
private CrossSimRedialingController mCsrController;
+ private CarrierConfigManager mCarrierConfigManager;
+ private TelephonyManager mTelephonyManager;
@Before
public void setUp() throws Exception {
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index a372dd1..eab40f9 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -76,6 +76,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkRequest;
import android.os.Handler;
@@ -95,6 +96,7 @@
import android.telephony.EmergencyRegResult;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PreciseDisconnectCause;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TransportSelectorCallback;
import android.telephony.WwanSelectorCallback;
@@ -139,6 +141,8 @@
@Mock private DomainSelectorBase.DestroyListener mDestroyListener;
@Mock private ProvisioningManager mProvisioningManager;
@Mock private CrossSimRedialingController mCsrdCtrl;
+ @Mock private CarrierConfigHelper mCarrierConfigHelper;
+ @Mock private Resources mResources;
private Context mContext;
@@ -188,6 +192,11 @@
public String getOpPackageName() {
return "";
}
+
+ @Override
+ public Resources getResources() {
+ return mResources;
+ }
};
if (Looper.myLooper() == null) {
@@ -208,6 +217,7 @@
.thenReturn(mTelephonyManager);
when(mTelephonyManager.getNetworkCountryIso()).thenReturn("");
when(mTelephonyManager.getSimState(anyInt())).thenReturn(TelephonyManager.SIM_STATE_READY);
+ when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
when(mCarrierConfigManager.getConfigForSubId(anyInt()))
@@ -254,6 +264,8 @@
}
}).when(mWwanSelectorCallback).onRequestEmergencyNetworkScan(
any(), anyInt(), any(), any());
+
+ when(mResources.getStringArray(anyInt())).thenReturn(null);
}
@After
@@ -359,6 +371,7 @@
doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
.when(mTelephonyManager).getSimState(anyInt());
doReturn(true).when(mCsrdCtrl).isThereOtherSlot();
+ doReturn(new String[] {"jp"}).when(mResources).getStringArray(anyInt());
EmergencyRegResult regResult = getEmergencyRegResult(
UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "", "jp");
@@ -1306,6 +1319,7 @@
doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
.when(mTelephonyManager).getSimState(anyInt());
doReturn(true).when(mCsrdCtrl).isThereOtherSlot();
+ doReturn(new String[] {"jp"}).when(mResources).getStringArray(anyInt());
EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
0, false, false, 0, 0, "", "", "jp");
@@ -1328,6 +1342,7 @@
doReturn(TelephonyManager.SIM_STATE_PIN_REQUIRED)
.when(mTelephonyManager).getSimState(anyInt());
doReturn(false).when(mCsrdCtrl).isThereOtherSlot();
+ doReturn(new String[] {"jp"}).when(mResources).getStringArray(anyInt());
EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
0, false, false, 0, 0, "", "", "jp");
@@ -1668,6 +1683,7 @@
public void testStartCrossStackTimer() throws Exception {
createSelector(SLOT_0_SUB_ID);
unsolBarringInfoChanged(false);
+ doReturn(2).when(mTelephonyManager).getActiveModemCount();
EmergencyRegResult regResult = getEmergencyRegResult(
UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
@@ -1987,6 +2003,111 @@
verify(mTransportSelectorCallback, times(2)).onWlanSelected(anyBoolean());
}
+ @Test
+ public void testSimLockScanPsPreferredWithNr() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ // The last valid subscription supported NR.
+ doReturn(true).when(mCarrierConfigHelper).isVoNrEmergencySupported(eq(SLOT_0));
+ when(mTelephonyManager.getSimState(anyInt())).thenReturn(
+ TelephonyManager.SIM_STATE_PIN_REQUIRED);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(
+ UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+ any(), anyInt(), any(), any());
+ assertEquals(4, mAccessNetwork.size());
+ assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
+ assertEquals(NGRAN, (int) mAccessNetwork.get(1));
+ assertEquals(UTRAN, (int) mAccessNetwork.get(2));
+ assertEquals(GERAN, (int) mAccessNetwork.get(3));
+ }
+
+ @Test
+ public void testSimLockScanPsPreferredWithNrAtTheEnd() throws Exception {
+ createSelector(SLOT_0_SUB_ID);
+ unsolBarringInfoChanged(false);
+
+ when(mTelephonyManager.getSimState(anyInt())).thenReturn(
+ TelephonyManager.SIM_STATE_PIN_REQUIRED);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(
+ UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+ any(), anyInt(), any(), any());
+ assertEquals(4, mAccessNetwork.size());
+ assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
+ assertEquals(UTRAN, (int) mAccessNetwork.get(1));
+ assertEquals(GERAN, (int) mAccessNetwork.get(2));
+ assertEquals(NGRAN, (int) mAccessNetwork.get(3));
+ }
+
+ @Test
+ public void testInvalidSubscriptionScanPsPreferredWithNrAtTheEnd() throws Exception {
+ createSelector(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ unsolBarringInfoChanged(false);
+
+ EmergencyRegResult regResult = getEmergencyRegResult(
+ UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+ any(), anyInt(), any(), any());
+ assertEquals(4, mAccessNetwork.size());
+ assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
+ assertEquals(UTRAN, (int) mAccessNetwork.get(1));
+ assertEquals(GERAN, (int) mAccessNetwork.get(2));
+ assertEquals(NGRAN, (int) mAccessNetwork.get(3));
+ }
+
+ @Test
+ public void testInvalidSubscriptionScanPsPreferredWithNr() throws Exception {
+ createSelector(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ unsolBarringInfoChanged(false);
+
+ // The last valid subscription supported NR.
+ doReturn(true).when(mCarrierConfigHelper).isVoNrEmergencySupported(eq(SLOT_0));
+
+ EmergencyRegResult regResult = getEmergencyRegResult(
+ UNKNOWN, REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+ SelectionAttributes attr = getSelectionAttributes(SLOT_0,
+ SubscriptionManager.INVALID_SUBSCRIPTION_ID, regResult);
+ mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+ processAllMessages();
+
+ bindImsServiceUnregistered();
+ processAllMessages();
+
+ verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+ any(), anyInt(), any(), any());
+ assertEquals(4, mAccessNetwork.size());
+ assertEquals(EUTRAN, (int) mAccessNetwork.get(0));
+ assertEquals(NGRAN, (int) mAccessNetwork.get(1));
+ assertEquals(UTRAN, (int) mAccessNetwork.get(2));
+ assertEquals(GERAN, (int) mAccessNetwork.get(3));
+ }
+
private void setupForScanListTest(PersistableBundle bundle) throws Exception {
setupForScanListTest(bundle, false);
}
@@ -2060,8 +2181,8 @@
private void createSelector(int subId) throws Exception {
mDomainSelector = new EmergencyCallDomainSelector(
mContext, SLOT_0, subId, mHandlerThread.getLooper(),
- mImsStateTracker, mDestroyListener, mCsrdCtrl);
-
+ mImsStateTracker, mDestroyListener, mCsrdCtrl, mCarrierConfigHelper);
+ mDomainSelector.clearResourceConfiguration();
replaceInstance(DomainSelectorBase.class,
"mWwanSelectorCallback", mDomainSelector, mWwanSelectorCallback);
}
diff --git a/tests/src/com/android/services/telephony/domainselection/OWNERS b/tests/src/com/android/services/telephony/domainselection/OWNERS
new file mode 100644
index 0000000..b9112be
--- /dev/null
+++ b/tests/src/com/android/services/telephony/domainselection/OWNERS
@@ -0,0 +1,8 @@
+# automatically inherit owners from fw/opt/telephony
+
+hwangoo@google.com
+forestchoi@google.com
+avinashmp@google.com
+mkoon@google.com
+seheele@google.com
+radhikaagrawal@google.com
diff --git a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
index f340e94..647ef41 100644
--- a/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/TelephonyDomainSelectionServiceTest.java
@@ -78,7 +78,8 @@
@SelectorType int selectorType, boolean isEmergency,
@NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker,
@NonNull DomainSelectorBase.DestroyListener listener,
- @NonNull CrossSimRedialingController crossSimRedialingController) {
+ @NonNull CrossSimRedialingController crossSimRedialingController,
+ @NonNull CarrierConfigHelper carrierConfigHelper) {
switch (selectorType) {
case DomainSelectionService.SELECTOR_TYPE_CALLING: // fallthrough
case DomainSelectionService.SELECTOR_TYPE_SMS: // fallthrough
@@ -107,6 +108,7 @@
@Mock private TransportSelectorCallback mSelectorCallback1;
@Mock private TransportSelectorCallback mSelectorCallback2;
@Mock private ImsStateTracker mImsStateTracker;
+ @Mock private CarrierConfigHelper mCarrierConfigHelper;
private final ServiceState mServiceState = new ServiceState();
private final BarringInfo mBarringInfo = new BarringInfo();
@@ -128,7 +130,7 @@
mContext = new TestContext();
mDomainSelectionService = new TelephonyDomainSelectionService(mContext,
- mImsStateTrackerFactory, mDomainSelectorFactory);
+ mImsStateTrackerFactory, mDomainSelectorFactory, mCarrierConfigHelper);
mServiceHandler = new Handler(mDomainSelectionService.getLooper());
mTestableLooper = new TestableLooper(mDomainSelectionService.getLooper());