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

Commit 8f8016e3 authored by Bryce Lee's avatar Bryce Lee
Browse files

Ignore package sessions with empty package names.

This changelist prevents package sessions with empty package names from
being processed. Previously, the SessionInfo was directly translated
into a PackageInstallSession model. Since the package name field is
non-null, this can lead to a crash. The conversion now returns a
nullable result which is checked by the callers.

Fixes: 398478006
Flag: EXEMPT bugfix
Test: atest PackageInstallerMonitorTest#onCreateUpdatedSession_ignoreNullPackageNameSessions
Change-Id: I42703ec1f9664094aa0db70ed0c9911f10ade4d2
parent 2f39979e
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.PackageInstallSession
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.kosmos.backgroundScope
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.testKosmos
@@ -172,6 +175,58 @@ class PackageInstallerMonitorTest : SysuiTestCase() {
            assertThat(sessions?.size).isEqualTo(1)
        }

    @Test
    fun onCreateUpdatedSession_ignoreNullPackageNameSessions() =
        kosmos.runTest {
            val nullPackageSession =
                SessionInfo().apply {
                    sessionId = 1
                    appPackageName = null
                    appIcon = icon1
                }

            val wellFormedSession =
                SessionInfo().apply {
                    sessionId = 2
                    appPackageName = "pkg_name"
                    appIcon = icon2
                }

            defaultSessions = listOf(wellFormedSession)

            whenever(packageInstaller.allSessions).thenReturn(defaultSessions)
            whenever(packageInstaller.getSessionInfo(1)).thenReturn(nullPackageSession)
            whenever(packageInstaller.getSessionInfo(2)).thenReturn(wellFormedSession)

            val packageInstallerMonitor =
                PackageInstallerMonitor(
                    handler,
                    backgroundScope,
                    logcatLogBuffer("PackageInstallerRepositoryImplTest"),
                    packageInstaller,
                )

            val sessions by collectLastValue(packageInstallerMonitor.installSessionsForPrimaryUser)

            // Verify flow updated with the new session
            assertThat(sessions)
                .comparingElementsUsing(represents)
                .containsExactlyElementsIn(defaultSessions)

            val callback =
                withArgCaptor<PackageInstaller.SessionCallback> {
                    verify(packageInstaller).registerSessionCallback(capture(), eq(handler))
                }

            // New session added
            callback.onCreated(nullPackageSession.sessionId)

            // Verify flow updated with the new session
            assertThat(sessions)
                .comparingElementsUsing(represents)
                .containsExactlyElementsIn(defaultSessions)
        }

    @Test
    fun installSessions_newSessionsAreAdded() =
        testScope.runTest {
+8 −5
Original line number Diff line number Diff line
@@ -64,15 +64,14 @@ constructor(
                        synchronized(sessions) {
                            sessions.putAll(
                                packageInstaller.allSessions
                                    .filter { !TextUtils.isEmpty(it.appPackageName) }
                                    .map { session -> session.toModel() }
                                    .mapNotNull { session -> session.toModel() }
                                    .associateBy { it.sessionId }
                            )
                            updateInstallerSessionsFlow()
                        }
                        packageInstaller.registerSessionCallback(
                            this@PackageInstallerMonitor,
                            bgHandler
                            bgHandler,
                        )
                    } else {
                        synchronized(sessions) {
@@ -130,7 +129,7 @@ constructor(
            if (session == null) {
                sessions.remove(sessionId)
            } else {
                sessions[sessionId] = session.toModel()
                session.toModel()?.apply { sessions[sessionId] = this }
            }
            updateInstallerSessionsFlow()
        }
@@ -144,7 +143,11 @@ constructor(
    companion object {
        const val TAG = "PackageInstallerMonitor"

        private fun PackageInstaller.SessionInfo.toModel(): PackageInstallSession {
        private fun PackageInstaller.SessionInfo.toModel(): PackageInstallSession? {
            if (TextUtils.isEmpty(this.appPackageName)) {
                return null
            }

            return PackageInstallSession(
                sessionId = this.sessionId,
                packageName = this.appPackageName,