From f91346f2893881e13f4cbc3cfc2633de80b794b9 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Wed, 26 Jan 2022 19:01:08 +0000 Subject: [PATCH 1/2] [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 --- .../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. From 63e2995eaa3a2b598dec82d88e68d108579bfa55 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Thu, 17 Feb 2022 19:55:26 +0000 Subject: [PATCH 2/2] [Ongoing Call] Provide our package name when requesting UID process state of dialer. This ensures that we can still access the UID process state of dialer apps even after ag/16659008 is submitted. Fixes: 216489355 Test: atest OngoingCallControllerTest Bug: 216248574 Bug: 216693695 Change-Id: Ibe37de264dd1b84af0348c84e6d6eace74187bd9 --- .../dagger/StatusBarDependenciesModule.java | 2 ++ .../phone/ongoingcall/OngoingCallController.kt | 8 ++++++-- .../phone/ongoingcall/OngoingCallControllerTest.kt | 13 +++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java index c687e8282c7c9..fa6b502776db5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java @@ -261,6 +261,7 @@ public interface StatusBarDependenciesModule { @Provides @SysUISingleton static OngoingCallController provideOngoingCallController( + Context context, CommonNotifCollection notifCollection, SystemClock systemClock, ActivityStarter activityStarter, @@ -284,6 +285,7 @@ public interface StatusBarDependenciesModule { : Optional.empty(); OngoingCallController ongoingCallController = new OngoingCallController( + context, notifCollection, ongoingCallFlags, systemClock, 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 6e7231ef5ca38..4fccc5a07317b 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 @@ -21,6 +21,7 @@ import android.app.IActivityManager import android.app.IUidObserver import android.app.Notification import android.app.Notification.CallStyle.CALL_TYPE_ONGOING +import android.content.Context import android.content.Intent import android.util.Log import android.view.View @@ -52,6 +53,7 @@ import javax.inject.Inject */ @SysUISingleton class OngoingCallController @Inject constructor( + private val context: Context, private val notifCollection: CommonNotifCollection, private val ongoingCallFlags: OngoingCallFlags, private val systemClock: SystemClock, @@ -244,7 +246,9 @@ class OngoingCallController @Inject constructor( private fun setUpUidObserver(currentCallNotificationInfo: CallNotificationInfo) { try { isCallAppVisible = isProcessVisibleToUser( - iActivityManager.getUidProcessState(currentCallNotificationInfo.uid, null) + iActivityManager.getUidProcessState( + currentCallNotificationInfo.uid, context.opPackageName + ) ) } catch (se: SecurityException) { Log.e(TAG, "Security exception when trying to get process state: $se") @@ -286,7 +290,7 @@ class OngoingCallController @Inject constructor( uidObserver, ActivityManager.UID_OBSERVER_PROCSTATE, ActivityManager.PROCESS_STATE_UNKNOWN, - null + context.opPackageName ) } catch (se: SecurityException) { Log.e(TAG, "Security exception when trying to register uid observer: $se") 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 807664d093dab..ada0453acd86c 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 @@ -105,6 +105,7 @@ class OngoingCallControllerTest : SysuiTestCase() { val notificationCollection = mock(CommonNotifCollection::class.java) controller = OngoingCallController( + context, notificationCollection, mockOngoingCallFlags, clock, @@ -238,6 +239,18 @@ class OngoingCallControllerTest : SysuiTestCase() { notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) } + /** Regression test for b/216248574. */ + @Test + fun entryUpdated_packageNameProvidedToActivityManager() { + notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) + + val packageNameCaptor = ArgumentCaptor.forClass(String::class.java) + verify(mockIActivityManager).registerUidObserver( + any(), any(), any(), packageNameCaptor.capture() + ) + assertThat(packageNameCaptor.value).isNotNull() + } + /** * If a call notification is never added before #onEntryRemoved is called, then the listener * should never be notified.