Loading packages/SystemUI/multivalentTests/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureIconRepositoryImplTest.kt +5 −110 Original line number Diff line number Diff line Loading @@ -33,12 +33,9 @@ import com.android.launcher3.icons.FastBitmapDrawable import com.android.launcher3.icons.IconFactory import com.android.launcher3.util.UserIconInfo import com.android.systemui.SysuiTestCase import com.android.systemui.kosmos.backgroundScope import com.android.systemui.kosmos.currentValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testDispatcher import com.android.systemui.testKosmosNew import com.android.systemui.unfold.util.fakeDeviceStateManager import com.google.common.truth.Truth.assertThat import javax.inject.Provider import org.junit.Test Loading Loading @@ -96,7 +93,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { // Arrange val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading @@ -117,7 +113,8 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verify(mockIconFactory).createBadgedIconBitmap(same(fakeDrawable), any()) verify(mockIconFactory).close() assertThat(result?.sameAs(fakeBadgedBitmap)).isTrue() assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()?.sameAs(fakeBadgedBitmap)).isTrue() } @Test Loading @@ -126,7 +123,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { // Arrange val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading @@ -147,7 +143,8 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verifyNoInteractions(mockIconFactory) assertThat(result?.sameAs(fakeUnbadgedBitmap)).isTrue() assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()?.sameAs(fakeUnbadgedBitmap)).isTrue() } @Test Loading @@ -157,7 +154,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { packageManagerWrapper.stub { on { getActivityInfo(any(), any()) } doReturn null } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading @@ -177,104 +173,7 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verifyNoInteractions(mockIconFactory) assertThat(result).isNull() } @Test fun iconFor_flowEmitsBadgedIcon() = kosmos.runTest { // Arrange val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, packageManagerWrapper = packageManagerWrapper, packageManager = packageManager, iconFactoryProvider = testIconFactoryProvider, ) // Act val flow = iconRepository.iconFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, ) val result = currentValue(flow) // Assert verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verify(mockIconFactory).createBadgedIconBitmap(same(fakeDrawable), any()) verify(mockIconFactory).close() assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()?.sameAs(fakeBadgedBitmap)).isTrue() } @Test fun iconFor_unbadged_flowEmitsUnbadgedIcon() = kosmos.runTest { // Arrange val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, packageManagerWrapper = packageManagerWrapper, packageManager = packageManager, iconFactoryProvider = testIconFactoryProvider, ) // Act val flow = iconRepository.iconFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, badged = false, ) val result = currentValue(flow) // Assert verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verifyNoInteractions(mockIconFactory) assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()?.sameAs(fakeUnbadgedBitmap)).isTrue() } @Test fun iconFor_couldNotFindActivity_flowEmitsFailure() = kosmos.runTest { // Arrange packageManagerWrapper.stub { on { getActivityInfo(any(), any()) } doReturn null } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, packageManagerWrapper = packageManagerWrapper, packageManager = packageManager, iconFactoryProvider = testIconFactoryProvider, ) this.fakeDeviceStateManager // Act val flow = iconRepository.iconFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, ) val result = currentValue(flow) // Assert verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verifyNoInteractions(mockIconFactory) assertThat(result?.isFailure).isTrue() assertThat(result.isFailure).isTrue() } @Test Loading @@ -293,7 +192,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading Loading @@ -325,7 +223,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading Loading @@ -357,7 +254,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading Loading @@ -389,7 +285,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading packages/SystemUI/multivalentTests/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureLabelRepositoryImplTest.kt +5 −103 Original line number Diff line number Diff line Loading @@ -24,8 +24,6 @@ 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.kosmos.backgroundScope import com.android.systemui.kosmos.currentValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testDispatcher import com.android.systemui.testKosmosNew Loading Loading @@ -66,7 +64,6 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager, ) Loading @@ -86,7 +83,8 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { eq(123), ) verify(packageManager).getUserBadgedLabel(any(), eq(UserHandle(123))) assertThat(result).isEqualTo("TestBadgedLabel") assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()).isEqualTo("TestBadgedLabel") } @Test Loading @@ -95,7 +93,6 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager, ) Loading @@ -116,7 +113,8 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { eq(123), ) verify(packageManager, never()).getUserBadgedLabel(any(), any()) assertThat(result).isEqualTo("TestUnbadgedLabel") assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()).isEqualTo("TestUnbadgedLabel") } @Test Loading @@ -125,7 +123,6 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager.stub { Loading @@ -147,101 +144,6 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { ) // Assert assertThat(result).isNull() } @Test fun LabelFor_flowEmitsBadgedLabel() = kosmos.runTest { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager, ) // Act val flow = labelRepository.labelFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, ) val result = currentValue(flow) // Assert verify(packageManager) .getApplicationInfoAsUser( eq("TestPackage"), argThat<PackageManager.ApplicationInfoFlags> { value == 0L }, eq(123), ) verify(packageManager).getUserBadgedLabel(any(), eq(UserHandle(123))) assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()).isEqualTo("TestBadgedLabel") } @Test fun LabelFor_unbadged_flowEmitsUnbadgedLabel() = kosmos.runTest { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager, ) // Act val flow = labelRepository.labelFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, badged = false, ) val result = currentValue(flow) // Assert verify(packageManager) .getApplicationInfoAsUser( eq("TestPackage"), argThat<PackageManager.ApplicationInfoFlags> { value == 0L }, eq(123), ) verify(packageManager, never()).getUserBadgedLabel(any(), any()) assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()).isEqualTo("TestUnbadgedLabel") } @Test fun LabelFor_appNotFound_flowEmitsFailure() = kosmos.runTest { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager.stub { on { getApplicationInfoAsUser( any<String>(), any<PackageManager.ApplicationInfoFlags>(), any<Int>(), ) } doThrow PackageManager.NameNotFoundException() }, ) // Act val flow = labelRepository.labelFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, ) val result = currentValue(flow) // Assert assertThat(result?.isFailure).isTrue() assertThat(result.isFailure).isTrue() } } packages/SystemUI/multivalentTests/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureThumbnailRepositoryImplTest.kt +3 −54 Original line number Diff line number Diff line Loading @@ -20,8 +20,6 @@ import androidx.core.graphics.createBitmap import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.kosmos.backgroundScope import com.android.systemui.kosmos.currentValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testDispatcher import com.android.systemui.shared.recents.model.ThumbnailData Loading Loading @@ -50,7 +48,6 @@ class ScreenCaptureThumbnailRepositoryImplTest : SysuiTestCase() { // Arrange val thumbnailRepository = ScreenCaptureThumbnailRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, activityManager = activityManagerWrapper.stub { Loading @@ -64,7 +61,8 @@ class ScreenCaptureThumbnailRepositoryImplTest : SysuiTestCase() { // Assert verify(activityManagerWrapper).takeTaskThumbnail(eq(123)) assertThat(result?.sameAs(fakeThumbnail)).isTrue() assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()?.sameAs(fakeThumbnail)).isTrue() } @Test Loading @@ -73,7 +71,6 @@ class ScreenCaptureThumbnailRepositoryImplTest : SysuiTestCase() { // Arrange val thumbnailRepository = ScreenCaptureThumbnailRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, activityManager = activityManagerWrapper.stub { Loading @@ -86,54 +83,6 @@ class ScreenCaptureThumbnailRepositoryImplTest : SysuiTestCase() { // Assert verify(activityManagerWrapper).takeTaskThumbnail(eq(123)) assertThat(result).isNull() } @Test fun thumbnailFor_flowEmitsNewThumbnail() = kosmos.runTest { // Arrange val thumbnailRepository = ScreenCaptureThumbnailRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, activityManager = activityManagerWrapper.stub { on { takeTaskThumbnail(any()) } doReturn ThumbnailData(thumbnail = fakeThumbnail) }, ) // Act val flow = thumbnailRepository.thumbnailFor(123) val result = currentValue(flow) // Assert verify(activityManagerWrapper).takeTaskThumbnail(eq(123)) assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()?.sameAs(fakeThumbnail)).isTrue() } @Test fun thumbnailFor_failsToTakeThumbnail_flowEmitsFailure() = kosmos.runTest { // Arrange val thumbnailRepository = ScreenCaptureThumbnailRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, activityManager = activityManagerWrapper.stub { on { takeTaskThumbnail(any()) } doReturn ThumbnailData(thumbnail = null) }, ) // Act val flow = thumbnailRepository.thumbnailFor(123) val result = currentValue(flow) // Assert verify(activityManagerWrapper).takeTaskThumbnail(eq(123)) assertThat(result?.isFailure).isTrue() assertThat(result.isFailure).isTrue() } } packages/SystemUI/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureIconRepository.kt +17 −43 Original line number Diff line number Diff line Loading @@ -32,41 +32,29 @@ import com.android.launcher3.icons.IconFactory import com.android.launcher3.util.UserIconInfo import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.screencapture.common.ScreenCapture import com.android.systemui.screencapture.common.ScreenCaptureScope import com.android.systemui.shared.system.PackageManagerWrapper import javax.inject.Inject import javax.inject.Provider import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext /** Repository for app icons. */ interface ScreenCaptureIconRepository { /** Returns a flow that fetches an app icon. */ fun iconFor( component: ComponentName, @UserIdInt userId: Int, badged: Boolean = true, ): StateFlow<Result<Bitmap>?> /** Fetch app icon on background dispatcher. */ suspend fun loadIcon( component: ComponentName, @UserIdInt userId: Int, badged: Boolean = true, ): Bitmap? ): Result<Bitmap> } /** Default implementation of [ScreenCaptureIconRepository]. */ @ScreenCaptureScope class ScreenCaptureIconRepositoryImpl @Inject constructor( @ScreenCapture private val scope: CoroutineScope, @Background private val bgContext: CoroutineContext, private val context: Context, private val userManager: UserManager, Loading @@ -75,44 +63,30 @@ constructor( @ScreenCapture private val iconFactoryProvider: Provider<IconFactory>, ) : ScreenCaptureIconRepository { override fun iconFor( component: ComponentName, userId: Int, badged: Boolean, ): StateFlow<Result<Bitmap>?> = flow { val icon = loadIcon(component, userId, badged) if (icon == null) { emit( Result.failure( Exception( "Could not find icon for ${component.flattenToString()}, user $userId" ) ) ) } else { emit(Result.success(icon)) } } .stateIn(scope, SharingStarted.Eagerly, null) override suspend fun loadIcon( component: ComponentName, @UserIdInt userId: Int, badged: Boolean, ): Bitmap? = ): Result<Bitmap> = withContext(bgContext) { packageManagerWrapper .getActivityInfo(component, userId) ?.loadIcon(packageManager) ?.let { Result.success( if (badged) { badgeIcon(it, userId) } else { it } .toBitmap() ) } ?: Result.failure( IllegalStateException( "Could not find icon for ${component.flattenToString()}, user $userId" ) ) } private suspend fun badgeIcon(icon: Drawable, @UserIdInt userId: Int): Drawable { Loading packages/SystemUI/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureLabelRepository.kt +12 −44 Original line number Diff line number Diff line Loading @@ -22,69 +22,35 @@ import android.content.pm.PackageManager import android.os.UserHandle import android.util.Log import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.screencapture.common.ScreenCapture import com.android.systemui.screencapture.common.ScreenCaptureScope import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext /** Repository for fetching app labels */ interface ScreenCaptureLabelRepository { /** Returns a flow that fetches an app label. */ fun labelFor( component: ComponentName, @UserIdInt userId: Int, badged: Boolean = true, ): StateFlow<Result<CharSequence>?> /** Fetch app label on background dispatcher. */ suspend fun loadLabel( component: ComponentName, @UserIdInt userId: Int, badged: Boolean = true, ): CharSequence? ): Result<CharSequence> } /** Default implementation of [ScreenCaptureLabelRepository]. */ @ScreenCaptureScope class ScreenCaptureLabelRepositoryImpl @Inject constructor( @ScreenCapture private val scope: CoroutineScope, @Background private val bgContext: CoroutineContext, private val packageManager: PackageManager, ) : ScreenCaptureLabelRepository { override fun labelFor( component: ComponentName, userId: Int, badged: Boolean, ): StateFlow<Result<CharSequence>?> = flow { val label = loadLabel(component, userId, badged) if (label == null) { emit( Result.failure( Exception( "Could not find label for ${component.flattenToString()}, user $userId" ) ) ) } else { emit(Result.success(label)) } } .stateIn(scope, SharingStarted.Eagerly, null) override suspend fun loadLabel( component: ComponentName, @UserIdInt userId: Int, badged: Boolean, ): CharSequence? = ): Result<CharSequence> = withContext(bgContext) { try { val label = Loading @@ -95,14 +61,16 @@ constructor( userId, ) .let { appInfo -> packageManager.getApplicationLabel(appInfo) } Result.success( if (badged) { packageManager.getUserBadgedLabel(label, UserHandle(userId)) } else { label } ) } catch (e: PackageManager.NameNotFoundException) { Log.e(TAG, "Unable to get application info", e) null Result.failure(e) } } } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureIconRepositoryImplTest.kt +5 −110 Original line number Diff line number Diff line Loading @@ -33,12 +33,9 @@ import com.android.launcher3.icons.FastBitmapDrawable import com.android.launcher3.icons.IconFactory import com.android.launcher3.util.UserIconInfo import com.android.systemui.SysuiTestCase import com.android.systemui.kosmos.backgroundScope import com.android.systemui.kosmos.currentValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testDispatcher import com.android.systemui.testKosmosNew import com.android.systemui.unfold.util.fakeDeviceStateManager import com.google.common.truth.Truth.assertThat import javax.inject.Provider import org.junit.Test Loading Loading @@ -96,7 +93,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { // Arrange val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading @@ -117,7 +113,8 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verify(mockIconFactory).createBadgedIconBitmap(same(fakeDrawable), any()) verify(mockIconFactory).close() assertThat(result?.sameAs(fakeBadgedBitmap)).isTrue() assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()?.sameAs(fakeBadgedBitmap)).isTrue() } @Test Loading @@ -126,7 +123,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { // Arrange val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading @@ -147,7 +143,8 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verifyNoInteractions(mockIconFactory) assertThat(result?.sameAs(fakeUnbadgedBitmap)).isTrue() assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()?.sameAs(fakeUnbadgedBitmap)).isTrue() } @Test Loading @@ -157,7 +154,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { packageManagerWrapper.stub { on { getActivityInfo(any(), any()) } doReturn null } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading @@ -177,104 +173,7 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verifyNoInteractions(mockIconFactory) assertThat(result).isNull() } @Test fun iconFor_flowEmitsBadgedIcon() = kosmos.runTest { // Arrange val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, packageManagerWrapper = packageManagerWrapper, packageManager = packageManager, iconFactoryProvider = testIconFactoryProvider, ) // Act val flow = iconRepository.iconFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, ) val result = currentValue(flow) // Assert verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verify(mockIconFactory).createBadgedIconBitmap(same(fakeDrawable), any()) verify(mockIconFactory).close() assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()?.sameAs(fakeBadgedBitmap)).isTrue() } @Test fun iconFor_unbadged_flowEmitsUnbadgedIcon() = kosmos.runTest { // Arrange val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, packageManagerWrapper = packageManagerWrapper, packageManager = packageManager, iconFactoryProvider = testIconFactoryProvider, ) // Act val flow = iconRepository.iconFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, badged = false, ) val result = currentValue(flow) // Assert verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verifyNoInteractions(mockIconFactory) assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()?.sameAs(fakeUnbadgedBitmap)).isTrue() } @Test fun iconFor_couldNotFindActivity_flowEmitsFailure() = kosmos.runTest { // Arrange packageManagerWrapper.stub { on { getActivityInfo(any(), any()) } doReturn null } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, packageManagerWrapper = packageManagerWrapper, packageManager = packageManager, iconFactoryProvider = testIconFactoryProvider, ) this.fakeDeviceStateManager // Act val flow = iconRepository.iconFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, ) val result = currentValue(flow) // Assert verify(packageManagerWrapper) .getActivityInfo(eq(ComponentName("TestPackage", "TestClass")), eq(123)) verifyNoInteractions(mockIconFactory) assertThat(result?.isFailure).isTrue() assertThat(result.isFailure).isTrue() } @Test Loading @@ -293,7 +192,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading Loading @@ -325,7 +223,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading Loading @@ -357,7 +254,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading Loading @@ -389,7 +285,6 @@ class ScreenCaptureIconRepositoryImplTest : SysuiTestCase() { } val iconRepository = ScreenCaptureIconRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, context = testableContext, userManager = userManager, Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureLabelRepositoryImplTest.kt +5 −103 Original line number Diff line number Diff line Loading @@ -24,8 +24,6 @@ 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.kosmos.backgroundScope import com.android.systemui.kosmos.currentValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testDispatcher import com.android.systemui.testKosmosNew Loading Loading @@ -66,7 +64,6 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager, ) Loading @@ -86,7 +83,8 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { eq(123), ) verify(packageManager).getUserBadgedLabel(any(), eq(UserHandle(123))) assertThat(result).isEqualTo("TestBadgedLabel") assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()).isEqualTo("TestBadgedLabel") } @Test Loading @@ -95,7 +93,6 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager, ) Loading @@ -116,7 +113,8 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { eq(123), ) verify(packageManager, never()).getUserBadgedLabel(any(), any()) assertThat(result).isEqualTo("TestUnbadgedLabel") assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()).isEqualTo("TestUnbadgedLabel") } @Test Loading @@ -125,7 +123,6 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager.stub { Loading @@ -147,101 +144,6 @@ class ScreenCaptureLabelRepositoryImplTest : SysuiTestCase() { ) // Assert assertThat(result).isNull() } @Test fun LabelFor_flowEmitsBadgedLabel() = kosmos.runTest { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager, ) // Act val flow = labelRepository.labelFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, ) val result = currentValue(flow) // Assert verify(packageManager) .getApplicationInfoAsUser( eq("TestPackage"), argThat<PackageManager.ApplicationInfoFlags> { value == 0L }, eq(123), ) verify(packageManager).getUserBadgedLabel(any(), eq(UserHandle(123))) assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()).isEqualTo("TestBadgedLabel") } @Test fun LabelFor_unbadged_flowEmitsUnbadgedLabel() = kosmos.runTest { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager, ) // Act val flow = labelRepository.labelFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, badged = false, ) val result = currentValue(flow) // Assert verify(packageManager) .getApplicationInfoAsUser( eq("TestPackage"), argThat<PackageManager.ApplicationInfoFlags> { value == 0L }, eq(123), ) verify(packageManager, never()).getUserBadgedLabel(any(), any()) assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()).isEqualTo("TestUnbadgedLabel") } @Test fun LabelFor_appNotFound_flowEmitsFailure() = kosmos.runTest { // Arrange val labelRepository = ScreenCaptureLabelRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, packageManager = packageManager.stub { on { getApplicationInfoAsUser( any<String>(), any<PackageManager.ApplicationInfoFlags>(), any<Int>(), ) } doThrow PackageManager.NameNotFoundException() }, ) // Act val flow = labelRepository.labelFor( component = ComponentName("TestPackage", "TestClass"), userId = 123, ) val result = currentValue(flow) // Assert assertThat(result?.isFailure).isTrue() assertThat(result.isFailure).isTrue() } }
packages/SystemUI/multivalentTests/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureThumbnailRepositoryImplTest.kt +3 −54 Original line number Diff line number Diff line Loading @@ -20,8 +20,6 @@ import androidx.core.graphics.createBitmap import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.kosmos.backgroundScope import com.android.systemui.kosmos.currentValue import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testDispatcher import com.android.systemui.shared.recents.model.ThumbnailData Loading Loading @@ -50,7 +48,6 @@ class ScreenCaptureThumbnailRepositoryImplTest : SysuiTestCase() { // Arrange val thumbnailRepository = ScreenCaptureThumbnailRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, activityManager = activityManagerWrapper.stub { Loading @@ -64,7 +61,8 @@ class ScreenCaptureThumbnailRepositoryImplTest : SysuiTestCase() { // Assert verify(activityManagerWrapper).takeTaskThumbnail(eq(123)) assertThat(result?.sameAs(fakeThumbnail)).isTrue() assertThat(result.isSuccess).isTrue() assertThat(result.getOrNull()?.sameAs(fakeThumbnail)).isTrue() } @Test Loading @@ -73,7 +71,6 @@ class ScreenCaptureThumbnailRepositoryImplTest : SysuiTestCase() { // Arrange val thumbnailRepository = ScreenCaptureThumbnailRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, activityManager = activityManagerWrapper.stub { Loading @@ -86,54 +83,6 @@ class ScreenCaptureThumbnailRepositoryImplTest : SysuiTestCase() { // Assert verify(activityManagerWrapper).takeTaskThumbnail(eq(123)) assertThat(result).isNull() } @Test fun thumbnailFor_flowEmitsNewThumbnail() = kosmos.runTest { // Arrange val thumbnailRepository = ScreenCaptureThumbnailRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, activityManager = activityManagerWrapper.stub { on { takeTaskThumbnail(any()) } doReturn ThumbnailData(thumbnail = fakeThumbnail) }, ) // Act val flow = thumbnailRepository.thumbnailFor(123) val result = currentValue(flow) // Assert verify(activityManagerWrapper).takeTaskThumbnail(eq(123)) assertThat(result?.isSuccess).isTrue() assertThat(result?.getOrNull()?.sameAs(fakeThumbnail)).isTrue() } @Test fun thumbnailFor_failsToTakeThumbnail_flowEmitsFailure() = kosmos.runTest { // Arrange val thumbnailRepository = ScreenCaptureThumbnailRepositoryImpl( scope = backgroundScope, bgContext = testDispatcher, activityManager = activityManagerWrapper.stub { on { takeTaskThumbnail(any()) } doReturn ThumbnailData(thumbnail = null) }, ) // Act val flow = thumbnailRepository.thumbnailFor(123) val result = currentValue(flow) // Assert verify(activityManagerWrapper).takeTaskThumbnail(eq(123)) assertThat(result?.isFailure).isTrue() assertThat(result.isFailure).isTrue() } }
packages/SystemUI/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureIconRepository.kt +17 −43 Original line number Diff line number Diff line Loading @@ -32,41 +32,29 @@ import com.android.launcher3.icons.IconFactory import com.android.launcher3.util.UserIconInfo import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.screencapture.common.ScreenCapture import com.android.systemui.screencapture.common.ScreenCaptureScope import com.android.systemui.shared.system.PackageManagerWrapper import javax.inject.Inject import javax.inject.Provider import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.async import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext /** Repository for app icons. */ interface ScreenCaptureIconRepository { /** Returns a flow that fetches an app icon. */ fun iconFor( component: ComponentName, @UserIdInt userId: Int, badged: Boolean = true, ): StateFlow<Result<Bitmap>?> /** Fetch app icon on background dispatcher. */ suspend fun loadIcon( component: ComponentName, @UserIdInt userId: Int, badged: Boolean = true, ): Bitmap? ): Result<Bitmap> } /** Default implementation of [ScreenCaptureIconRepository]. */ @ScreenCaptureScope class ScreenCaptureIconRepositoryImpl @Inject constructor( @ScreenCapture private val scope: CoroutineScope, @Background private val bgContext: CoroutineContext, private val context: Context, private val userManager: UserManager, Loading @@ -75,44 +63,30 @@ constructor( @ScreenCapture private val iconFactoryProvider: Provider<IconFactory>, ) : ScreenCaptureIconRepository { override fun iconFor( component: ComponentName, userId: Int, badged: Boolean, ): StateFlow<Result<Bitmap>?> = flow { val icon = loadIcon(component, userId, badged) if (icon == null) { emit( Result.failure( Exception( "Could not find icon for ${component.flattenToString()}, user $userId" ) ) ) } else { emit(Result.success(icon)) } } .stateIn(scope, SharingStarted.Eagerly, null) override suspend fun loadIcon( component: ComponentName, @UserIdInt userId: Int, badged: Boolean, ): Bitmap? = ): Result<Bitmap> = withContext(bgContext) { packageManagerWrapper .getActivityInfo(component, userId) ?.loadIcon(packageManager) ?.let { Result.success( if (badged) { badgeIcon(it, userId) } else { it } .toBitmap() ) } ?: Result.failure( IllegalStateException( "Could not find icon for ${component.flattenToString()}, user $userId" ) ) } private suspend fun badgeIcon(icon: Drawable, @UserIdInt userId: Int): Drawable { Loading
packages/SystemUI/src/com/android/systemui/screencapture/common/data/repository/ScreenCaptureLabelRepository.kt +12 −44 Original line number Diff line number Diff line Loading @@ -22,69 +22,35 @@ import android.content.pm.PackageManager import android.os.UserHandle import android.util.Log import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.screencapture.common.ScreenCapture import com.android.systemui.screencapture.common.ScreenCaptureScope import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext /** Repository for fetching app labels */ interface ScreenCaptureLabelRepository { /** Returns a flow that fetches an app label. */ fun labelFor( component: ComponentName, @UserIdInt userId: Int, badged: Boolean = true, ): StateFlow<Result<CharSequence>?> /** Fetch app label on background dispatcher. */ suspend fun loadLabel( component: ComponentName, @UserIdInt userId: Int, badged: Boolean = true, ): CharSequence? ): Result<CharSequence> } /** Default implementation of [ScreenCaptureLabelRepository]. */ @ScreenCaptureScope class ScreenCaptureLabelRepositoryImpl @Inject constructor( @ScreenCapture private val scope: CoroutineScope, @Background private val bgContext: CoroutineContext, private val packageManager: PackageManager, ) : ScreenCaptureLabelRepository { override fun labelFor( component: ComponentName, userId: Int, badged: Boolean, ): StateFlow<Result<CharSequence>?> = flow { val label = loadLabel(component, userId, badged) if (label == null) { emit( Result.failure( Exception( "Could not find label for ${component.flattenToString()}, user $userId" ) ) ) } else { emit(Result.success(label)) } } .stateIn(scope, SharingStarted.Eagerly, null) override suspend fun loadLabel( component: ComponentName, @UserIdInt userId: Int, badged: Boolean, ): CharSequence? = ): Result<CharSequence> = withContext(bgContext) { try { val label = Loading @@ -95,14 +61,16 @@ constructor( userId, ) .let { appInfo -> packageManager.getApplicationLabel(appInfo) } Result.success( if (badged) { packageManager.getUserBadgedLabel(label, UserHandle(userId)) } else { label } ) } catch (e: PackageManager.NameNotFoundException) { Log.e(TAG, "Unable to get application info", e) null Result.failure(e) } } } Loading