Loading src/com/android/server/telecom/CallsManager.java +18 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading src/com/android/server/telecom/InCallController.java +33 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; } Loading Loading @@ -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( Loading @@ -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; } Loading src/com/android/server/telecom/TelecomServiceImpl.java +53 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -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; } } Loading Loading @@ -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"); } Loading tests/src/com/android/server/telecom/tests/InCallControllerTests.java +56 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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 { Loading tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { }; Loading Loading @@ -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); Loading Loading @@ -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 { Loading Loading
src/com/android/server/telecom/CallsManager.java +18 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading
src/com/android/server/telecom/InCallController.java +33 −1 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; } Loading Loading @@ -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( Loading @@ -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; } Loading
src/com/android/server/telecom/TelecomServiceImpl.java +53 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -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; } } Loading Loading @@ -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"); } Loading
tests/src/com/android/server/telecom/tests/InCallControllerTests.java +56 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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 { Loading
tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java +20 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { }; Loading Loading @@ -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); Loading Loading @@ -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 { Loading