1 /* <lambda>null2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.common.data.repository 18 19 import android.content.Context 20 import android.content.pm.PackageManager 21 import android.os.Handler 22 import android.os.UserHandle 23 import androidx.test.ext.junit.runners.AndroidJUnit4 24 import androidx.test.filters.SmallTest 25 import com.android.systemui.SysuiTestCase 26 import com.android.systemui.common.shared.model.PackageChangeModel 27 import com.android.systemui.coroutines.collectLastValue 28 import com.android.systemui.coroutines.collectValues 29 import com.android.systemui.kosmos.applicationCoroutineScope 30 import com.android.systemui.kosmos.testDispatcher 31 import com.android.systemui.kosmos.testScope 32 import com.android.systemui.log.logcatLogBuffer 33 import com.android.systemui.testKosmos 34 import com.android.systemui.util.mockito.whenever 35 import com.android.systemui.util.time.fakeSystemClock 36 import com.google.common.truth.Truth.assertThat 37 import kotlinx.coroutines.test.runTest 38 import org.junit.Before 39 import org.junit.Test 40 import org.junit.runner.RunWith 41 import org.mockito.Mock 42 import org.mockito.MockitoAnnotations 43 44 @SmallTest 45 @RunWith(AndroidJUnit4::class) 46 class PackageChangeRepositoryTest : SysuiTestCase() { 47 48 private val kosmos = testKosmos() 49 50 @Mock private lateinit var context: Context 51 @Mock private lateinit var packageManager: PackageManager 52 @Mock private lateinit var handler: Handler 53 @Mock private lateinit var packageInstallerMonitor: PackageInstallerMonitor 54 55 private lateinit var repository: PackageChangeRepository 56 private lateinit var updateMonitor: PackageUpdateMonitor 57 58 @Before 59 fun setUp() = 60 with(kosmos) { 61 MockitoAnnotations.initMocks(this@PackageChangeRepositoryTest) 62 whenever(context.packageManager).thenReturn(packageManager) 63 64 repository = 65 PackageChangeRepositoryImpl(packageInstallerMonitor) { user -> 66 updateMonitor = 67 PackageUpdateMonitor( 68 user = user, 69 bgDispatcher = testDispatcher, 70 scope = applicationCoroutineScope, 71 context = context, 72 bgHandler = handler, 73 logger = PackageUpdateLogger(logcatLogBuffer()), 74 systemClock = fakeSystemClock, 75 ) 76 updateMonitor 77 } 78 } 79 80 @Test 81 fun packageUninstalled() = 82 with(kosmos) { 83 testScope.runTest { 84 val packageChange by collectLastValue(repository.packageChanged(USER_100)) 85 assertThat(packageChange).isNull() 86 87 updateMonitor.onPackageRemoved( 88 packageName = TEST_PACKAGE, 89 uid = UserHandle.getUid(/* userId = */ 100, /* appId = */ 10) 90 ) 91 92 assertThat(packageChange).isInstanceOf(PackageChangeModel.Uninstalled::class.java) 93 assertThat(packageChange?.packageName).isEqualTo(TEST_PACKAGE) 94 } 95 } 96 97 @Test 98 fun packageUpdateStarted() = 99 with(kosmos) { 100 testScope.runTest { 101 val packageChange by collectLastValue(repository.packageChanged(USER_100)) 102 assertThat(packageChange).isNull() 103 104 updateMonitor.onPackageUpdateStarted( 105 packageName = TEST_PACKAGE, 106 uid = UserHandle.getUid(/* userId = */ 100, /* appId = */ 10) 107 ) 108 109 assertThat(packageChange).isInstanceOf(PackageChangeModel.UpdateStarted::class.java) 110 assertThat(packageChange?.packageName).isEqualTo(TEST_PACKAGE) 111 } 112 } 113 114 @Test 115 fun packageUpdateFinished() = 116 with(kosmos) { 117 testScope.runTest { 118 val packageChange by collectLastValue(repository.packageChanged(USER_100)) 119 assertThat(packageChange).isNull() 120 121 updateMonitor.onPackageUpdateFinished( 122 packageName = TEST_PACKAGE, 123 uid = UserHandle.getUid(/* userId = */ 100, /* appId = */ 10) 124 ) 125 126 assertThat(packageChange) 127 .isInstanceOf(PackageChangeModel.UpdateFinished::class.java) 128 assertThat(packageChange?.packageName).isEqualTo(TEST_PACKAGE) 129 } 130 } 131 132 @Test 133 fun packageInstalled() = 134 with(kosmos) { 135 testScope.runTest { 136 val packageChange by collectLastValue(repository.packageChanged(UserHandle.ALL)) 137 assertThat(packageChange).isNull() 138 139 updateMonitor.onPackageAdded( 140 packageName = TEST_PACKAGE, 141 uid = UserHandle.getUid(/* userId = */ 100, /* appId = */ 10) 142 ) 143 144 assertThat(packageChange).isInstanceOf(PackageChangeModel.Installed::class.java) 145 assertThat(packageChange?.packageName).isEqualTo(TEST_PACKAGE) 146 } 147 } 148 149 @Test 150 fun packageIsChanged() = 151 with(kosmos) { 152 testScope.runTest { 153 val packageChange by collectLastValue(repository.packageChanged(USER_100)) 154 assertThat(packageChange).isNull() 155 156 updateMonitor.onPackageChanged( 157 packageName = TEST_PACKAGE, 158 uid = UserHandle.getUid(/* userId = */ 100, /* appId = */ 10), 159 components = emptyArray() 160 ) 161 162 assertThat(packageChange).isInstanceOf(PackageChangeModel.Changed::class.java) 163 assertThat(packageChange?.packageName).isEqualTo(TEST_PACKAGE) 164 } 165 } 166 167 @Test 168 fun filtersOutUpdatesFromOtherUsers() = 169 with(kosmos) { 170 testScope.runTest { 171 val packageChange by collectLastValue(repository.packageChanged(USER_100)) 172 assertThat(packageChange).isNull() 173 174 updateMonitor.onPackageUpdateFinished( 175 packageName = TEST_PACKAGE, 176 uid = UserHandle.getUid(/* userId = */ 101, /* appId = */ 10) 177 ) 178 179 updateMonitor.onPackageAdded( 180 packageName = TEST_PACKAGE, 181 uid = UserHandle.getUid(/* userId = */ 99, /* appId = */ 10) 182 ) 183 184 assertThat(packageChange).isNull() 185 } 186 } 187 188 @Test 189 fun listenToUpdatesFromAllUsers() = 190 with(kosmos) { 191 testScope.runTest { 192 val packageChanges by collectValues(repository.packageChanged(UserHandle.ALL)) 193 assertThat(packageChanges).isEmpty() 194 195 updateMonitor.onPackageUpdateFinished( 196 packageName = TEST_PACKAGE, 197 uid = UserHandle.getUid(/* userId = */ 101, /* appId = */ 10) 198 ) 199 200 updateMonitor.onPackageAdded( 201 packageName = TEST_PACKAGE, 202 uid = UserHandle.getUid(/* userId = */ 99, /* appId = */ 10) 203 ) 204 205 assertThat(packageChanges).hasSize(2) 206 } 207 } 208 209 private companion object { 210 val USER_100 = UserHandle.of(100) 211 const val TEST_PACKAGE = "pkg.test" 212 } 213 } 214