Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 158fd68d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Ibe37de26,I1108fc6f

* changes:
  [Ongoing Call] Provide our package name when requesting UID process state of dialer.
  [Ongoing Call] Catch a security exception instead of crashing SysUI.
parents f2ff0ea1 63e2995e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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,
+20 −5
Original line number Diff line number Diff line
@@ -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,
@@ -242,8 +244,16 @@ class OngoingCallController @Inject constructor(
     * Sets up an [IUidObserver] to monitor the status of the application managing the ongoing call.
     */
    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")
            return
        }

        if (uidObserver != null) {
            iActivityManager.unregisterUidObserver(uidObserver)
@@ -275,12 +285,17 @@ class OngoingCallController @Inject constructor(
            override fun onUidCachedChanged(uid: Int, cached: Boolean) {}
        }

        try {
            iActivityManager.registerUidObserver(
                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")
            return
        }
    }

    /** Returns true if the given [procState] represents a process that's visible to the user. */
+34 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ class OngoingCallControllerTest : SysuiTestCase() {
        val notificationCollection = mock(CommonNotifCollection::class.java)

        controller = OngoingCallController(
                context,
                notificationCollection,
                mockOngoingCallFlags,
                clock,
@@ -217,6 +218,39 @@ 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())
    }

    /** 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.