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

Commit ae297076 authored by Lucas Silva's avatar Lucas Silva
Browse files

Implement PackageChangeInteractor for listening to package updates.

Also moves the model to a shared directory so it can be used by the
domain and data layer.

Bug: 323220486
Flag: NA
Test: atest PackageChangeInteractorTest
Change-Id: I863d80d244ebd7da89ce6a26ae91bf3986643876
parent a4ad8c50
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.data.shared.model.PackageChangeModel
import com.android.systemui.common.shared.model.PackageChangeModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -32,6 +32,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -67,7 +68,8 @@ class PackageChangeRepositoryTest : SysuiTestCase() {
                        scope = applicationCoroutineScope,
                        context = context,
                        bgHandler = handler,
                        logger = PackageUpdateLogger(logcatLogBuffer())
                        logger = PackageUpdateLogger(logcatLogBuffer()),
                        systemClock = fakeSystemClock,
                    )
                updateMonitor
            }
+30 −7
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.data.shared.model.PackageChangeModel
import com.android.systemui.common.shared.model.PackageChangeModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.kosmos.applicationCoroutineScope
@@ -32,6 +32,7 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.log.logcatLogBuffer
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.fakeSystemClock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -71,8 +72,11 @@ class PackageUpdateMonitorTest : SysuiTestCase() {
                    bgHandler = handler,
                    context = context,
                    scope = applicationCoroutineScope,
                    logger = PackageUpdateLogger(logcatLogBuffer())
                    logger = PackageUpdateLogger(logcatLogBuffer()),
                    systemClock = fakeSystemClock,
                )

            fakeSystemClock.setCurrentTimeMillis(0)
        }

    @Test
@@ -96,11 +100,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() {
                val packageChange by collectLastValue(monitor.packageChanged)
                assertThat(packageChange).isNull()

                fakeSystemClock.setCurrentTimeMillis(100)
                monitor.onPackageAdded(TEST_PACKAGE, 123)

                assertThat(packageChange)
                    .isEqualTo(
                        PackageChangeModel.Installed(packageName = TEST_PACKAGE, packageUid = 123)
                        PackageChangeModel.Installed(
                            packageName = TEST_PACKAGE,
                            packageUid = 123,
                            timeMillis = 100,
                        )
                    )
            }
        }
@@ -112,11 +121,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() {
                val packageChange by collectLastValue(monitor.packageChanged)
                assertThat(packageChange).isNull()

                fakeSystemClock.setCurrentTimeMillis(200)
                monitor.onPackageRemoved(TEST_PACKAGE, 123)

                assertThat(packageChange)
                    .isEqualTo(
                        PackageChangeModel.Uninstalled(packageName = TEST_PACKAGE, packageUid = 123)
                        PackageChangeModel.Uninstalled(
                            packageName = TEST_PACKAGE,
                            packageUid = 123,
                            timeMillis = 200,
                        )
                    )
            }
        }
@@ -128,11 +142,16 @@ class PackageUpdateMonitorTest : SysuiTestCase() {
                val packageChange by collectLastValue(monitor.packageChanged)
                assertThat(packageChange).isNull()

                fakeSystemClock.setCurrentTimeMillis(100)
                monitor.onPackageChanged(TEST_PACKAGE, 123, emptyArray())

                assertThat(packageChange)
                    .isEqualTo(
                        PackageChangeModel.Changed(packageName = TEST_PACKAGE, packageUid = 123)
                        PackageChangeModel.Changed(
                            packageName = TEST_PACKAGE,
                            packageUid = 123,
                            timeMillis = 100,
                        )
                    )
            }
        }
@@ -144,13 +163,15 @@ class PackageUpdateMonitorTest : SysuiTestCase() {
                val packageChange by collectLastValue(monitor.packageChanged)
                assertThat(packageChange).isNull()

                fakeSystemClock.setCurrentTimeMillis(100)
                monitor.onPackageUpdateStarted(TEST_PACKAGE, 123)

                assertThat(packageChange)
                    .isEqualTo(
                        PackageChangeModel.UpdateStarted(
                            packageName = TEST_PACKAGE,
                            packageUid = 123
                            packageUid = 123,
                            timeMillis = 100,
                        )
                    )
            }
@@ -163,13 +184,15 @@ class PackageUpdateMonitorTest : SysuiTestCase() {
                val packageChange by collectLastValue(monitor.packageChanged)
                assertThat(packageChange).isNull()

                fakeSystemClock.setCurrentTimeMillis(100)
                monitor.onPackageUpdateFinished(TEST_PACKAGE, 123)

                assertThat(packageChange)
                    .isEqualTo(
                        PackageChangeModel.UpdateFinished(
                            packageName = TEST_PACKAGE,
                            packageUid = 123
                            packageUid = 123,
                            timeMillis = 100,
                        )
                    )
            }
+175 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.common.domain.interactor

