Merge "Allow carrier-privileged apps to register telephony listeners." into pi-dev
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 3896871..539c001 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -89,6 +89,8 @@
private static final boolean VDBG = false; // STOPSHIP if true
private static class Record {
+ Context context;
+
String callingPackage;
IBinder binder;
@@ -107,8 +109,6 @@
int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
- boolean canReadPhoneState;
-
boolean matchPhoneStateListenerEvent(int events) {
return (callback != null) && ((events & this.events) != 0);
}
@@ -117,6 +117,15 @@
return (onSubscriptionsChangedListenerCallback != null);
}
+ boolean canReadPhoneState() {
+ try {
+ return TelephonyPermissions.checkReadPhoneState(
+ context, subId, callerPid, callerUid, callingPackage, "listen");
+ } catch (SecurityException e) {
+ return false;
+ }
+ }
+
@Override
public String toString() {
return "{callingPackage=" + callingPackage + " binder=" + binder
@@ -124,8 +133,7 @@
+ " onSubscriptionsChangedListenererCallback="
+ onSubscriptionsChangedListenerCallback
+ " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
- + " events=" + Integer.toHexString(events)
- + " canReadPhoneState=" + canReadPhoneState + "}";
+ + " events=" + Integer.toHexString(events) + "}";
}
}
@@ -206,11 +214,6 @@
PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR |
PhoneStateListener.LISTEN_VOLTE_STATE;
- static final int CHECK_PHONE_STATE_PERMISSION_MASK =
- PhoneStateListener.LISTEN_CALL_STATE |
- PhoneStateListener.LISTEN_DATA_ACTIVITY |
- PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
-
static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE;
@@ -376,22 +379,13 @@
public void addOnSubscriptionsChangedListener(String callingPackage,
IOnSubscriptionsChangedListener callback) {
int callerUserId = UserHandle.getCallingUserId();
- mContext.getSystemService(AppOpsManager.class)
- .checkPackage(Binder.getCallingUid(), callingPackage);
+ mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
if (VDBG) {
log("listen oscl: E pkg=" + callingPackage + " myUserId=" + UserHandle.myUserId()
+ " callerUserId=" + callerUserId + " callback=" + callback
+ " callback.asBinder=" + callback.asBinder());
}
- // TODO(b/70041899): Find a way to make this work for carrier-privileged callers.
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
- "addOnSubscriptionsChangedListener")) {
- return;
- }
-
-
synchronized (mRecords) {
// register
IBinder b = callback.asBinder();
@@ -401,12 +395,12 @@
return;
}
+ r.context = mContext;
r.onSubscriptionsChangedListenerCallback = callback;
r.callingPackage = callingPackage;
r.callerUid = Binder.getCallingUid();
r.callerPid = Binder.getCallingPid();
r.events = 0;
- r.canReadPhoneState = true; // permission has been enforced above
if (DBG) {
log("listen oscl: Register r=" + r);
}
@@ -475,8 +469,7 @@
private void listen(String callingPackage, IPhoneStateListener callback, int events,
boolean notifyNow, int subId) {
int callerUserId = UserHandle.getCallingUserId();
- mContext.getSystemService(AppOpsManager.class)
- .checkPackage(Binder.getCallingUid(), callingPackage);
+ mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
if (VDBG) {
log("listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events)
+ " notifyNow=" + notifyNow + " subId=" + subId + " myUserId="
@@ -487,7 +480,7 @@
// Checks permission and throws SecurityException for disallowed operations. For pre-M
// apps whose runtime permission has been revoked, we return immediately to skip sending
// events to the app without crashing it.
- if (!checkListenerPermission(events, callingPackage, "listen")) {
+ if (!checkListenerPermission(events, subId, callingPackage, "listen")) {
return;
}
@@ -501,14 +494,11 @@
return;
}
+ r.context = mContext;
r.callback = callback;
r.callingPackage = callingPackage;
r.callerUid = Binder.getCallingUid();
r.callerPid = Binder.getCallingPid();
- boolean isPhoneStateEvent = (events & (CHECK_PHONE_STATE_PERMISSION_MASK
- | ENFORCE_PHONE_STATE_PERMISSION_MASK)) != 0;
- r.canReadPhoneState =
- isPhoneStateEvent && canReadPhoneState(callingPackage, "listen");
// Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
// force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -676,19 +666,9 @@
}
}
- private boolean canReadPhoneState(String callingPackage, String message) {
- try {
- // TODO(b/70041899): Find a way to make this work for carrier-privileged callers.
- return TelephonyPermissions.checkCallingOrSelfReadPhoneState(
- mContext, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage, message);
- } catch (SecurityException e) {
- return false;
- }
- }
-
private String getCallIncomingNumber(Record record, int phoneId) {
- // Hide the number if record's process has no READ_PHONE_STATE permission
- return record.canReadPhoneState ? mCallIncomingNumber[phoneId] : "";
+ // Hide the number if record's process can't currently read phone state.
+ return record.canReadPhoneState() ? mCallIncomingNumber[phoneId] : "";
}
private Record add(IBinder binder) {
@@ -763,7 +743,7 @@
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) &&
(r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
try {
- String incomingNumberOrEmpty = r.canReadPhoneState ? incomingNumber : "";
+ String incomingNumberOrEmpty = r.canReadPhoneState() ? incomingNumber : "";
r.callback.onCallStateChanged(state, incomingNumberOrEmpty);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
@@ -1690,7 +1670,8 @@
== PackageManager.PERMISSION_GRANTED;
}
- private boolean checkListenerPermission(int events, String callingPackage, String message) {
+ private boolean checkListenerPermission(
+ int events, int subId, String callingPackage, String message) {
if ((events & ENFORCE_COARSE_LOCATION_PERMISSION_MASK) != 0) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.ACCESS_COARSE_LOCATION, null);
@@ -1701,9 +1682,8 @@
}
if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
- // TODO(b/70041899): Find a way to make this work for carrier-privileged callers.
- if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext,
- SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage, message)) {
+ if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
+ mContext, subId, callingPackage, message)) {
return false;
}
}
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 0446925..0ff2982 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -61,9 +61,6 @@
/**
* Listen for changes to the network signal strength (cellular).
* {@more}
- * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
- * READ_PHONE_STATE}
- * <p>
*
* @see #onSignalStrengthChanged
*
@@ -76,7 +73,8 @@
* Listen for changes to the message-waiting indicator.
* {@more}
* Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
- * READ_PHONE_STATE}
+ * READ_PHONE_STATE} or that the calling app has carrier privileges (see
+ * {@link TelephonyManager#hasCarrierPrivileges}).
* <p>
* Example: The status bar uses this to determine when to display the
* voicemail icon.
@@ -89,7 +87,9 @@
* Listen for changes to the call-forwarding indicator.
* {@more}
* Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
- * READ_PHONE_STATE}
+ * READ_PHONE_STATE} or that the calling app has carrier privileges (see
+ * {@link TelephonyManager#hasCarrierPrivileges}).
+ *
* @see #onCallForwardingIndicatorChanged
*/
public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008;
@@ -430,8 +430,9 @@
* Callback invoked when device call state changes.
* @param state call state
* @param phoneNumber call phone number. If application does not have
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} permission, an empty
- * string will be passed as an argument.
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} permission or carrier
+ * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be
+ * passed as an argument.
*
* @see TelephonyManager#CALL_STATE_IDLE
* @see TelephonyManager#CALL_STATE_RINGING
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index ef66ed7..472a6fb 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -609,8 +609,6 @@
* @param listener an instance of {@link OnSubscriptionsChangedListener} with
* onSubscriptionsChanged overridden.
*/
- // TODO(b/70041899): Find a way to extend this to carrier-privileged apps.
- @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) {
String pkgName = mContext != null ? mContext.getOpPackageName() : "<unknown>";
if (DBG) {