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

Commit cf497c9f authored by Yorke Lee's avatar Yorke Lee
Browse files

Enforce CALL_PHONE permission for default/system dialer for non emergency calls

This CL fixes a bug where a default/system dialer targeting SDK 23 would
be allowed to place phone calls without the CALL_PHONE permission. This is
because for the default/system dialer, the Telecom system was only enforcing
the CALL_PHONE app_op.

In order to enforce runtime permissions for both SDK 23 and pre SDK 23 apps,
both OP_CALL_PHONE and CALL_PHONE permission must be checked.

Bug: 23607431
Change-Id: I57b6388349e0637df02799c14a2850c2c6e5a300
parent 7c64a4ee
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -808,9 +808,19 @@ public class TelecomServiceImpl {
                        + " is not allowed to place phone calls");
            }

            // Note: we can still get here for the default/system dialer, even if the Phone
            // permission is turned off. This is because the default/system dialer is always
            // allowed to attempt to place a call (regardless of permission state), in case
            // it turns out to be an emergency call. If the permission is denied and the
            // call is being made to a non-emergency number, the call will be denied later on
            // by {@link UserCallIntentProcessor}.

            final boolean hasCallAppOp = mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,
                    Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED;

            final boolean hasCallPermission = mContext.checkCallingPermission(CALL_PHONE) ==
                    PackageManager.PERMISSION_GRANTED;

            synchronized (mLock) {
                final UserHandle userHandle = Binder.getCallingUserHandle();
                long token = Binder.clearCallingIdentity();
@@ -818,7 +828,7 @@ public class TelecomServiceImpl {
                    final Intent intent = new Intent(Intent.ACTION_CALL, handle);
                    intent.putExtras(extras);
                    new UserCallIntentProcessor(mContext, userHandle).processIntent(intent,
                            callingPackage, hasCallAppOp);
                            callingPackage, hasCallAppOp && hasCallPermission);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
+5 −4
Original line number Diff line number Diff line
@@ -70,7 +70,8 @@ public class UserCallIntentProcessor {
     *
     * @param intent The intent.
     */
    public void processIntent(Intent intent, String callingPackageName, boolean hasCallAppOp) {
    public void processIntent(Intent intent, String callingPackageName,
            boolean canCallNonEmergency) {
        // Ensure call intents are not processed on devices that are not capable of calling.
        if (!isVoiceCapable()) {
            return;
@@ -81,12 +82,12 @@ public class UserCallIntentProcessor {
        if (Intent.ACTION_CALL.equals(action) ||
                Intent.ACTION_CALL_PRIVILEGED.equals(action) ||
                Intent.ACTION_CALL_EMERGENCY.equals(action)) {
            processOutgoingCallIntent(intent, callingPackageName, hasCallAppOp);
            processOutgoingCallIntent(intent, callingPackageName, canCallNonEmergency);
        }
    }

    private void processOutgoingCallIntent(Intent intent, String callingPackageName,
            boolean hasCallAppOp) {
            boolean canCallNonEmergency) {
        Uri handle = intent.getData();
        String scheme = handle.getScheme();
        String uriString = handle.getSchemeSpecificPart();
@@ -109,7 +110,7 @@ public class UserCallIntentProcessor {
            return;
        }

        if (!hasCallAppOp && !TelephonyUtil.shouldProcessAsEmergency(mContext, handle)) {
        if (!canCallNonEmergency && !TelephonyUtil.shouldProcessAsEmergency(mContext, handle)) {
            showErrorDialogForRestrictedOutgoingCall(mContext,
                    R.string.outgoing_call_not_allowed_no_permission);
            Log.w(this, "Rejecting non-emergency phone call because "