import android.content.pm.UserInfo
import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.data.repository.fakePackageChangeRepository
import com.android.systemui.common.data.repository.packageChangeRepository
import com.android.systemui.common.shared.model.PackageChangeModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.user.domain.interactor.selectedUserInteractor
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidJUnit4::class)
class PackageChangeInteractorTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    private lateinit var underTest: PackageChangeInteractor

    @Before
    fun setUp() =
        with(kosmos) {
            underTest =
                PackageChangeInteractor(
                    packageChangeRepository = packageChangeRepository,
                    userInteractor = selectedUserInteractor,
                )
            fakeUserRepository.setUserInfos(listOf(MAIN_USER, SECONDARY_USER))
        }

    @Test
    fun packageChanges() =
        with(kosmos) {
            testScope.runTest {
                val packageChange by collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE))
                assertThat(packageChange).isNull()

                // Even if secondary user is active, we should still receive changes for the
                // primary user.
                setUser(SECONDARY_USER)

                fakePackageChangeRepository.notifyChange(
                    PackageChangeModel.Installed(
                        packageName = "pkg",
                        packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10),
                    )
                )

                assertThat(packageChange).isInstanceOf(PackageChangeModel.Installed::class.java)
                assertThat(packageChange?.packageName).isEqualTo("pkg")
            }
        }

    @Test
    fun packageChanges_ignoresUpdatesFromOtherUsers() =
        with(kosmos) {
            testScope.runTest {
                val packageChange by collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE))
                assertThat(packageChange).isNull()

                setUser(SECONDARY_USER)
                fakePackageChangeRepository.notifyChange(
                    PackageChangeModel.Installed(
                        packageName = "pkg",
                        packageUid = UserHandle.getUid(SECONDARY_USER.id, /* appId = */ 10),
                    )
                )

                assertThat(packageChange).isNull()
            }
        }

    @Test
    fun packageChanges_forCurrentUser() =
        with(kosmos) {
            testScope.runTest {
                val packageChanges by collectValues(underTest.packageChanged(UserHandle.CURRENT))
                assertThat(packageChanges).isEmpty()

                setUser(SECONDARY_USER)
                fakePackageChangeRepository.notifyChange(
                    PackageChangeModel.Installed(
                        packageName = "first",
                        packageUid = UserHandle.getUid(SECONDARY_USER.id, /* appId = */ 10),
                    )
                )
                fakePackageChangeRepository.notifyChange(
                    PackageChangeModel.Installed(
                        packageName = "second",
                        packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10),
                    )
                )
                setUser(MAIN_USER)
                fakePackageChangeRepository.notifyChange(
                    PackageChangeModel.Installed(
                        packageName = "third",
                        packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10),
                    )
                )

                assertThat(packageChanges.map { it.packageName })
                    .containsExactly("first", "third")
                    .inOrder()
            }
        }

    @Test
    fun packageChanges_forSpecificPackageName() =
        with(kosmos) {
            testScope.runTest {
                val packageChange by
                    collectLastValue(underTest.packageChanged(MAIN_USER_HANDLE, "mypkg"))
                assertThat(packageChange).isNull()

                fakePackageChangeRepository.notifyChange(
                    PackageChangeModel.Installed(
                        packageName = "other",
                        packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10),
                    )
                )
                assertThat(packageChange).isNull()

                fakePackageChangeRepository.notifyChange(
                    PackageChangeModel.Installed(
                        packageName = "mypkg",
                        packageUid = UserHandle.getUid(MAIN_USER.id, /* appId = */ 10),
                    )
                )
                assertThat(packageChange).isInstanceOf(PackageChangeModel.Installed::class.java)
                assertThat(packageChange?.packageName).isEqualTo("mypkg")
            }
        }

    private suspend fun TestScope.setUser(user: UserInfo) {
        kosmos.fakeUserRepository.setSelectedUserInfo(user)
        runCurrent()
    }

    private companion object {
        val MAIN_USER_HANDLE = UserHandle.of(1)
        val MAIN_USER = UserInfo(MAIN_USER_HANDLE.identifier, "main", UserInfo.FLAG_MAIN)
        val SECONDARY_USER_HANDLE = UserHandle.of(2)
        val SECONDARY_USER = UserInfo(SECONDARY_USER_HANDLE.identifier, "secondary", 0)
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.data.repository.fakePackageChangeRepository
import com.android.systemui.common.data.repository.packageChangeRepository
import com.android.systemui.common.data.shared.model.PackageChangeModel
import com.android.systemui.common.shared.model.PackageChangeModel
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
+1 −1
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@
package com.android.systemui.common.data.repository

import android.os.UserHandle
import com.android.systemui.common.data.shared.model.PackageChangeModel
import com.android.systemui.common.shared.model.PackageChangeModel
import kotlinx.coroutines.flow.Flow

interface PackageChangeRepository {
Loading