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

Commit fca9ee39 authored by Sean Kelley's avatar Sean Kelley
Browse files

Add support for skipping call filtering

This CL adds support for recognising the constant:
  PhoneAccount.EXTRA_SKIP_CALL_FILTERING

If the extra is specified to be true, this:
  - Enforces that the phone account belongs to a system app
  - Skips call filtering when new calls are added

Bug: 65223222
Test: tested locally with modified ConnectionService
Test: ran unit tests: runtest --path packages/services/Telecomm/tests
Change-Id: I78029e98df53dd73eb422031dc5fe7036c838ef7
parent 2c2dcb6d
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -20,9 +20,9 @@ import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.pm.UserInfo;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.ToneGenerator;
@@ -46,11 +46,11 @@ import android.telecom.Connection;
import android.telecom.DisconnectCause;
import android.telecom.GatewayInfo;
import android.telecom.Log;
import android.telecom.Logging.Runnable;
import android.telecom.ParcelableConference;
import android.telecom.ParcelableConnection;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.Logging.Runnable;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import android.telephony.CarrierConfigManager;
@@ -516,12 +516,20 @@ public class CallsManager extends Call.ListenerBase
    @Override
    public void onSuccessfulIncomingCall(Call incomingCall) {
        Log.d(this, "onSuccessfulIncomingCall");
        PhoneAccount phoneAccount = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
                incomingCall.getTargetPhoneAccount());
        Bundle extras =
            phoneAccount == null || phoneAccount.getExtras() == null
                ? new Bundle()
                : phoneAccount.getExtras();
        if (incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE) ||
                incomingCall.isSelfManaged()) {
            Log.i(this, "Skipping call filtering for %s (ecm=%b, selfMgd=%b)",
                incomingCall.isSelfManaged() ||
                extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING)) {
            Log.i(this, "Skipping call filtering for %s (ecm=%b, selfMgd=%b, skipExtra=%b)",
                    incomingCall.getId(),
                    incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE),
                    incomingCall.isSelfManaged());
                    incomingCall.isSelfManaged(),
                    extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING));
            onCallFilteringComplete(incomingCall, new CallFilteringResult(true, false, true, true));
            incomingCall.setIsUsingCallFiltering(false);
            return;
+12 −0
Original line number Diff line number Diff line
@@ -440,6 +440,11 @@ public class TelecomServiceImpl {
                        if (account.hasCapabilities(PhoneAccount.CAPABILITY_MULTI_USER)) {
                            enforceRegisterMultiUser();
                        }
                        Bundle extras = account.getExtras();
                        if (extras != null
                                && extras.getBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING)) {
                            enforceRegisterSkipCallFiltering();
                        }
                        enforceUserHandleMatchesCaller(account.getAccountHandle());
                        final long token = Binder.clearCallingIdentity();
                        try {
@@ -1671,6 +1676,13 @@ public class TelecomServiceImpl {
        }
    }

    private void enforceRegisterSkipCallFiltering() {
        if (!isCallerSystemApp()) {
            throw new SecurityException(
                "EXTRA_SKIP_CALL_FILTERING is only available to system apps.");
        }
    }

    private void enforceUserHandleMatchesCaller(PhoneAccountHandle accountHandle) {
        if (!Binder.getCallingUserHandle().equals(accountHandle.getUserHandle())) {
            throw new SecurityException("Calling UserHandle does not match PhoneAccountHandle's");
+30 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;

import android.content.ComponentName;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.telecom.Connection;
import android.telecom.PhoneAccount;
@@ -38,7 +39,6 @@ import android.telecom.PhoneAccountHandle;
import android.telecom.VideoProfile;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.MediumTest;

import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.AsyncRingtonePlayer;
import com.android.server.telecom.Call;
@@ -719,6 +719,35 @@ public class CallsManagerTest extends TelecomTestCase {
        verify(incomingCall).setIsUsingCallFiltering(eq(false));
    }

    @SmallTest
    @Test
    public void testNoFilteringOfCallsWhenPhoneAccountRequestsSkipped() {
        ConnectionServiceWrapper connSvr1 = Mockito.mock(ConnectionServiceWrapper.class);

        // GIVEN an incoming call which is from a PhoneAccount that requested to skip filtering.
        Call incomingCall = addSpyCallWithConnectionService(connSvr1);
        Bundle extras = new Bundle();
        extras.putBoolean(PhoneAccount.EXTRA_SKIP_CALL_FILTERING, true);
        PhoneAccount skipRequestedAccount = new PhoneAccount.Builder(SIM_2_HANDLE, "Skipper")
            .setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION
                | PhoneAccount.CAPABILITY_CALL_PROVIDER)
            .setExtras(extras)
            .setIsEnabled(true)
            .build();
        when(mPhoneAccountRegistrar.getPhoneAccountUnchecked(SIM_2_HANDLE))
            .thenReturn(skipRequestedAccount);
        doReturn(false).when(incomingCall).can(Connection.CAPABILITY_HOLD);
        doReturn(false).when(incomingCall).can(Connection.CAPABILITY_SUPPORT_HOLD);
        doReturn(false).when(incomingCall).isSelfManaged();
        doNothing().when(incomingCall).setState(anyInt(), any());

        // WHEN the incoming call is successfully added.
        mCallsManager.onSuccessfulIncomingCall(incomingCall);

        // THEN the incoming call is not using call filtering
        verify(incomingCall).setIsUsingCallFiltering(eq(false));
    }

    private Call addSpyCallWithConnectionService(ConnectionServiceWrapper connSvr) {
        Call call = addSpyCall();
        doReturn(connSvr).when(call).getConnectionService();