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

Commit f0295d4e authored by Grant Menke's avatar Grant Menke Committed by Android (Google) Code Review
Browse files

Merge "Report anomalies when setting up MO calls."

parents 1115ecf1 b39b69b8
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -266,6 +266,15 @@ public class CallsManager extends Call.ListenerBase
            UUID.fromString("1c4eed7c-9132-11ed-a1eb-0242ac120002");
    public static final String EXCEPTION_WHILE_ESTABLISHING_CONNECTION_ERROR_MSG =
            "Exception thrown while establishing connection.";
    public static final UUID EXCEPTION_RETRIEVING_PHONE_ACCOUNTS_ERROR_UUID =
            UUID.fromString("b68c881d-0ed8-4f31-9342-8bf416c96d18");
    public static final String EXCEPTION_RETRIEVING_PHONE_ACCOUNTS_ERROR_MSG =
            "Exception thrown while retrieving list of potential phone accounts.";
    public static final UUID EXCEPTION_RETRIEVING_PHONE_ACCOUNTS_EMERGENCY_ERROR_UUID =
            UUID.fromString("f272f89d-fb3a-4004-aa2d-20b8d679467e");
    public static final String EXCEPTION_RETRIEVING_PHONE_ACCOUNTS_EMERGENCY_ERROR_MSG =
            "Exception thrown while retrieving list of potential phone accounts when placing an "
                    + "emergency call.";

    private static final int[] OUTGOING_CALL_STATES =
            {CallState.CONNECTING, CallState.SELECT_PHONE_ACCOUNT, CallState.DIALING,
@@ -1762,6 +1771,15 @@ public class CallsManager extends Call.ListenerBase
                accountsForCall.whenCompleteAsync((potentialPhoneAccounts, exception) -> {
                    if (exception != null){
                        Log.e(TAG, exception, "Error retrieving list of potential phone accounts.");
                        if (finalCall.isEmergencyCall()) {
                            mAnomalyReporter.reportAnomaly(
                                    EXCEPTION_RETRIEVING_PHONE_ACCOUNTS_EMERGENCY_ERROR_UUID,
                                    EXCEPTION_RETRIEVING_PHONE_ACCOUNTS_EMERGENCY_ERROR_MSG);
                        } else {
                            mAnomalyReporter.reportAnomaly(
                                    EXCEPTION_RETRIEVING_PHONE_ACCOUNTS_ERROR_UUID,
                                    EXCEPTION_RETRIEVING_PHONE_ACCOUNTS_ERROR_MSG);
                        }
                    }
                    Log.i(CallsManager.this, "set outgoing call phone acct; potentialAccts=%s",
                            potentialPhoneAccounts);
+33 −1
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -88,6 +89,29 @@ public class InCallController extends CallsManagerListenerBase implements
        AppOpsManager.OnOpActiveChangedListener {
    public static final String NOTIFICATION_TAG = InCallController.class.getSimpleName();
    public static final int IN_CALL_SERVICE_NOTIFICATION_ID = 3;
    private AnomalyReporterAdapter mAnomalyReporter = new AnomalyReporterAdapterImpl();

    /**
     * Anomaly Report UUIDs and corresponding error descriptions specific to InCallController.
     */
    public static final UUID SET_IN_CALL_ADAPTER_ERROR_UUID =
            UUID.fromString("0c2adf96-353a-433c-afe9-1e5564f304f9");
    public static final String SET_IN_CALL_ADAPTER_ERROR_MSG =
            "Exception thrown while setting the in-call adapter.";
    public static final UUID BIND_TO_IN_CALL_ERROR_UUID =
            UUID.fromString("1261231d-b16a-4e0c-a322-623f8bb8e599");
    public static final String BIND_TO_IN_CALL_ERROR_MSG =
            "Failed to connect when attempting to bind to InCall.";
    public static final UUID BIND_TO_IN_CALL_EMERGENCY_ERROR_UUID =
            UUID.fromString("9ec8f1f0-3f0b-4079-9e9f-325f1262a8c7");
    public static final String BIND_TO_IN_CALL_EMERGENCY_ERROR_MSG =
            "Outgoing emergency call failed to connect when attempting to bind to InCall.";

    @VisibleForTesting
    public void setAnomalyReporterAdapter(AnomalyReporterAdapter mAnomalyReporterAdapter){
        mAnomalyReporter = mAnomalyReporterAdapter;
    }

    public class InCallServiceConnection {
        /**
         * Indicates that a call to {@link #connect(Call)} has succeeded and resulted in a
@@ -325,6 +349,13 @@ public class InCallController extends CallsManagerListenerBase implements
                        | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
                        | Context.BIND_SCHEDULE_LIKE_TOP_APP, userToBind)) {
                Log.w(this, "Failed to connect.");
                if (call != null && call.isEmergencyCall()) {
                    mAnomalyReporter.reportAnomaly(BIND_TO_IN_CALL_EMERGENCY_ERROR_UUID,
                            BIND_TO_IN_CALL_EMERGENCY_ERROR_MSG);
                } else {
                    mAnomalyReporter.reportAnomaly(BIND_TO_IN_CALL_ERROR_UUID,
                            BIND_TO_IN_CALL_ERROR_MSG);
                }
                mIsConnected = false;
            }

@@ -2009,7 +2040,6 @@ public class InCallController extends CallsManagerListenerBase implements
        mInCallServices.putIfAbsent(userHandle,
                new ArrayMap<InCallController.InCallServiceInfo, IInCallService>());
        mInCallServices.get(userHandle).put(info, inCallService);

        try {
            inCallService.setInCallAdapter(
                    new InCallAdapter(
@@ -2019,6 +2049,8 @@ public class InCallController extends CallsManagerListenerBase implements
                            info.getComponentName().getPackageName()));
        } catch (RemoteException e) {
            Log.e(this, e, "Failed to set the in-call adapter.");
            mAnomalyReporter.reportAnomaly(SET_IN_CALL_ADAPTER_ERROR_UUID,
                    SET_IN_CALL_ADAPTER_ERROR_MSG);
            Trace.endSection();
            return false;
        }
+53 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ import java.io.PrintWriter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

// TODO: Needed for move to system service: import com.android.internal.R;

@@ -136,6 +137,44 @@ public class TelecomServiceImpl {
            "android.permission.HANDLE_CALL_INTENT";
    private static final String ADD_CALL_ERR_MSG = "Call could not be created or found. "
            + "Retry operation.";
    private AnomalyReporterAdapter mAnomalyReporter = new AnomalyReporterAdapterImpl();

    /**
     * Anomaly Report UUIDs and corresponding error descriptions specific to TelecomServiceImpl.
     */
    public static final UUID REGISTER_PHONE_ACCOUNT_ERROR_UUID =
            UUID.fromString("0e49f82e-6acc-48a9-b088-66c8296c1eb5");
    public static final String REGISTER_PHONE_ACCOUNT_ERROR_MSG =
            "Exception thrown while registering phone account.";
    public static final UUID SET_USER_PHONE_ACCOUNT_ERROR_UUID =
            UUID.fromString("80866066-7818-4869-bd44-1f7f689543e2");
    public static final String SET_USER_PHONE_ACCOUNT_ERROR_MSG =
            "Exception thrown while setting the user selected outgoing phone account.";
    public static final UUID GET_CALL_CAPABLE_ACCOUNTS_ERROR_UUID =
            UUID.fromString("4f39b865-01f2-4c1f-83a5-37ce52807e83");
    public static final String GET_CALL_CAPABLE_ACCOUNTS_ERROR_MSG =
            "Exception thrown while getting the call capable phone accounts";
    public static final UUID GET_PHONE_ACCOUNT_ERROR_UUID =
            UUID.fromString("b653c1f0-91b4-45c8-ad05-3ee4d1006c7f");
    public static final String GET_PHONE_ACCOUNT_ERROR_MSG =
            "Exception thrown while retrieving the phone account.";
    public static final UUID GET_SIM_MANAGER_ERROR_UUID =
            UUID.fromString("4244cb3f-bd02-4cc5-9f90-f41ea62ce0bb");
    public static final String GET_SIM_MANAGER_ERROR_MSG =
            "Exception thrown while retrieving the SIM CallManager.";
    public static final UUID GET_SIM_MANAGER_FOR_USER_ERROR_UUID =
            UUID.fromString("5d347ce7-7527-40d3-b98a-09b423ad031c");
    public static final String GET_SIM_MANAGER_FOR_USER_ERROR_MSG =
            "Exception thrown while retrieving the SIM CallManager based on the provided user.";
    public static final UUID PLACE_CALL_SECURITY_EXCEPTION_ERROR_UUID =
            UUID.fromString("4edf6c8d-1e43-4c94-b0fc-a40c8d80cfe8");
    public static final String PLACE_CALL_SECURITY_EXCEPTION_ERROR_MSG =
            "Security exception thrown while placing an outgoing call.";

    @VisibleForTesting
    public void setAnomalyReporterAdapter(AnomalyReporterAdapter mAnomalyReporterAdapter){
        mAnomalyReporter = mAnomalyReporterAdapter;
    }

    private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {

@@ -295,6 +334,8 @@ public class TelecomServiceImpl {
                                accountHandle, callingUserHandle);
                    } catch (Exception e) {
                        Log.e(this, e, "setUserSelectedOutgoingPhoneAccount");
                        mAnomalyReporter.reportAnomaly(SET_USER_PHONE_ACCOUNT_ERROR_UUID,
                                SET_USER_PHONE_ACCOUNT_ERROR_MSG);
                        throw e;
                    } finally {
                        Binder.restoreCallingIdentity(token);
@@ -332,6 +373,8 @@ public class TelecomServiceImpl {
                                        hasCrossUserAccess));
                    } catch (Exception e) {
                        Log.e(this, e, "getCallCapablePhoneAccounts");
                        mAnomalyReporter.reportAnomaly(GET_CALL_CAPABLE_ACCOUNTS_ERROR_UUID,
                                GET_CALL_CAPABLE_ACCOUNTS_ERROR_MSG);
                        throw e;
                    } finally {
                        Binder.restoreCallingIdentity(token);
@@ -511,6 +554,8 @@ public class TelecomServiceImpl {
                                        /* acrossProfiles */ true);
                    } catch (Exception e) {
                        Log.e(this, e, "getPhoneAccount %s", accountHandle);
                        mAnomalyReporter.reportAnomaly(GET_PHONE_ACCOUNT_ERROR_UUID,
                                GET_PHONE_ACCOUNT_ERROR_MSG);
                        throw e;
                    } finally {
                        Binder.restoreCallingIdentity(token);
@@ -632,6 +677,8 @@ public class TelecomServiceImpl {
                    }
                } catch (Exception e) {
                    Log.e(this, e, "getSimCallManager");
                    mAnomalyReporter.reportAnomaly(GET_SIM_MANAGER_ERROR_UUID,
                            GET_SIM_MANAGER_ERROR_MSG);
                    throw e;
                } finally {
                    Log.endSession();
@@ -656,6 +703,8 @@ public class TelecomServiceImpl {
                    }
                } catch (Exception e) {
                    Log.e(this, e, "getSimCallManager");
                    mAnomalyReporter.reportAnomaly(GET_SIM_MANAGER_FOR_USER_ERROR_UUID,
                            GET_SIM_MANAGER_FOR_USER_ERROR_MSG);
                    throw e;
                } finally {
                    Log.endSession();
@@ -733,6 +782,8 @@ public class TelecomServiceImpl {
                        }
                    } catch (Exception e) {
                        Log.e(this, e, "registerPhoneAccount %s", account);
                        mAnomalyReporter.reportAnomaly(REGISTER_PHONE_ACCOUNT_ERROR_UUID,
                                REGISTER_PHONE_ACCOUNT_ERROR_MSG);
                        throw e;
                    }
                }
@@ -1722,6 +1773,8 @@ public class TelecomServiceImpl {
                        clearPhoneAccountHandleExtra = true;
                    }
                } else if (!canCallPhone(callingPackage, callingFeatureId, "placeCall")) {
                    mAnomalyReporter.reportAnomaly(PLACE_CALL_SECURITY_EXCEPTION_ERROR_UUID,
                            PLACE_CALL_SECURITY_EXCEPTION_ERROR_MSG);
                    throw new SecurityException("Package " + callingPackage
                            + " is not allowed to place phone calls");
                }
+56 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.internal.telecom.IInCallAdapter;
import com.android.internal.telecom.IInCallService;
import com.android.server.telecom.Analytics;
import com.android.server.telecom.AnomalyReporterAdapter;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallsManager;
import com.android.server.telecom.CarModeTracker;
@@ -148,6 +149,7 @@ public class InCallControllerTests extends TelecomTestCase {
    @Mock NotificationManager mNotificationManager;
    @Mock PermissionInfo mMockPermissionInfo;
    @Mock InCallController.InCallServiceInfo mInCallServiceInfo;
    @Mock private AnomalyReporterAdapter mAnomalyReporterAdapter;

    @Rule
    public TestRule compatChangeRule = new PlatformCompatChangeRule();
@@ -421,6 +423,60 @@ public class InCallControllerTests extends TelecomTestCase {
                TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS));
    }

    @MediumTest
    @Test
    public void testBindToService_OutgoingCall_FailToBind_AnomalyReported() throws Exception {
        mInCallController.setAnomalyReporterAdapter(mAnomalyReporterAdapter);
        when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
                anyInt(), any(UserHandle.class))).thenReturn(false);
        Bundle callExtras = new Bundle();
        callExtras.putBoolean("whatever", true);

        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
        when(mMockCallsManager.isInEmergencyCall()).thenReturn(false);
        when(mMockCall.isIncoming()).thenReturn(false);
        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
        when(mMockCall.isExternalCall()).thenReturn(false);
        when(mTimeoutsAdapter.getEmergencyCallbackWindowMillis(any(ContentResolver.class)))
                .thenReturn(300_000L);

        setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
        mInCallController.bindToServices(mMockCall);

        verify(mAnomalyReporterAdapter).reportAnomaly(InCallController.BIND_TO_IN_CALL_ERROR_UUID,
                InCallController.BIND_TO_IN_CALL_ERROR_MSG);
    }

    @MediumTest
    @Test
    public void testBindToService_OutgoingEmergCall_FailToBind_AnomalyReported() throws Exception {
        mInCallController.setAnomalyReporterAdapter(mAnomalyReporterAdapter);
        when(mMockContext.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class),
                anyInt(), any(UserHandle.class))).thenReturn(false);
        Bundle callExtras = new Bundle();
        callExtras.putBoolean("whatever", true);

        when(mMockCallsManager.getCurrentUserHandle()).thenReturn(mUserHandle);
        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
        when(mMockCallsManager.isInEmergencyCall()).thenReturn(false);
        when(mMockCall.isEmergencyCall()).thenReturn(true);
        when(mMockCall.isIncoming()).thenReturn(false);
        when(mMockCall.getTargetPhoneAccount()).thenReturn(PA_HANDLE);
        when(mMockCall.getIntentExtras()).thenReturn(callExtras);
        when(mMockCall.isExternalCall()).thenReturn(false);
        when(mTimeoutsAdapter.getEmergencyCallbackWindowMillis(any(ContentResolver.class)))
                .thenReturn(300_000L);

        setupMockPackageManager(false /* default */, true /* system */, false /* external calls */);
        mInCallController.bindToServices(mMockCall);

        verify(mAnomalyReporterAdapter).reportAnomaly(
                InCallController.BIND_TO_IN_CALL_EMERGENCY_ERROR_UUID,
                InCallController.BIND_TO_IN_CALL_EMERGENCY_ERROR_MSG);
    }

    @MediumTest
    @Test
    public void testBindToService_DefaultDialer_NoEmergency() throws Exception {
+20 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import android.test.suitebuilder.annotation.SmallTest;

import com.android.internal.telecom.ICallEventCallback;
import com.android.internal.telecom.ITelecomService;
import com.android.server.telecom.AnomalyReporterAdapter;
import com.android.server.telecom.Call;
import com.android.server.telecom.CallIntentProcessor;
import com.android.server.telecom.CallState;
@@ -188,6 +189,7 @@ public class TelecomServiceImplTest extends TelecomTestCase {
    @Mock private ApplicationInfo mApplicationInfo;
    @Mock private ICallEventCallback mICallEventCallback;
    @Mock private TransactionManager mTransactionManager;
    @Mock private AnomalyReporterAdapter mAnomalyReporterAdapter;

    private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() { };

@@ -238,6 +240,7 @@ public class TelecomServiceImplTest extends TelecomTestCase {
                mSettingsSecureAdapter,
                mLock);
        telecomServiceImpl.setTransactionManager(mTransactionManager);
        telecomServiceImpl.setAnomalyReporterAdapter(mAnomalyReporterAdapter);
        mTSIBinder = telecomServiceImpl.getBinder();
        mComponentContextFixture.setTelecomManager(mTelecomManager);
        when(mTelecomManager.getDefaultDialerPackage()).thenReturn(DEFAULT_DIALER_PACKAGE);
@@ -722,6 +725,23 @@ public class TelecomServiceImplTest extends TelecomTestCase {
        registerPhoneAccountTestHelper(phoneAccount, true);
    }

    @SmallTest
    @Test
    public void testRegisterPhoneAccountWithoutPermissionAnomalyReported() throws RemoteException {
        PhoneAccountHandle handle = new PhoneAccountHandle(
                new ComponentName("package", "cs"), "test", Binder.getCallingUserHandle());
        PhoneAccount account = makeSelfManagedPhoneAccount(handle).build();

        List<String> enforcedPermissions = List.of(MANAGE_OWN_CALLS);
        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
                argThat(new AnyStringIn(enforcedPermissions)), any());

        registerPhoneAccountTestHelper(account, false);
        verify(mAnomalyReporterAdapter).reportAnomaly(
                TelecomServiceImpl.REGISTER_PHONE_ACCOUNT_ERROR_UUID,
                TelecomServiceImpl.REGISTER_PHONE_ACCOUNT_ERROR_MSG);
    }

    @SmallTest
    @Test
    public void testRegisterPhoneAccountSelfManagedWithoutPermission() throws RemoteException {