diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt index c7f7258513d02..6e7231ef5ca38 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt @@ -242,8 +242,14 @@ class OngoingCallController @Inject constructor( * Sets up an [IUidObserver] to monitor the status of the application managing the ongoing call. */ private fun setUpUidObserver(currentCallNotificationInfo: CallNotificationInfo) { - isCallAppVisible = isProcessVisibleToUser( - iActivityManager.getUidProcessState(currentCallNotificationInfo.uid, null)) + try { + isCallAppVisible = isProcessVisibleToUser( + iActivityManager.getUidProcessState(currentCallNotificationInfo.uid, null) + ) + } catch (se: SecurityException) { + Log.e(TAG, "Security exception when trying to get process state: $se") + return + } if (uidObserver != null) { iActivityManager.unregisterUidObserver(uidObserver) @@ -275,12 +281,17 @@ class OngoingCallController @Inject constructor( override fun onUidCachedChanged(uid: Int, cached: Boolean) {} } - iActivityManager.registerUidObserver( + try { + iActivityManager.registerUidObserver( uidObserver, ActivityManager.UID_OBSERVER_PROCSTATE, ActivityManager.PROCESS_STATE_UNKNOWN, null - ) + ) + } catch (se: SecurityException) { + Log.e(TAG, "Security exception when trying to register uid observer: $se") + return + } } /** Returns true if the given [procState] represents a process that's visible to the user. */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt index 0920cac9c0944..807664d093dab 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt @@ -217,6 +217,27 @@ class OngoingCallControllerTest : SysuiTestCase() { verify(mockIActivityManager, times(numCalls - 1)).unregisterUidObserver(any()) } + /** Regression test for b/216248574. */ + @Test + fun entryUpdated_getUidProcessStateThrowsException_noCrash() { + `when`(mockIActivityManager.getUidProcessState(eq(CALL_UID), nullable(String::class.java))) + .thenThrow(SecurityException()) + + // No assert required, just check no crash + notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) + } + + /** Regression test for b/216248574. */ + @Test + fun entryUpdated_registerUidObserverThrowsException_noCrash() { + `when`(mockIActivityManager.registerUidObserver( + any(), any(), any(), nullable(String::class.java) + )).thenThrow(SecurityException()) + + // No assert required, just check no crash + notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) + } + /** * If a call notification is never added before #onEntryRemoved is called, then the listener * should never be notified.