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

Commit 6ebd7c5c authored by Tyler Gunn's avatar Tyler Gunn Committed by android-build-merger
Browse files

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

am: f07a8fdc

Change-Id: Ied5cc32989d06afb8a11aa5f799e82a5d91b8be7
parents 4379fbc2 f07a8fdc
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