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 16fa5da9e9794..6982631766f79 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 @@ -218,6 +218,10 @@ class OngoingCallController @Inject constructor( isCallAppVisible = isProcessVisibleToUser( iActivityManager.getUidProcessState(currentCallNotificationInfo.uid, null)) + if (uidObserver != null) { + iActivityManager.unregisterUidObserver(uidObserver) + } + uidObserver = object : IUidObserver.Stub() { override fun onUidStateChanged( uid: Int, procState: Int, procStateSeq: Long, capability: Int) { 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 d36cb0b3a7177..d26db4c69ecef 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 @@ -184,6 +184,21 @@ class OngoingCallControllerTest : SysuiTestCase() { .isGreaterThan(0) } + /** Regression test for b/194731244. */ + @Test + fun onEntryUpdated_calledManyTimes_uidObserverUnregisteredManyTimes() { + val numCalls = 4 + + for (i in 0 until numCalls) { + // Re-create the notification each time so that it's considered a different object and + // observers will get re-registered (and hopefully unregistered). + notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) + } + + // There should be 1 observer still registered, so we should unregister n-1 times. + verify(mockIActivityManager, times(numCalls - 1)).unregisterUidObserver(any()) + } + /** * If a call notification is never added before #onEntryRemoved is called, then the listener * should never be notified.