Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be3e094f authored by Jeff Davidson's avatar Jeff Davidson Committed by Android (Google) Code Review
Browse files

Merge "Allow carrier-privileged apps to register telephony listeners." into pi-dev-plus-aosp

parents c9791bca e173cbd3
Loading
Loading
Loading
Loading
+24 −44
Original line number Diff line number Diff line
@@ -89,6 +89,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;
@@ -107,8 +109,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);
        }
@@ -117,6 +117,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
@@ -124,8 +133,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
                    + " onSubscriptionsChangedListenererCallback="
                                            + onSubscriptionsChangedListenerCallback
                    + " callerUid=" + callerUid + " subId=" + subId + " phoneId=" + phoneId
                    + " events=" + Integer.toHexString(events)
                    + " canReadPhoneState=" + canReadPhoneState + "}";
                    + " events=" + Integer.toHexString(events) + "}";
        }
    }

@@ -206,11 +214,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;
@@ -376,22 +379,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();
@@ -401,12 +395,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);
            }
@@ -475,8 +469,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="
@@ -487,7 +480,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;
            }

@@ -501,14 +494,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)) {
@@ -676,19 +666,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) {
@@ -763,7 +743,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);
@@ -1690,7 +1670,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);
@@ -1701,9 +1682,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;
            }
        }
+8 −7
Original line number Diff line number Diff line
@@ -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
+0 −2
Original line number Diff line number Diff line
@@ -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) {