From 706633bcf8b4ff03b6ff58066bbbe9e2ff7b9820 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Wed, 26 Jan 2022 19:01:08 +0000 Subject: [PATCH] [Ongoing Call] Catch a security exception instead of crashing SysUI. This will mean that the ongoing call chip will stay visible even when the user is in the calling process. However, this is much better than crashing SysUI. Fixes: 216693695 Bug: 216489355 Bug: 216248574 Test: verified starting a call won't crash SysUI even with ag/16659008 in the build. Test: new unit test Change-Id: I1108fc6fe01f284364331dd9de57ebe9390d4d78 Merged-In: I1108fc6fe01f284364331dd9de57ebe9390d4d78 --- .../ongoingcall/OngoingCallController.kt | 19 +++++++++++++---- .../ongoingcall/OngoingCallControllerTest.kt | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) 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.