Merge "Require correct permission in carrier config loader." into mnc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ab074e4..1ce9e9c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1283,7 +1283,7 @@
<string name="message_decode_error">There was an error while decoding the message.</string>
<!-- Call failure reason: SIM card and roaming capabilities have already been activated. [CHAR LIMIT=NONE]-->
- <string name="callFailed_cdma_activation_">
+ <string name="callFailed_cdma_activation">
A SIM card has activated your service and updated your phone\'s roaming capabilities.
</string>
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 6a4034e..11f81ff 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -200,8 +200,7 @@
(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Preference phoneAccountSettingsPreference = findPreference(PHONE_ACCOUNT_SETTINGS_KEY);
- if (telephonyManager.isMultiSimEnabled() || (mTelecomManager.getSimCallManagers().isEmpty()
- && !SipUtil.isVoipSupported(mPhone.getContext()))) {
+ if (telephonyManager.isMultiSimEnabled() || !SipUtil.isVoipSupported(mPhone.getContext())) {
getPreferenceScreen().removePreference(phoneAccountSettingsPreference);
}
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index f1706be..d5db212 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -17,7 +17,6 @@
package com.android.phone;
import static android.Manifest.permission.READ_PHONE_STATE;
-import static com.android.internal.telephony.uicc.IccCardProxy.ACTION_INTERNAL_SIM_STATE_CHANGED;
import android.annotation.NonNull;
import android.app.ActivityManagerNative;
@@ -72,7 +71,6 @@
/**
* CarrierConfigLoader binds to privileged carrier apps to fetch carrier config overlays.
- * TODO: handle package install/uninstall events
*/
public class CarrierConfigLoader extends ICarrierConfigLoader.Stub {
@@ -163,10 +161,13 @@
case EVENT_PACKAGE_CHANGED:
carrierPackageName = (String) msg.obj;
- deleteConfigForPackage(carrierPackageName);
- int numPhones = TelephonyManager.from(mContext).getPhoneCount();
- for (int i = 0; i < numPhones; ++i) {
- updateConfigForPhoneId(i);
+ // Only update if there are cached config removed to avoid updating config
+ // for unrelated packages.
+ if (deleteConfigForPackage(carrierPackageName)) {
+ int numPhones = TelephonyManager.from(mContext).getPhoneCount();
+ for (int i = 0; i < numPhones; ++i) {
+ updateConfigForPhoneId(i);
+ }
}
break;
@@ -311,12 +312,14 @@
private CarrierConfigLoader(Context context) {
mContext = context;
- // Register for package updates.
- IntentFilter triggers = new IntentFilter();
- triggers.addAction(Intent.ACTION_PACKAGE_ADDED);
- triggers.addAction(Intent.ACTION_PACKAGE_CHANGED);
- triggers.addAction(Intent.ACTION_PACKAGE_REMOVED);
- mContext.registerReceiver(mReceiver, triggers);
+ // Register for package updates. Update app or uninstall app update will have all 3 intents,
+ // in the order or removed, added, replaced, all with extra_replace set to true.
+ IntentFilter pkgFilter = new IntentFilter();
+ pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ pkgFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+ pkgFilter.addDataScheme("package");
+ context.registerReceiverAsUser(mReceiver, UserHandle.ALL, pkgFilter, null, null);
int numPhones = TelephonyManager.from(context).getPhoneCount();
mConfigFromDefaultApp = new PersistableBundle[numPhones];
@@ -530,18 +533,23 @@
return restoredBundle;
}
- /** Deletes all saved XML files associated with the given package name. */
- private void deleteConfigForPackage(final String packageName) {
+ /**
+ * Deletes all saved XML files associated with the given package name.
+ * Return false if can't find matching XML files.
+ */
+ private boolean deleteConfigForPackage(final String packageName) {
File dir = mContext.getFilesDir();
File[] packageFiles = dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename) {
return filename.startsWith("carrierconfig-" + packageName + "-");
}
});
+ if (packageFiles == null || packageFiles.length < 1) return false;
for (File f : packageFiles) {
log("deleting " + f.getName());
f.delete();
}
+ return true;
}
/** Builds a canonical file name for a config file. */
@@ -566,6 +574,12 @@
* have a saved config file to use instead.
*/
private void updateConfigForPhoneId(int phoneId) {
+ // Clear in-memory cache for carrier app config, so when carrier app gets uninstalled, no
+ // stale config is left.
+ if (mConfigFromCarrierApp[phoneId] != null &&
+ getCarrierPackageForPhoneId(phoneId) == null) {
+ mConfigFromCarrierApp[phoneId] = null;
+ }
mHandler.sendMessage(mHandler.obtainMessage(EVENT_FETCH_DEFAULT, phoneId, -1));
}
@@ -675,18 +689,23 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- log("Receive action: " + action);
+ boolean replace = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+ // If replace is true, only care ACTION_PACKAGE_REPLACED.
+ if (replace && !Intent.ACTION_PACKAGE_REPLACED.equals(action))
+ return;
+
switch (action) {
case Intent.ACTION_PACKAGE_ADDED:
- case Intent.ACTION_PACKAGE_CHANGED:
case Intent.ACTION_PACKAGE_REMOVED:
+ case Intent.ACTION_PACKAGE_REPLACED:
int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
String packageName = mContext.getPackageManager().getNameForUid(uid);
- // We don't have a phoneId for arg1.
- mHandler.sendMessage(
- mHandler.obtainMessage(EVENT_PACKAGE_CHANGED, packageName));
+ if (packageName != null) {
+ // We don't have a phoneId for arg1.
+ mHandler.sendMessage(
+ mHandler.obtainMessage(EVENT_PACKAGE_CHANGED, packageName));
+ }
break;
-
}
}
}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index ec8ce40..882a898 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -227,15 +227,18 @@
IccAPDUArgument iccArgument;
switch (msg.what) {
- case CMD_HANDLE_PIN_MMI:
+ case CMD_HANDLE_PIN_MMI: {
request = (MainThreadRequest) msg.obj;
- request.result = getPhoneFromRequest(request).handlePinMmi(
- (String) request.argument);
+ final Phone phone = getPhoneFromRequest(request);
+ request.result = phone != null ?
+ getPhoneFromRequest(request).handlePinMmi((String) request.argument)
+ : false;
// Wake up the requesting thread
synchronized (request) {
request.notifyAll();
}
break;
+ }
case CMD_HANDLE_NEIGHBORING_CELL:
request = (MainThreadRequest) msg.obj;
@@ -2201,16 +2204,26 @@
}
@Override
- public String[] getMergedSubscriberIds() {
+ public String[] getMergedSubscriberIds(String callingPackage) {
+ if (!canReadPhoneState(callingPackage, "getMergedSubscriberIds")) {
+ return null;
+ }
final Context context = mPhone.getContext();
final TelephonyManager tele = TelephonyManager.from(context);
final SubscriptionManager sub = SubscriptionManager.from(context);
// Figure out what subscribers are currently active
final ArraySet<String> activeSubscriberIds = new ArraySet<>();
- final int[] subIds = sub.getActiveSubscriptionIdList();
- for (int subId : subIds) {
- activeSubscriberIds.add(tele.getSubscriberId(subId));
+ // Clear calling identity, when calling TelephonyManager, because callerUid must be
+ // the process, where TelephonyManager was instantiated. Otherwise AppOps check will fail.
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final int[] subIds = sub.getActiveSubscriptionIdList();
+ for (int subId : subIds) {
+ activeSubscriberIds.add(tele.getSubscriberId(subId));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
// First pass, find a number override for an active subscriber
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index aaaf7db..4a92847 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -95,6 +95,7 @@
return DisconnectCause.RESTRICTED;
case android.telephony.DisconnectCause.CDMA_ACCESS_FAILURE:
+ case android.telephony.DisconnectCause.CDMA_ALREADY_ACTIVATED:
case android.telephony.DisconnectCause.CDMA_CALL_LOST:
case android.telephony.DisconnectCause.CDMA_DROP:
case android.telephony.DisconnectCause.CDMA_INTERCEPT:
@@ -230,6 +231,10 @@
resourceId = R.string.callFailed_cb_enabled;
break;
+ case android.telephony.DisconnectCause.CDMA_ALREADY_ACTIVATED:
+ resourceId = R.string.callFailed_cdma_activation;
+ break;
+
case android.telephony.DisconnectCause.FDN_BLOCKED:
resourceId = R.string.callFailed_fdn_only;
break;
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index a52418c..8c09a95 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -724,7 +724,8 @@
break;
case DISCONNECTED:
setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
- mOriginalConnection.getDisconnectCause()));
+ mOriginalConnection.getDisconnectCause(),
+ mOriginalConnection.getVendorDisconnectCause()));
close();
break;
case DISCONNECTING:
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 7826ce0..f8a3b84 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -185,7 +185,8 @@
if (disableActivation) {
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
- android.telephony.DisconnectCause.INVALID_NUMBER,
+ android.telephony.DisconnectCause
+ .CDMA_ALREADY_ACTIVATED,
"Tried to dial *228"));
}
}
@@ -293,7 +294,8 @@
if (phone == null) {
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
- android.telephony.DisconnectCause.ERROR_UNSPECIFIED));
+ android.telephony.DisconnectCause.ERROR_UNSPECIFIED,
+ "Phone is null"));
}
Call call = phone.getRingingCall();
@@ -332,7 +334,8 @@
if (phone == null) {
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
- android.telephony.DisconnectCause.ERROR_UNSPECIFIED));
+ android.telephony.DisconnectCause.ERROR_UNSPECIFIED,
+ "Phone is null"));
}
final List<com.android.internal.telephony.Connection> allConnections = new ArrayList<>();