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

Commit f07a8fdc authored by Tyler Gunn's avatar Tyler Gunn Committed by Android (Google) Code Review
Browse files

Merge "Permit system dialer callscreeningservice to access sip invite." into qt-dev

parents dfca4bd1 2c90c974
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -123,8 +122,10 @@ public class CallScreeningServiceHelper {
                Log.continueSession(mLoggingSession, "CSSH.oSC");
                try {
                    try {
                        // Note: for outgoing calls, never include the restricted extras.
                        screeningService.screenCall(new CallScreeningAdapter(),
                                mParcelableCallUtilsConverter.toParcelableCallForScreening(mCall));
                                mParcelableCallUtilsConverter.toParcelableCallForScreening(mCall,
                                        false /* areRestrictedExtrasIncluded */));
                    } catch (RemoteException e) {
                        Log.w(CallScreeningServiceHelper.this,
                                "Cancelling call id due to remote exception");
+54 −5
Original line number Diff line number Diff line
@@ -52,6 +52,17 @@ public class ParcelableCallUtils {
        EXTRA_KEYS_TO_SANITIZE.add(android.telecom.Connection.EXTRA_SIP_INVITE);
    }

    /**
     * A list of extra keys which should be added to {@link ParcelableCall} when it is being
     * generated for the purpose of sending to a CallScreeningService which has access to these
     * restricted keys.
     */
    private static List<String> RESTRICTED_CALL_SCREENING_EXTRA_KEYS;
    static {
        RESTRICTED_CALL_SCREENING_EXTRA_KEYS = new ArrayList<>();
        RESTRICTED_CALL_SCREENING_EXTRA_KEYS.add(android.telecom.Connection.EXTRA_SIP_INVITE);
    }

    public static class Converter {
        public ParcelableCall toParcelableCall(Call call, boolean includeVideoProvider,
                PhoneAccountRegistrar phoneAccountRegistrar) {
@@ -59,8 +70,10 @@ public class ParcelableCallUtils {
                    call, includeVideoProvider, phoneAccountRegistrar, false, false, false);
        }

        public ParcelableCall toParcelableCallForScreening(Call call) {
            return ParcelableCallUtils.toParcelableCallForScreening(call);
        public ParcelableCall toParcelableCallForScreening(Call call,
                boolean areRestrictedExtrasIncluded) {
            return ParcelableCallUtils.toParcelableCallForScreening(call,
                    areRestrictedExtrasIncluded);
        }
    }

@@ -256,10 +269,17 @@ public class ParcelableCallUtils {
     *     <li>Handle (phone number) presentation</li>
     * </ul>
     * All other fields are nulled or set to 0 values.
     * Where the call screening service is part of the system dialer, the
     * {@link Connection#EXTRA_SIP_INVITE} header information is also sent to the call screening
     * service (since the system dialer has access to this anyways).
     * @param call The telecom call to send to a call screening service.
     * @param areRestrictedExtrasIncluded {@code true} if the set of restricted extras defined in
     *                                    {@link #RESTRICTED_CALL_SCREENING_EXTRA_KEYS} are to
     *                                    be included in the parceled call, {@code false} otherwise.
     * @return Minimal {@link ParcelableCall} to send to the call screening service.
     */
    public static ParcelableCall toParcelableCallForScreening(Call call) {
    public static ParcelableCall toParcelableCallForScreening(Call call,
            boolean areRestrictedExtrasIncluded) {
        Uri handle = call.getHandlePresentation() == TelecomManager.PRESENTATION_ALLOWED ?
                call.getHandle() : null;
        int callDirection;
@@ -270,6 +290,13 @@ public class ParcelableCallUtils {
        } else {
            callDirection = DIRECTION_OUTGOING;
        }
        Bundle callExtras;
        if (areRestrictedExtrasIncluded) {
            callExtras = sanitizeRestrictedCallExtras(call.getExtras());
        } else {
            callExtras = new Bundle();
        }

        return new ParcelableCall(
                call.getId(),
                getParcelableState(call, false /* supportsExternalCalls */),
@@ -295,7 +322,7 @@ public class ParcelableCallUtils {
                0, /* videoState */
                Collections.emptyList(), /* conferenceableCallIds */
                null, /* intentExtras */
                null, /* callExtras */
                callExtras, /* callExtras */
                call.getCreationTimeMillis(),
                callDirection);
    }
@@ -303,7 +330,7 @@ public class ParcelableCallUtils {
    /**
     * Sanitize the extras bundle passed in, removing keys which should not be sent to non-system
     * dialer apps.
     * @param extras Extras bundle to sanitize.
     * @param oldExtras Extras bundle to sanitize.
     * @return The sanitized extras bundle.
     */
    private static Bundle sanitizeExtras(Bundle oldExtras) {
@@ -326,6 +353,28 @@ public class ParcelableCallUtils {
        return extras;
    }

    /**
     * Sanitize the extras bundle passed in, removing keys which should not be sent to call
     * screening services which have access to the restricted extras.
     * @param oldExtras Extras bundle to sanitize.
     * @return The sanitized extras bundle.
     */
    private static Bundle sanitizeRestrictedCallExtras(Bundle oldExtras) {
        if (oldExtras == null) {
            return new Bundle();
        }
        Bundle extras = new Bundle(oldExtras);
        Iterator<String> toCheck = extras.keySet().iterator();
        while (toCheck.hasNext()) {
            String extraKey = toCheck.next();
            if (TextUtils.isEmpty(extraKey)
                    || !RESTRICTED_CALL_SCREENING_EXTRA_KEYS.contains(extraKey)) {
                toCheck.remove();
            }
        }
        return extras;
    }

    private static int getParcelableState(Call call, boolean supportsExternalCalls) {
        int state = CallState.NEW;
        switch (call.getState()) {
+13 −3
Original line number Diff line number Diff line
@@ -160,7 +160,8 @@ public class CallScreeningServiceController implements IncomingCallFilter.CallFi
            bindDefaultDialerAndUserChosenService();
        } else {
            createCallScreeningServiceFilter().startCallScreeningFilter(mCall, this,
                    carrierPackageName, mAppLabelProxy.getAppLabel(carrierPackageName));
                    carrierPackageName, mAppLabelProxy.getAppLabel(carrierPackageName),
                    CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_CARRIER);
        }

        // Carrier filtering timed out
@@ -178,12 +179,16 @@ public class CallScreeningServiceController implements IncomingCallFilter.CallFi
    private void bindDefaultDialerAndUserChosenService() {
        if (mIsCarrierFinished) {
            String dialerPackageName = getDefaultDialerPackageName();
            String systemDialerPackageName = getSystemDialerPackageName();
            if (TextUtils.isEmpty(dialerPackageName)) {
                mIsDefaultDialerFinished = true;
            } else {
                int dialerType = dialerPackageName.equals(systemDialerPackageName) ?
                        CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_SYSTEM_DIALER :
                        CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_DEFAULT_DIALER;
                createCallScreeningServiceFilter().startCallScreeningFilter(mCall,
                        CallScreeningServiceController.this, dialerPackageName,
                        mAppLabelProxy.getAppLabel(dialerPackageName));
                        mAppLabelProxy.getAppLabel(dialerPackageName), dialerType);
            }

            String userChosenPackageName = getUserChosenPackageName();
@@ -192,7 +197,8 @@ public class CallScreeningServiceController implements IncomingCallFilter.CallFi
            } else {
                createCallScreeningServiceFilter().startCallScreeningFilter(mCall,
                        CallScreeningServiceController.this, userChosenPackageName,
                        mAppLabelProxy.getAppLabel(userChosenPackageName));
                        mAppLabelProxy.getAppLabel(userChosenPackageName),
                        CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
            }

            if (mIsDefaultDialerFinished && mIsUserChosenFinished) {
@@ -257,6 +263,10 @@ public class CallScreeningServiceController implements IncomingCallFilter.CallFi
        return TelecomManager.from(mContext).getDefaultDialerPackage();
    }

    private String getSystemDialerPackageName() {
        return TelecomManager.from(mContext).getSystemDialerPackage();
    }

    private String getUserChosenPackageName() {
        return mCallsManager.getRoleManagerAdapter().getDefaultCallScreeningApp();
    }
+18 −11
Original line number Diff line number Diff line
@@ -16,12 +16,9 @@

package com.android.server.telecom.callfiltering;

import android.Manifest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.IBinder;
import android.os.PersistableBundle;
@@ -29,9 +26,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.CallLog;
import android.provider.Settings;
import android.telecom.CallScreeningService;
import android.telecom.Log;
import android.telecom.ParcelableCall;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.text.TextUtils;
@@ -47,14 +42,17 @@ import com.android.server.telecom.PhoneAccountRegistrar;
import com.android.server.telecom.TelecomServiceImpl.SettingsSecureAdapter;
import com.android.server.telecom.TelecomSystem;

import java.util.List;

/**
 * Binds to {@link ICallScreeningService} to allow call blocking. A single instance of this class
 * handles a single call.
 */
public class CallScreeningServiceFilter {

    public static final int CALL_SCREENING_FILTER_TYPE_USER_SELECTED = 1;
    public static final int CALL_SCREENING_FILTER_TYPE_DEFAULT_DIALER = 2;
    public static final int CALL_SCREENING_FILTER_TYPE_SYSTEM_DIALER = 3;
    public static final int CALL_SCREENING_FILTER_TYPE_CARRIER = 4;

    public interface CallScreeningFilterResultCallback {
        void onCallScreeningFilterComplete(Call call, CallFilteringResult result, String
                packageName);
@@ -194,6 +192,7 @@ public class CallScreeningServiceFilter {
    private String mPackageName;
    private CharSequence mAppName;
    private boolean mHasFinished = false;
    private int mCallScreeningServiceType;

    private CallFilteringResult mResult = new CallFilteringResult(
            true, // shouldAllowCall
@@ -219,7 +218,8 @@ public class CallScreeningServiceFilter {
    public void startCallScreeningFilter(Call call,
            CallScreeningFilterResultCallback callback,
            String packageName,
                                         CharSequence appName) {
            CharSequence appName,
            int callScreeningServiceType) {
        if (mHasFinished) {
            Log.w(this, "Attempting to reuse CallScreeningServiceFilter. Ignoring.");
            return;
@@ -229,6 +229,7 @@ public class CallScreeningServiceFilter {
        mCallback = callback;
        mPackageName = packageName;
        mAppName = appName;
        mCallScreeningServiceType = callScreeningServiceType;

        mConnection = new CallScreeningServiceConnection();
        if (!CallScreeningServiceHelper.bindCallScreeningService(mContext,
@@ -262,9 +263,15 @@ public class CallScreeningServiceFilter {
    private void onServiceBound(ICallScreeningService service) {
        mService = service;
        try {
            boolean isSystemDialer =
                    mCallScreeningServiceType
                            == CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_SYSTEM_DIALER;
            // Important: Only send a minimal subset of the call to the screening service.
            // We will send some of the call extras to the call screening service which the system
            // dialer implements.
            mService.screenCall(new CallScreeningAdapter(),
                    mParcelableCallUtilsConverter.toParcelableCallForScreening(mCall));
                    mParcelableCallUtilsConverter.toParcelableCallForScreening(mCall,
                            isSystemDialer));
        } catch (RemoteException e) {
            Log.e(this, e, "Failed to set the call screening adapter.");
            finishCallScreening();
+22 −12
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.graphics.drawable.Icon;
import android.os.IBinder;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -166,7 +165,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {
    @SmallTest
    @Test
    public void testNoPackageName() {
        mFilter.startCallScreeningFilter(mCall, mCallback, null, null);
        mFilter.startCallScreeningFilter(mCall, mCallback, null, null,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(PASS_RESULT), eq(null));
    }

@@ -175,7 +175,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {
    public void testNoResolveEntries() {
        when(mPackageManager.queryIntentServicesAsUser(nullable(Intent.class), anyInt(), anyInt()))
                .thenReturn(Collections.emptyList());
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME);
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(PASS_RESULT), eq(PKG_NAME));
    }

@@ -183,7 +184,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {
    @Test
    public void testBadResolveEntry() {
        mResolveInfo.serviceInfo = null;
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME);
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(PASS_RESULT), eq(PKG_NAME));
    }

@@ -191,7 +193,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {
    @Test
    public void testPermissionlessFilterService() {
        mResolveInfo.serviceInfo.permission = null;
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME);
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(PASS_RESULT), eq(PKG_NAME));
    }

@@ -200,7 +203,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {
    public void testContextFailToBind() {
        when(mContext.bindServiceAsUser(nullable(Intent.class), nullable(ServiceConnection.class),
                anyInt(), eq(UserHandle.CURRENT))).thenReturn(false);
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME);
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(PASS_RESULT), eq(PKG_NAME));
    }

@@ -209,7 +213,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {
    public void testExceptionInScreeningService() throws Exception {
        doThrow(new RemoteException()).when(mCallScreeningService).screenCall(
                nullable(ICallScreeningAdapter.class), nullable(ParcelableCall.class));
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME);
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        ServiceConnection serviceConnection = verifyBindingIntent();
        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
        verify(mCallback).onCallScreeningFilterComplete(eq(mCall), eq(PASS_RESULT), eq(PKG_NAME));
@@ -218,7 +223,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {
    @SmallTest
    @Test
    public void testAllowCall() throws Exception {
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME);
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        ServiceConnection serviceConnection = verifyBindingIntent();
        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
@@ -229,7 +235,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {
    @SmallTest
    @Test
    public void testSilenceCall() throws Exception {
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME);
        mFilter.startCallScreeningFilter(mCall, mCallback, PKG_NAME, APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        ServiceConnection serviceConnection = verifyBindingIntent();
        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
@@ -249,7 +256,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {

        mFilter.startCallScreeningFilter(mCall, mCallback,
                CARRIER_DEFINED_CALL_SCREENING.getPackageName(),
                CARRIER_DEFINED_CALL_SCREENING_APP_NAME);
                CARRIER_DEFINED_CALL_SCREENING_APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_CARRIER);
        ServiceConnection serviceConnection = verifyBindingIntent();
        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
@@ -281,7 +289,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {

        mFilter.startCallScreeningFilter(mCall, mCallback,
                DEFAULT_DIALER_CALL_SCREENING.getPackageName(),
                DEFAULT_DIALER_APP_NAME);
                DEFAULT_DIALER_APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_DEFAULT_DIALER);
        ServiceConnection serviceConnection = verifyBindingIntent();
        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
@@ -313,7 +322,8 @@ public class CallScreeningServiceFilterTest extends TelecomTestCase {

        mFilter.startCallScreeningFilter(mCall, mCallback,
                USER_CHOSEN_CALL_SCREENING.getPackageName(),
                USER_CHOSEN_CALL_SCREENING_APP_NAME);
                USER_CHOSEN_CALL_SCREENING_APP_NAME,
                CallScreeningServiceFilter.CALL_SCREENING_FILTER_TYPE_USER_SELECTED);
        ServiceConnection serviceConnection = verifyBindingIntent();
        serviceConnection.onServiceConnected(COMPONENT_NAME, mBinder);
        ICallScreeningAdapter csAdapter = getCallScreeningAdapter();
Loading