Merge "Allow carrier-privileged apps to register telephony listeners."

This commit is contained in:
TreeHugger Robot
2018-03-15 02:35:45 +00:00
committed by Android (Google) Code Review
3 changed files with 32 additions and 53 deletions

View File

@@ -90,6 +90,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private static final boolean VDBG = false; // STOPSHIP if true
private static class Record {
Context context;
String callingPackage;
IBinder binder;
@@ -108,8 +110,6 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
boolean canReadPhoneState;
boolean matchPhoneStateListenerEvent(int events) {
return (callback != null) && ((events & this.events) != 0);
}
@@ -118,6 +118,15 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
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
@@ -125,8 +134,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
+ " onSubscriptionsChangedListenererCallback="
+ onSubscriptionsChangedListenerCallback
+ " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
+ " events=" + Integer.toHexString(events)
+ " canReadPhoneState=" + canReadPhoneState + "}";
+ " events=" + Integer.toHexString(events) + "}";
}
}
@@ -212,11 +220,6 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
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;
@@ -386,22 +389,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
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();
@@ -411,12 +405,12 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
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);
}
@@ -485,8 +479,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
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="
@@ -497,7 +490,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
// 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;
}
@@ -511,14 +504,11 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
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)) {
@@ -686,19 +676,9 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
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) {
@@ -773,7 +753,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
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);
@@ -1727,7 +1707,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
== 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);
@@ -1738,9 +1719,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
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;
}
}

View File

@@ -62,9 +62,6 @@ public class PhoneStateListener {
/**
* 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
*
@@ -77,7 +74,8 @@ public class PhoneStateListener {
* 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.
@@ -90,7 +88,9 @@ public class PhoneStateListener {
* 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;
@@ -439,8 +439,9 @@ public class PhoneStateListener {
*
* @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.
*/
public void onCallStateChanged(@TelephonyManager.CallState int state, String phoneNumber) {
// default implementation empty

View File

@@ -609,8 +609,6 @@ public class SubscriptionManager {
* @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) {