Merge "Remove SHELL UID permission check from overrideConfig"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 545815e..e2d9c4a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -83,6 +83,7 @@
<protected-broadcast android:name= "com.android.internal.telephony.CARRIER_VVM_PACKAGE_INSTALLED" />
<protected-broadcast android:name= "com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO" />
<protected-broadcast android:name= "com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD" />
+ <protected-broadcast android:name= "com.android.internal.telephony.OPEN_DEFAULT_SMS_APP" />
<protected-broadcast android:name= "android.telephony.action.SIM_CARD_STATE_CHANGED" />
<protected-broadcast android:name= "android.telephony.action.SIM_APPLICATION_STATE_CHANGED" />
<protected-broadcast android:name= "android.telephony.action.SIM_SLOT_STATUS_CHANGED" />
diff --git a/ecc/input/eccdata.txt b/ecc/input/eccdata.txt
index 403cad7..bf5d92c 100644
--- a/ecc/input/eccdata.txt
+++ b/ecc/input/eccdata.txt
@@ -600,8 +600,11 @@
countries {
iso_code: "DE"
eccs {
- phone_number: "112"
+ phone_number: "110"
types: POLICE
+ }
+ eccs {
+ phone_number: "112"
types: AMBULANCE
types: FIRE
}
diff --git a/ecc/output/eccdata b/ecc/output/eccdata
index 679bc36..2b9007a 100644
--- a/ecc/output/eccdata
+++ b/ecc/output/eccdata
Binary files differ
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 0cb93aa..629276e 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -410,6 +410,10 @@
}
}
mButtonWifiCalling.setSummary(resId);
+ Intent intent = mButtonWifiCalling.getIntent();
+ if (intent != null) {
+ intent.putExtra(Settings.EXTRA_SUB_ID, mPhone.getSubId());
+ }
prefSet.addPreference(mButtonWifiCalling);
}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index de3fffc..942c1e2 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -569,9 +569,8 @@
if (DBG) log("showDataDisconnectedRoaming()...");
// "Mobile network settings" screen / dialog
- Intent intent = new Intent(mContext, com.android.phone.MobileNetworkSettings.class);
+ Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
intent.putExtra(Settings.EXTRA_SUB_ID, subId);
- intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(mContext, subId, intent, 0);
final CharSequence contentText = mContext.getText(R.string.roaming_reenable_message);
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index c00ccf4..bdf66df 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -172,6 +172,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Set;
/**
@@ -248,6 +249,8 @@
private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
private static final int CMD_REQUEST_ENABLE_MODEM = 68;
private static final int EVENT_ENABLE_MODEM_DONE = 69;
+ private static final int CMD_GET_MODEM_STATUS = 70;
+ private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
// Parameters of select command.
private static final int SELECT_COMMAND = 0xA4;
@@ -1117,10 +1120,42 @@
ar = (AsyncResult) msg.obj;
request = (MainThreadRequest) ar.userObj;
request.result = (ar.exception == null);
+ int phoneId = request.phone.getPhoneId();
//update the cache as modem status has changed
- mPhoneConfigurationManager.addToPhoneStatusCache(
- request.phone.getPhoneId(), msg.arg1 == 1);
- updateModemStateMetrics();
+ if ((boolean) request.result) {
+ mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
+ updateModemStateMetrics();
+ } else {
+ Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
+ + ar.exception);
+ }
+ notifyRequester(request);
+ break;
+ case CMD_GET_MODEM_STATUS:
+ request = (MainThreadRequest) msg.obj;
+ onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
+ PhoneConfigurationManager.getInstance()
+ .getPhoneStatusFromModem(request.phone, onCompleted);
+ break;
+ case EVENT_GET_MODEM_STATUS_DONE:
+ ar = (AsyncResult) msg.obj;
+ request = (MainThreadRequest) ar.userObj;
+ int id = request.phone.getPhoneId();
+ if (ar.exception == null && ar.result != null) {
+ request.result = ar.result;
+ //update the cache as modem status has changed
+ mPhoneConfigurationManager.addToPhoneStatusCache(id,
+ (boolean) request.result);
+ } else {
+ // Return true if modem status cannot be retrieved. For most cases,
+ // modem status is on. And for older version modems, GET_MODEM_STATUS
+ // and disable modem are not supported. Modem is always on.
+ // TODO: this should be fixed in R to support a third
+ // status UNKNOWN b/131631629
+ request.result = true;
+ Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
+ + ar.exception);
+ }
notifyRequester(request);
break;
default:
@@ -6276,14 +6311,16 @@
@Override
public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
+ boolean hasReadPermission = false;
try {
enforceReadPrivilegedPermission("getUiccCardsInfo");
+ hasReadPermission = true;
} catch (SecurityException e) {
// even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
// has carrier privileges on an active UICC
if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
!= TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
- throw new SecurityException("Caller does not have carrier privileges on any UICC");
+ throw new SecurityException("Caller does not have permission.");
}
}
@@ -6291,27 +6328,30 @@
try {
UiccController uiccController = UiccController.getInstance();
ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
-
- ApplicationInfo ai = mApp.getPackageManager().getApplicationInfo(callingPackage, 0);
- if ((ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
- // Remove private info if the caller doesn't have access
- ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
- for (UiccCardInfo cardInfo : cardInfos) {
- UiccCard card = uiccController.getUiccCard(cardInfo.getSlotIndex());
- UiccProfile profile = card.getUiccProfile();
- if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
- != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
- filteredInfos.add(cardInfo.getUnprivileged());
- } else {
- filteredInfos.add(cardInfo);
- }
- }
- return filteredInfos;
+ if (hasReadPermission) {
+ return cardInfos;
}
- return cardInfos;
- } catch (PackageManager.NameNotFoundException e) {
- // This should not happen since we pass the package info in from TelephonyManager
- throw new SecurityException("Invalid calling package.");
+
+ // Remove private info if the caller doesn't have access
+ ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
+ for (UiccCardInfo cardInfo : cardInfos) {
+ // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
+ // is available
+ UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getSlotIndex());
+ if (card == null || card.getUiccProfile() == null) {
+ // assume no access if the card or profile is unavailable
+ filteredInfos.add(cardInfo.getUnprivileged());
+ continue;
+ }
+ UiccProfile profile = card.getUiccProfile();
+ if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ filteredInfos.add(cardInfo);
+ } else {
+ filteredInfos.add(cardInfo.getUnprivileged());
+ }
+ }
+ return filteredInfos;
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -6791,7 +6831,11 @@
final long identity = Binder.clearCallingIdentity();
try {
- return PhoneConfigurationManager.getInstance().getPhoneStatus(phone);
+ try {
+ return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
+ } catch (NoSuchElementException ex) {
+ return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index fd7eeb2..498625d 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -177,6 +177,8 @@
public int capabilities;
// By default, we will assume that the slots are not locked.
public boolean isLocked = false;
+ // Is the emergency number associated with the slot
+ public boolean hasDialedEmergencyNumber = false;
public SlotStatus(int slotId, int capabilities) {
this.slotId = slotId;
@@ -1356,31 +1358,41 @@
if (potentialEmergencyPhones.size() > 0) {
Log.i(this, "getPhoneForEmergencyCall, Phone Id that supports emergency number:"
+ potentialEmergencyPhones.get(0).getPhoneId());
- return potentialEmergencyPhones.get(0);
+ return getFirstPhoneForEmergencyCall(potentialEmergencyPhones);
}
// c)
return getFirstPhoneForEmergencyCall();
}
+ @VisibleForTesting
+ public Phone getFirstPhoneForEmergencyCall() {
+ return getFirstPhoneForEmergencyCall(null);
+ }
+
/**
* Retrieves the most sensible Phone to use for an emergency call using the following Priority
* list (for multi-SIM devices):
* 1) The User's SIM preference for Voice calling
* 2) The First Phone that is currently IN_SERVICE or is available for emergency calling
- * 3) If there is a PUK locked SIM, compare the SIMs that are not PUK locked. If all the SIMs
- * are locked, skip to condition 4).
- * 4) The Phone with more Capabilities.
- * 5) The First Phone that has a SIM card in it (Starting from Slot 0...N)
- * 6) The Default Phone (Currently set as Slot 0)
+ * 3) Prioritize phones that have the dialed emergency number as part of their emergency
+ * number list
+ * 4) If there is a PUK locked SIM, compare the SIMs that are not PUK locked. If all the SIMs
+ * are locked, skip to condition 5).
+ * 5) The Phone with more Capabilities.
+ * 6) The First Phone that has a SIM card in it (Starting from Slot 0...N)
+ * 7) The Default Phone (Currently set as Slot 0)
*/
@VisibleForTesting
- public Phone getFirstPhoneForEmergencyCall() {
+ public Phone getFirstPhoneForEmergencyCall(List<Phone> phonesWithEmergencyNumber) {
// 1)
int phoneId = mSubscriptionManagerProxy.getDefaultVoicePhoneId();
if (phoneId != SubscriptionManager.INVALID_PHONE_INDEX) {
Phone defaultPhone = mPhoneFactoryProxy.getPhone(phoneId);
if (defaultPhone != null && isAvailableForEmergencyCalls(defaultPhone)) {
- return defaultPhone;
+ if (phonesWithEmergencyNumber == null
+ || phonesWithEmergencyNumber.contains(defaultPhone)) {
+ return defaultPhone;
+ }
}
}
@@ -1394,25 +1406,38 @@
}
// 2)
if (isAvailableForEmergencyCalls(phone)) {
- // the slot has the radio on & state is in service.
- Log.i(this, "getFirstPhoneForEmergencyCall, radio on & in service, Phone Id:" + i);
- return phone;
+ if (phonesWithEmergencyNumber == null
+ || phonesWithEmergencyNumber.contains(phone)) {
+ // the slot has the radio on & state is in service.
+ Log.i(this,
+ "getFirstPhoneForEmergencyCall, radio on & in service, Phone Id:" + i);
+ return phone;
+ }
}
- // 4)
+ // 5)
// Store the RAF Capabilities for sorting later.
int radioAccessFamily = phone.getRadioAccessFamily();
SlotStatus status = new SlotStatus(i, radioAccessFamily);
phoneSlotStatus.add(status);
Log.i(this, "getFirstPhoneForEmergencyCall, RAF:" +
Integer.toHexString(radioAccessFamily) + " saved for Phone Id:" + i);
- // 3)
+ // 4)
// Report Slot's PIN/PUK lock status for sorting later.
int simState = mSubscriptionManagerProxy.getSimStateForSlotIdx(i);
if (simState == TelephonyManager.SIM_STATE_PIN_REQUIRED ||
simState == TelephonyManager.SIM_STATE_PUK_REQUIRED) {
status.isLocked = true;
}
- // 5)
+ // 3) Store if the Phone has the corresponding emergency number
+ if (phonesWithEmergencyNumber != null) {
+ for (Phone phoneWithEmergencyNumber : phonesWithEmergencyNumber) {
+ if (phoneWithEmergencyNumber != null
+ && phoneWithEmergencyNumber.getPhoneId() == i) {
+ status.hasDialedEmergencyNumber = true;
+ }
+ }
+ }
+ // 6)
if (firstPhoneWithSim == null && mTelephonyManagerProxy.hasIccCard(i)) {
// The slot has a SIM card inserted, but is not in service, so keep track of this
// Phone. Do not return because we want to make sure that none of the other Phones
@@ -1422,19 +1447,28 @@
firstPhoneWithSim.getPhoneId());
}
}
- // 6)
+ // 7)
if (firstPhoneWithSim == null && phoneSlotStatus.isEmpty()) {
- // No Phones available, get the default.
- Log.i(this, "getFirstPhoneForEmergencyCall, return default phone");
- return mPhoneFactoryProxy.getDefaultPhone();
+ if (phonesWithEmergencyNumber == null || phonesWithEmergencyNumber.isEmpty()) {
+ // No Phones available, get the default
+ Log.i(this, "getFirstPhoneForEmergencyCall, return default phone");
+ return mPhoneFactoryProxy.getDefaultPhone();
+ }
+ return phonesWithEmergencyNumber.get(0);
} else {
- // 4)
+ // 5)
final int defaultPhoneId = mPhoneFactoryProxy.getDefaultPhone().getPhoneId();
final Phone firstOccupiedSlot = firstPhoneWithSim;
if (!phoneSlotStatus.isEmpty()) {
// Only sort if there are enough elements to do so.
if (phoneSlotStatus.size() > 1) {
Collections.sort(phoneSlotStatus, (o1, o2) -> {
+ if (!o1.hasDialedEmergencyNumber && o2.hasDialedEmergencyNumber) {
+ return -1;
+ }
+ if (o1.hasDialedEmergencyNumber && !o2.hasDialedEmergencyNumber) {
+ return 1;
+ }
// First start by seeing if either of the phone slots are locked. If they
// are, then sort by non-locked SIM first. If they are both locked, sort
// by capability instead.
@@ -1480,7 +1514,7 @@
"with highest capability");
return mPhoneFactoryProxy.getPhone(mostCapablePhoneId);
} else {
- // 5)
+ // 6)
return firstPhoneWithSim;
}
}