Merge "Reset a network mode of each SIM from system property" into pi-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d9219e7..d4e4926 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -144,6 +144,7 @@
<uses-permission android:name="com.android.smspush.WAPPUSH_MANAGER_BIND" />
<uses-permission android:name="android.permission.MANAGE_USERS" />
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+ <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS" />
<uses-permission android:name="android.permission.READ_SEARCH_INDEXABLES" />
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index cce7ebc..dd47d6a 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -176,6 +176,16 @@
<string name="preferred_network_mode_summary" msgid="1434820673166126609">"Change the network operating mode"</string>
<string name="preferred_network_mode_dialogtitle" msgid="4048082093347807230">"Preferred network type"</string>
<string name="forbidden_network" msgid="4384929668343563440">"(forbidden)"</string>
+ <!-- no translation found for choose_network_title (4023911977543009350) -->
+ <skip />
+ <!-- no translation found for network_disconnected (2227251609006103194) -->
+ <skip />
+ <!-- no translation found for network_connected (1288589103624338857) -->
+ <skip />
+ <!-- no translation found for network_connecting (4927203097283533783) -->
+ <skip />
+ <!-- no translation found for network_could_not_connect (8254009365807767243) -->
+ <skip />
<string-array name="preferred_network_mode_choices">
<item msgid="3628460389382468528">"GSM/WCDMA preferred"</item>
<item msgid="8442633436636425221">"GSM only"</item>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 097e36b..5b45b64 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -176,6 +176,11 @@
<string name="preferred_network_mode_summary" msgid="1434820673166126609">"Change the network operating mode"</string>
<string name="preferred_network_mode_dialogtitle" msgid="4048082093347807230">"Preferred network type"</string>
<string name="forbidden_network" msgid="4384929668343563440">"(forbidden)"</string>
+ <string name="choose_network_title" msgid="4023911977543009350">"Choose network"</string>
+ <string name="network_disconnected" msgid="2227251609006103194">"Disconnected"</string>
+ <string name="network_connected" msgid="1288589103624338857">"Connected"</string>
+ <string name="network_connecting" msgid="4927203097283533783">"Connecting..."</string>
+ <string name="network_could_not_connect" msgid="8254009365807767243">"Couldn’t connect"</string>
<string-array name="preferred_network_mode_choices">
<item msgid="3628460389382468528">"GSM/WCDMA preferred"</item>
<item msgid="8442633436636425221">"GSM only"</item>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 1a1c4f7..1bef191 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -176,6 +176,11 @@
<string name="preferred_network_mode_summary" msgid="1434820673166126609">"Changer le mode de fonctionnement du réseau"</string>
<string name="preferred_network_mode_dialogtitle" msgid="4048082093347807230">"Type de réseau préféré"</string>
<string name="forbidden_network" msgid="4384929668343563440">"(interdit)"</string>
+ <string name="choose_network_title" msgid="4023911977543009350">"Sélectionner un réseau"</string>
+ <string name="network_disconnected" msgid="2227251609006103194">"Déconnecté"</string>
+ <string name="network_connected" msgid="1288589103624338857">"Connecté"</string>
+ <string name="network_connecting" msgid="4927203097283533783">"Connexion…"</string>
+ <string name="network_could_not_connect" msgid="8254009365807767243">"Connexion impossible"</string>
<string-array name="preferred_network_mode_choices">
<item msgid="3628460389382468528">"GSM/WCDMA de préférence"</item>
<item msgid="8442633436636425221">"GSM uniquement"</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 08819ef..4d0e90e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -369,7 +369,7 @@
<!-- Available networks screen, text when no networks are found -->
<string name="empty_networks_list">No networks found.</string>
<!-- Available networks screen, toast when an error is encountered when searching for networks -->
- <string name="network_query_error">Error while searching for networks.</string>
+ <string name="network_query_error">Couldn\'t find networks. Try again.</string>
<!-- Available networks screen, toast when registering on a specific network -->
<string name="register_on_network">Registering on <xliff:g id="network">%s</xliff:g>\u2026</string>
<!-- Available networks screen, toast when SIM card isn't allowed on a network -->
@@ -536,7 +536,9 @@
<!-- Mobile network settings UI: notification message shown when you
lose data connectivity because you're roaming and you have the
"data roaming" feature turned off. -->
- <string name="roaming_reenable_message">You\'ve lost data connectivity because you left your home network with data roaming turned off.</string>
+ <string name="roaming_reenable_message">Data roaming is turned off. Tap to turn on.</string>
+ <!-- Roaming notification tile, notifying lost of roaming data connection -->
+ <string name="roaming_notification_title">Lost mobile data connection</string>
<!-- Mobile network settings screen, dialog message when user selects the Data roaming check box -->
<string name="roaming_warning">You may incur significant charges.</string>
<!-- Mobile network settings screen, message asking the user to check their pricing with their Carrier, when enabling Data roaming. -->
diff --git a/res/xml/cdma_options.xml b/res/xml/cdma_options.xml
index 8a41f87..6ac5dae 100644
--- a/res/xml/cdma_options.xml
+++ b/res/xml/cdma_options.xml
@@ -38,7 +38,7 @@
<PreferenceCategory
android:key="category_cdma_apn_key">
<!-- The launching Intent will be defined thru code as we need to pass some Extra -->
- <Preference
+ <com.android.phone.RestrictedPreference
android:key="button_cdma_apn_key"
android:title="@string/apn_settings"
android:persistent="false"/>
diff --git a/res/xml/gsm_umts_options.xml b/res/xml/gsm_umts_options.xml
index e6ddc37..e3e2617 100644
--- a/res/xml/gsm_umts_options.xml
+++ b/res/xml/gsm_umts_options.xml
@@ -37,7 +37,7 @@
<!--we want user to change it with caution.-->
<PreferenceCategory
android:key="category_gsm_apn_key">
- <Preference
+ <com.android.phone.RestrictedPreference
android:key="button_gsm_apn_key"
android:title="@string/apn_settings"
android:persistent="false" />
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 2e86dca..8b37a52 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -183,7 +183,7 @@
mConfigFromDefaultApp[phoneId] = null;
mConfigFromCarrierApp[phoneId] = null;
mServiceConnection[phoneId] = null;
- broadcastConfigChangedIntent(phoneId);
+ broadcastConfigChangedIntent(phoneId, false);
break;
}
@@ -521,10 +521,20 @@
}
private void broadcastConfigChangedIntent(int phoneId) {
+ broadcastConfigChangedIntent(phoneId, true);
+ }
+
+ private void broadcastConfigChangedIntent(int phoneId, boolean addSubIdExtra) {
Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT |
Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId);
+ // Include subId extra only if SIM records are loaded
+ TelephonyManager telephonyManager = TelephonyManager.from(mContext);
+ int simApplicationState = telephonyManager.getSimApplicationState();
+ if (addSubIdExtra && (simApplicationState != TelephonyManager.SIM_STATE_UNKNOWN
+ && simApplicationState != TelephonyManager.SIM_STATE_NOT_READY)) {
+ SubscriptionManager.putPhoneIdAndSubIdExtra(intent, phoneId);
+ }
intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, phoneId);
ActivityManager.broadcastStickyIntent(intent, UserHandle.USER_ALL);
mHasSentConfigChange[phoneId] = true;
diff --git a/src/com/android/phone/CdmaOptions.java b/src/com/android/phone/CdmaOptions.java
index 7c09265..ff37c70 100644
--- a/src/com/android/phone/CdmaOptions.java
+++ b/src/com/android/phone/CdmaOptions.java
@@ -29,6 +29,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.Phone;
+import com.android.settingslib.RestrictedLockUtils;
/**
* List of Phone-specific settings screens.
@@ -38,7 +39,7 @@
private CdmaSystemSelectListPreference mButtonCdmaSystemSelect;
private CdmaSubscriptionListPreference mButtonCdmaSubscription;
- private Preference mButtonAPNExpand;
+ private RestrictedPreference mButtonAPNExpand;
private Preference mCategoryAPNExpand;
private Preference mButtonCarrierSettings;
@@ -63,7 +64,7 @@
mButtonCdmaSubscription = (CdmaSubscriptionListPreference) mPrefScreen
.findPreference(BUTTON_CDMA_SUBSCRIPTION_KEY);
mButtonCarrierSettings = mPrefScreen.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
- mButtonAPNExpand = mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
+ mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
update(phone);
@@ -93,6 +94,10 @@
// Calling add or remove explicitly to make sure they are updated.
if (addAPNExpand) {
+ mButtonAPNExpand.setDisabledByAdmin(
+ MobileNetworkSettings.isDpcApnEnforced(mButtonAPNExpand.getContext())
+ ? RestrictedLockUtils.getDeviceOwner(mButtonAPNExpand.getContext())
+ : null);
mButtonAPNExpand.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
diff --git a/src/com/android/phone/GsmUmtsOptions.java b/src/com/android/phone/GsmUmtsOptions.java
index 5cf19ad..220cf34 100644
--- a/src/com/android/phone/GsmUmtsOptions.java
+++ b/src/com/android/phone/GsmUmtsOptions.java
@@ -28,6 +28,7 @@
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
+import com.android.settingslib.RestrictedLockUtils;
/**
* List of Network-specific settings screens.
@@ -35,7 +36,7 @@
public class GsmUmtsOptions {
private static final String LOG_TAG = "GsmUmtsOptions";
- private Preference mButtonAPNExpand;
+ private RestrictedPreference mButtonAPNExpand;
private Preference mCategoryAPNExpand;
Preference mCarrierSettingPref;
@@ -54,7 +55,7 @@
mPrefFragment = prefFragment;
mPrefScreen = prefScreen;
mPrefFragment.addPreferencesFromResource(R.xml.gsm_umts_options);
- mButtonAPNExpand = mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
+ mButtonAPNExpand = (RestrictedPreference) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
mCategoryAPNExpand = mPrefScreen.findPreference(CATEGORY_APN_EXPAND_KEY);
mNetworkOperator = (NetworkOperators) mPrefScreen
.findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
@@ -113,6 +114,10 @@
// Calling add or remove explicitly to make sure they are updated.
if (addAPNExpand) {
+ mButtonAPNExpand.setDisabledByAdmin(
+ MobileNetworkSettings.isDpcApnEnforced(mButtonAPNExpand.getContext())
+ ? RestrictedLockUtils.getDeviceOwner(mButtonAPNExpand.getContext())
+ : null);
mButtonAPNExpand.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
diff --git a/src/com/android/phone/IccNetworkDepersonalizationPanel.java b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
index 9dff461..8bd10a2 100644
--- a/src/com/android/phone/IccNetworkDepersonalizationPanel.java
+++ b/src/com/android/phone/IccNetworkDepersonalizationPanel.java
@@ -74,7 +74,7 @@
/**
* Shows the network depersonalization dialog, but only if it is not already visible.
*/
- public static void showDialog() {
+ public static void showDialog(Phone phone) {
if (sShowingDialog) {
Log.i(TAG, "[IccNetworkDepersonalizationPanel] - showDialog; skipped already shown.");
return;
@@ -82,7 +82,7 @@
Log.i(TAG, "[IccNetworkDepersonalizationPanel] - showDialog; showing dialog.");
sShowingDialog = true;
IccNetworkDepersonalizationPanel ndpPanel =
- new IccNetworkDepersonalizationPanel(PhoneGlobals.getInstance());
+ new IccNetworkDepersonalizationPanel(PhoneGlobals.getInstance(), phone);
ndpPanel.show();
}
@@ -133,6 +133,13 @@
//constructor
public IccNetworkDepersonalizationPanel(Context context) {
super(context);
+ mPhone = PhoneGlobals.getPhone();
+ }
+
+ //constructor
+ public IccNetworkDepersonalizationPanel(Context context, Phone phone) {
+ super(context);
+ mPhone = phone == null ? PhoneGlobals.getPhone() : phone;
}
@Override
@@ -172,8 +179,6 @@
//status panel is used since we're having problems with the alert dialog.
mStatusPanel = (LinearLayout) findViewById(R.id.status_panel);
mStatusText = (TextView) findViewById(R.id.status_text);
-
- mPhone = PhoneGlobals.getPhone();
}
@Override
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 5a2dba4..3a32e50 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -16,6 +16,8 @@
package com.android.phone;
+import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI;
+
import android.app.ActionBar;
import android.app.Activity;
import android.app.DialogFragment;
@@ -30,6 +32,8 @@
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.database.ContentObserver;
+import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Bundle;
@@ -181,6 +185,20 @@
return true;
}
+ /**
+ * Returns if DPC APNs are enforced.
+ */
+ public static boolean isDpcApnEnforced(Context context) {
+ try (Cursor enforceCursor = context.getContentResolver().query(ENFORCE_MANAGED_URI,
+ null, null, null, null)) {
+ if (enforceCursor == null || enforceCursor.getCount() != 1) {
+ return false;
+ }
+ enforceCursor.moveToFirst();
+ return enforceCursor.getInt(0) > 0;
+ }
+ }
+
public static class MobileNetworkFragment extends PreferenceFragment implements
Preference.OnPreferenceChangeListener, RoamingDialogFragment.RoamingDialogListener {
@@ -222,6 +240,7 @@
private static final String BUTTON_CDMA_APN_EXPAND_KEY = "button_cdma_apn_key";
private final BroadcastReceiver mPhoneChangeReceiver = new PhoneChangeReceiver();
+ private final ContentObserver mDpcEnforcedContentObserver = new DpcApnEnforcedObserver();
static final int preferredNetworkMode = Phone.PREFERRED_NT_MODE;
@@ -732,6 +751,9 @@
TelephonyIntents.ACTION_RADIO_TECHNOLOGY_CHANGED);
activity.registerReceiver(mPhoneChangeReceiver, intentFilter);
+ activity.getContentResolver().registerContentObserver(ENFORCE_MANAGED_URI, false,
+ mDpcEnforcedContentObserver);
+
Log.i(LOG_TAG, "onCreate:-");
}
@@ -764,12 +786,26 @@
}
}
+ private class DpcApnEnforcedObserver extends ContentObserver {
+ DpcApnEnforcedObserver() {
+ super(null);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ Log.i(LOG_TAG, "DPC enforced onChange:");
+ updateBody();
+ }
+ }
+
@Override
public void onDestroy() {
unbindNetworkQueryService();
super.onDestroy();
if (getActivity() != null) {
getActivity().unregisterReceiver(mPhoneChangeReceiver);
+ getActivity().getContentResolver().unregisterContentObserver(
+ mDpcEnforcedContentObserver);
}
}
diff --git a/src/com/android/phone/NetworkQueryService.java b/src/com/android/phone/NetworkQueryService.java
index 86f4b11..22b5509 100644
--- a/src/com/android/phone/NetworkQueryService.java
+++ b/src/com/android/phone/NetworkQueryService.java
@@ -79,7 +79,7 @@
private static final boolean INCREMENTAL_RESULTS = true;
// The parameters below are in seconds
private static final int SEARCH_PERIODICITY_SEC = 5;
- private static final int MAX_SEARCH_TIME_SEC = 60;
+ private static final int MAX_SEARCH_TIME_SEC = 300;
private static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;
/**
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index 219552a..9f4767a 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -542,7 +542,7 @@
final Notification.Builder builder = new Notification.Builder(mContext)
.setSmallIcon(android.R.drawable.stat_sys_warning)
- .setContentTitle(mContext.getText(R.string.roaming))
+ .setContentTitle(mContext.getText(R.string.roaming_notification_title))
.setColor(mContext.getResources().getColor(R.color.dialer_theme_color))
.setContentText(contentText)
.setChannel(NotificationChannelController.CHANNEL_ID_MOBILE_DATA_STATUS)
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 062286c..d4da7fe 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -199,7 +199,8 @@
// The user won't be able to do anything else until
// they enter a valid SIM network PIN.
Log.i(LOG_TAG, "show sim depersonal panel");
- IccNetworkDepersonalizationPanel.showDialog();
+ Phone phone = (Phone) ((AsyncResult) msg.obj).userObj;
+ IccNetworkDepersonalizationPanel.showDialog(phone);
}
break;
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 27700f3..16996c0 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -1264,7 +1264,7 @@
@Override
public boolean isOffhookForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "isOffhookForSubscriber")) {
+ mApp, subId, callingPackage, "isOffhookForSubscriber")) {
return false;
}
@@ -1284,7 +1284,7 @@
@Override
public boolean isRingingForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "isRingingForSubscriber")) {
+ mApp, subId, callingPackage, "isRingingForSubscriber")) {
return false;
}
@@ -1304,7 +1304,7 @@
@Override
public boolean isIdleForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "isIdleForSubscriber")) {
+ mApp, subId, callingPackage, "isIdleForSubscriber")) {
return false;
}
@@ -1480,7 +1480,7 @@
@Override
public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "isRadioOnForSubscriber")) {
+ mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
return false;
}
return isRadioOnForSubscriber(subId);
@@ -1793,32 +1793,44 @@
@Override
public String getImeiForSlot(int slotIndex, String callingPackage) {
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getImeiForSlot")) {
+ Phone phone = PhoneFactory.getPhone(slotIndex);
+ if (phone == null) {
return null;
}
- Phone phone = PhoneFactory.getPhone(slotIndex);
- return phone == null ? null : phone.getImei();
+ int subId = phone.getSubId();
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+ mApp, subId, callingPackage, "getImeiForSlot")) {
+ return null;
+ }
+ return phone.getImei();
}
@Override
public String getMeidForSlot(int slotIndex, String callingPackage) {
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getMeidForSlot")) {
+ Phone phone = PhoneFactory.getPhone(slotIndex);
+ if (phone == null) {
return null;
}
- Phone phone = PhoneFactory.getPhone(slotIndex);
- return phone == null ? null : phone.getMeid();
+ int subId = phone.getSubId();
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+ mApp, subId, callingPackage, "getMeidForSlot")) {
+ return null;
+ }
+ return phone.getMeid();
}
@Override
public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getDeviceSoftwareVersionForSlot")) {
+ Phone phone = PhoneFactory.getPhone(slotIndex);
+ if (phone == null) {
return null;
}
- Phone phone = PhoneFactory.getPhone(slotIndex);
- return phone == null ? null : phone.getDeviceSvn();
+ int subId = phone.getSubId();
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+ mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
+ return null;
+ }
+ return phone.getDeviceSvn();
}
@Override
@@ -1907,7 +1919,7 @@
@Override
public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
+ mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
return -1;
}
final Phone phone = getPhone(subId);
@@ -1931,7 +1943,7 @@
@Override
public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getCdmaEriIconModeForSubscriber")) {
+ mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
return -1;
}
final Phone phone = getPhone(subId);
@@ -1953,7 +1965,7 @@
@Override
public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getCdmaEriIconTextForSubscriber")) {
+ mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
return null;
}
final Phone phone = getPhone(subId);
@@ -2030,7 +2042,7 @@
public String getVisualVoicemailPackageName(String callingPackage, int subId) {
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getVisualVoicemailPackageName")) {
+ mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
return null;
}
return RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId).getPackageName();
@@ -2215,7 +2227,7 @@
@Override
public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getNetworkTypeForSubscriber")) {
+ mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
@@ -2241,7 +2253,7 @@
@Override
public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getDataNetworkTypeForSubscriber")) {
+ mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
@@ -2259,7 +2271,7 @@
@Override
public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getDataNetworkTypeForSubscriber")) {
+ mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
return TelephonyManager.NETWORK_TYPE_UNKNOWN;
}
@@ -2310,7 +2322,7 @@
@Override
public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getLteOnCdmaModeForSubscriber")) {
+ mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
}
@@ -2509,6 +2521,7 @@
* on a particular subscription
*/
public String[] getForbiddenPlmns(int subId, int appType) {
+ // TODO(b/73884967): Migrate to TelephonyPermissions check.
mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
"Requires READ_PHONE_STATE");
if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
@@ -2622,7 +2635,7 @@
public String[] getPcscfAddress(String apnType, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getPcscfAddress")) {
+ mApp, mPhone.getSubId(), callingPackage, "getPcscfAddress")) {
return new String[0];
}
@@ -2696,6 +2709,15 @@
return PhoneFactory.getImsResolver().isEmergencyMmTelAvailable(slotId);
}
+ /**
+ * @return true if the IMS resolver is busy resolving a binding and should not be considered
+ * available, false if the IMS resolver is idle.
+ */
+ public boolean isResolvingImsBinding() {
+ enforceModifyPermission();
+ return PhoneFactory.getImsResolver().isResolvingBinding();
+ }
+
public void setImsRegistrationState(boolean registered) {
enforceModifyPermission();
mPhone.setImsRegistrationState(registered);
@@ -2784,7 +2806,7 @@
@Override
public int getCalculatedPreferredNetworkType(String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getCalculatedPreferredNetworkType")) {
+ mApp, mPhone.getSubId(), callingPackage, "getCalculatedPreferredNetworkType")) {
return RILConstants.PREFERRED_NETWORK_MODE;
}
@@ -3129,7 +3151,7 @@
public String getLine1NumberForDisplay(int subId, String callingPackage) {
// This is open to apps with WRITE_SMS.
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
- mApp, callingPackage, "getLine1NumberForDisplay")) {
+ mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
return null;
}
@@ -3150,7 +3172,7 @@
@Override
public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getLine1AlphaTagForDisplay")) {
+ mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
return null;
}
@@ -3164,8 +3186,11 @@
@Override
public String[] getMergedSubscriberIds(String callingPackage) {
+ // This API isn't public, so no need to provide a valid subscription ID - we're not worried
+ // about carrier-privileged callers not having access.
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getMergedSubscriberIds")) {
+ mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
+ "getMergedSubscriberIds")) {
return null;
}
final Context context = mPhone.getContext();
@@ -3268,8 +3293,13 @@
@Override
public int getRadioAccessFamily(int phoneId, String callingPackage) {
+ Phone phone = PhoneFactory.getPhone(phoneId);
+ if (phone == null) {
+ return RadioAccessFamily.RAF_UNKNOWN;
+ }
+ int subId = phone.getSubId();
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getRadioAccessFamily")) {
+ mApp, subId, callingPackage, "getRadioAccessFamily")) {
return RadioAccessFamily.RAF_UNKNOWN;
}
@@ -3285,7 +3315,7 @@
@Override
public boolean isVideoCallingEnabled(String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "isVideoCallingEnabled")) {
+ mApp, mPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
return false;
}
@@ -3339,17 +3369,16 @@
*/
@Override
public String getDeviceId(String callingPackage) {
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getDeviceId")) {
- return null;
- }
-
final Phone phone = PhoneFactory.getPhone(0);
- if (phone != null) {
- return phone.getDeviceId();
- } else {
+ if (phone == null) {
return null;
}
+ int subId = phone.getSubId();
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+ mApp, subId, callingPackage, "getDeviceId")) {
+ return null;
+ }
+ return phone.getDeviceId();
}
/**
@@ -3590,7 +3619,7 @@
public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getServiceStateForSubscriber")) {
+ mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
return null;
}
@@ -3976,7 +4005,7 @@
@Override
public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mApp, callingPackage, "getClientRequestStats")) {
+ mApp, subId, callingPackage, "getClientRequestStats")) {
return null;
}
@@ -4093,7 +4122,12 @@
}
infos[i] = new UiccSlotInfo(
- slot.isActive(), slot.isEuicc(), cardId, cardState, slot.getPhoneId());
+ slot.isActive(),
+ slot.isEuicc(),
+ cardId,
+ cardState,
+ slot.getPhoneId(),
+ slot.isExtendedApduSupported());
}
return infos;
}
diff --git a/src/com/android/phone/PhoneSearchIndexablesProvider.java b/src/com/android/phone/PhoneSearchIndexablesProvider.java
index b7f6738..ee79f92 100644
--- a/src/com/android/phone/PhoneSearchIndexablesProvider.java
+++ b/src/com/android/phone/PhoneSearchIndexablesProvider.java
@@ -103,8 +103,7 @@
if (!mUserManager.isAdminUser()) {
final String[] values = new String[]{"preferred_network_mode_key",
- "button_roaming_key",
- "cdma_lte_data_service_key", "enabled_networks_key", "enhanced_4g_lte",
+ "button_roaming_key", "cdma_lte_data_service_key", "enhanced_4g_lte",
"button_apn_key", "button_carrier_sel_key", "carrier_settings_key",
"cdma_system_select_key", "esim_list_profile", "mobile_data_enable",
"data_usage_summary", "wifi_calling_key", "video_calling_key"};
@@ -119,6 +118,12 @@
cursor.addRow(createNonIndexableRow("enhanced_4g_lte" /* key */));
}
}
+
+ // enabled_networks button and preferred_network_mode button share the same title
+ // "Preferred network type"and are mutual exclusive. Thus we remove one from search
+ // result to avoid duplicate search result.
+ // TODO: b/63381516 all hidden buttons should dynamically be removed from search result.
+ cursor.addRow(createNonIndexableRow("enabled_networks_key" /* key */));
cursor.addRow(createNonIndexableRow("carrier_settings_euicc_key" /* key */));
cursor.addRow(createNonIndexableRow("advanced_options" /* key */));
return cursor;
diff --git a/src/com/android/phone/RestrictedPreference.java b/src/com/android/phone/RestrictedPreference.java
new file mode 100644
index 0000000..b8b6fe7
--- /dev/null
+++ b/src/com/android/phone/RestrictedPreference.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.settingslib.RestrictedLockUtils;
+
+/**
+ * Preference class that supports being disabled by a device admin.
+ *
+ * <p>This class is a mimic of ../../../frameworks/base/packages/SettingsLib/src/com/android
+ * /settingslib/RestrictedPreference.java,
+ * but support framework {@link Preference}.
+ */
+public class RestrictedPreference extends Preference {
+ private final Context mContext;
+
+ private boolean mDisabledByAdmin;
+ private EnforcedAdmin mEnforcedAdmin;
+
+ public RestrictedPreference(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ mContext = context;
+
+ setLayoutResource(com.android.settingslib.R.layout.preference_two_target);
+ setWidgetLayoutResource(R.layout.restricted_icon);
+ }
+
+ public RestrictedPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public RestrictedPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, android.R.attr.preferenceStyle);
+ }
+
+ public RestrictedPreference(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ public void performClick(PreferenceScreen preferenceScreen) {
+ if (mDisabledByAdmin) {
+ RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin);
+ } else {
+ super.performClick(preferenceScreen);
+ }
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+
+ final View divider = view.findViewById(com.android.settingslib.R.id.two_target_divider);
+ final View widgetFrame = view.findViewById(android.R.id.widget_frame);
+ final View restrictedIcon = view.findViewById(R.id.restricted_icon);
+ final TextView summaryView = view.findViewById(android.R.id.summary);
+ if (divider != null) {
+ divider.setVisibility(mDisabledByAdmin ? View.VISIBLE : View.GONE);
+ }
+ if (widgetFrame != null) {
+ widgetFrame.setVisibility(mDisabledByAdmin ? View.VISIBLE : View.GONE);
+ }
+ if (restrictedIcon != null) {
+ restrictedIcon.setVisibility(mDisabledByAdmin ? View.VISIBLE : View.GONE);
+ }
+ if (summaryView != null && mDisabledByAdmin) {
+ summaryView.setText(com.android.settingslib.R.string.disabled_by_admin_summary_text);
+ summaryView.setVisibility(View.VISIBLE);
+ }
+
+ if (mDisabledByAdmin) {
+ view.setEnabled(true);
+ }
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ if (enabled && mDisabledByAdmin) {
+ setDisabledByAdmin(null);
+ return;
+ }
+ super.setEnabled(enabled);
+ }
+
+ /**
+ * Disable this preference based on the enforce admin.
+ *
+ * @param admin Details of the admin who enforced the restriction. If it is {@code null}, then
+ * this preference will be enabled. Otherwise, it will be disabled.
+ */
+ public void setDisabledByAdmin(EnforcedAdmin admin) {
+ final boolean disabled = admin != null;
+ mEnforcedAdmin = admin;
+ boolean changed = false;
+ if (mDisabledByAdmin != disabled) {
+ mDisabledByAdmin = disabled;
+ changed = true;
+ }
+ setEnabled(!disabled);
+ if (changed) {
+ notifyChanged();
+ }
+ }
+}
diff --git a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
index 19ef9f7..8297c18 100644
--- a/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
+++ b/src/com/android/phone/euicc/EuiccUiDispatcherActivity.java
@@ -89,15 +89,13 @@
String action = getIntent().getAction();
Intent intent = new Intent();
+ intent.putExtras(getIntent());
switch (action) {
case EuiccManager.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS:
intent.setAction(EuiccService.ACTION_MANAGE_EMBEDDED_SUBSCRIPTIONS);
break;
case EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION:
intent.setAction(EuiccService.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION);
- intent.putExtra(
- EuiccManager.EXTRA_FORCE_PROVISION,
- getIntent().getBooleanExtra(EuiccManager.EXTRA_FORCE_PROVISION, false));
break;
default:
Log.w(TAG, "Unsupported action: " + action);
diff --git a/src/com/android/phone/vvm/RemoteVvmTaskManager.java b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
index 3a18c7e..98cb959 100644
--- a/src/com/android/phone/vvm/RemoteVvmTaskManager.java
+++ b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
@@ -139,6 +139,8 @@
TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
List<String> packages = new ArrayList<>();
packages.add(telecomManager.getDefaultDialerPackage());
+ // TODO(b/73136824): Check permissions in the calling function and avoid relying on the
+ // binder caller's permissions to access the carrier config.
PersistableBundle carrierConfig = context
.getSystemService(CarrierConfigManager.class).getConfigForSubId(subId);
packages.add(
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index a7bd2f2..f7d1747 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -1706,6 +1706,7 @@
private boolean isRtt() {
return mOriginalConnection != null
&& mOriginalConnection.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS
+ && mOriginalConnection instanceof ImsPhoneConnection
&& ((ImsPhoneConnection) mOriginalConnection).isRttEnabledForCall();
}
diff --git a/testapps/ImsTestService/AndroidManifest.xml b/testapps/ImsTestService/AndroidManifest.xml
index 4d81ffd..f47210e 100644
--- a/testapps/ImsTestService/AndroidManifest.xml
+++ b/testapps/ImsTestService/AndroidManifest.xml
@@ -40,9 +40,8 @@
android:enabled="true"
android:persistent="true"
android:permission="android.permission.BIND_IMS_SERVICE">
- <meta-data android:name="android.telephony.ims.MMTEL_FEATURE" android:value="true"/>
- <!--meta-data android:name="android.telephony.ims.EMERGENCY_MMTEL_FEATURE"
- android:value="true" /-->
+ <!--meta-data android:name="android.telephony.ims.MMTEL_FEATURE" android:value="true"/-->
+ <!-- No features means we will get queried for dynamic config. -->
<intent-filter>
<action android:name="android.telephony.ims.ImsService" />
</intent-filter>
diff --git a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsConfigImpl.java b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsConfigImpl.java
index 4b8842a..3269a5a 100644
--- a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsConfigImpl.java
+++ b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsConfigImpl.java
@@ -55,6 +55,10 @@
return sTestImsConfigImpl;
}
+ private TestImsConfigImpl() {
+ super();
+ }
+
public void setConfigListener(ImsConfigListener listener) {
mListener = listener;
}
diff --git a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsService.java b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsService.java
index 434cdb5..71323d8 100644
--- a/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsService.java
+++ b/testapps/ImsTestService/src/com/android/phone/testapps/imstestapp/TestImsService.java
@@ -17,9 +17,11 @@
package com.android.phone.testapps.imstestapp;
import android.telephony.ims.ImsService;
+import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.feature.RcsFeature;
import android.telephony.ims.stub.ImsConfigImplBase;
+import android.telephony.ims.stub.ImsFeatureConfiguration;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.util.Log;
@@ -54,8 +56,16 @@
}
@Override
+ public ImsFeatureConfiguration querySupportedImsFeatures() {
+ return new ImsFeatureConfiguration.Builder()
+ .addFeature(0, ImsFeature.FEATURE_EMERGENCY_MMTEL)
+ .addFeature(0, ImsFeature.FEATURE_MMTEL)
+ .build();
+ }
+
+ @Override
public MmTelFeature createMmTelFeature(int slotId) {
- Log.i(LOG_TAG, "TestImsService: onCreateEmergencyMMTelImsFeature");
+ Log.i(LOG_TAG, "TestImsService: onCreateMmTelImsFeature");
return mTestMmTelFeature;
}
diff --git a/tests/src/com/android/phone/PhoneSearchIndexablesProviderTest.java b/tests/src/com/android/phone/PhoneSearchIndexablesProviderTest.java
index 2176d6b..6b7f825 100644
--- a/tests/src/com/android/phone/PhoneSearchIndexablesProviderTest.java
+++ b/tests/src/com/android/phone/PhoneSearchIndexablesProviderTest.java
@@ -124,16 +124,16 @@
when(mUserManager.isAdminUser()).thenReturn(true);
Cursor cursor2 = mProvider
.queryNonIndexableKeys(SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
- assertThat(cursor2.getCount()).isEqualTo(2);
+ assertThat(cursor2.getCount()).isEqualTo(3);
mProvider.setIsEuiccSettingsHidden(true /* isEuiccSettingsHidden */);
Cursor cursor3 = mProvider
.queryNonIndexableKeys(SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
- assertThat(cursor3.getCount()).isEqualTo(3);
+ assertThat(cursor3.getCount()).isEqualTo(4);
mProvider.setIsEnhanced4gLteHidden(true /* isEnhanced4gLteHidden */);
Cursor cursor4 = mProvider
.queryNonIndexableKeys(SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS);
- assertThat(cursor4.getCount()).isEqualTo(4);
+ assertThat(cursor4.getCount()).isEqualTo(5);
}
}
diff --git a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
index 901ad9e..5ecebc3 100644
--- a/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
+++ b/tests/src/com/android/phone/euicc/EuiccUiDispatcherActivityTest.java
@@ -15,6 +15,7 @@
*/
package com.android.phone.euicc;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.when;
@@ -94,6 +95,15 @@
assertNotNull(mActivity.resolveEuiccUiIntent());
}
+ @Test
+ public void testExtrasPropagated() {
+ mIntent.putExtra("foo", "bar");
+
+ Intent euiccUiIntent = mActivity.resolveEuiccUiIntent();
+ assertNotNull(euiccUiIntent);
+ assertEquals("bar", euiccUiIntent.getStringExtra("foo"));
+ }
+
class TestEuiccUiDispatcherActivity extends EuiccUiDispatcherActivity {
public TestEuiccUiDispatcherActivity() {
attachBaseContext(mMockContext);