From d4d7e961cb7a21e02a40168e3911d69279d4ce1b Mon Sep 17 00:00:00 2001 From: Andrey Epin Date: Thu, 22 Feb 2024 10:23:37 -0800 Subject: Make ImageLoader injectable Do not inject ImageLoader anywhere by v2 activity tests. Rename TestPreviewImageLoader to FakeImageLoader for naming consistency. Bug: 302691505 Test: atest IntentResolver-tests-activity Test: atest IntentResolver-tests-unit Change-Id: I5630664eab6c9546d5de19fa7410184138d15602 --- .../contentpreview/ImageLoaderModule.kt | 44 ++++++++++++++++++++++ .../contentpreview/ImagePreviewImageLoader.kt | 34 +++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 java/src/com/android/intentresolver/contentpreview/ImageLoaderModule.kt (limited to 'java') diff --git a/java/src/com/android/intentresolver/contentpreview/ImageLoaderModule.kt b/java/src/com/android/intentresolver/contentpreview/ImageLoaderModule.kt new file mode 100644 index 00000000..b861a24a --- /dev/null +++ b/java/src/com/android/intentresolver/contentpreview/ImageLoaderModule.kt @@ -0,0 +1,44 @@ +/* + * Copyright 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.intentresolver.contentpreview + +import android.content.res.Resources +import com.android.intentresolver.R +import com.android.intentresolver.inject.ApplicationOwned +import dagger.Binds +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ActivityRetainedComponent +import dagger.hilt.android.scopes.ActivityRetainedScoped + +@Module +@InstallIn(ActivityRetainedComponent::class) +interface ImageLoaderModule { + @Binds + @ActivityRetainedScoped + fun imageLoader(previewImageLoader: ImagePreviewImageLoader): ImageLoader + + companion object { + @Provides + @ThumbnailSize + fun thumbnailSize(@ApplicationOwned resources: Resources): Int = + resources.getDimensionPixelSize(R.dimen.chooser_preview_image_max_dimen) + + @Provides @PreviewCacheSize fun cacheSize() = 16 + } +} diff --git a/java/src/com/android/intentresolver/contentpreview/ImagePreviewImageLoader.kt b/java/src/com/android/intentresolver/contentpreview/ImagePreviewImageLoader.kt index 572ccf0b..fab7203e 100644 --- a/java/src/com/android/intentresolver/contentpreview/ImagePreviewImageLoader.kt +++ b/java/src/com/android/intentresolver/contentpreview/ImagePreviewImageLoader.kt @@ -24,17 +24,31 @@ import android.util.Size import androidx.annotation.GuardedBy import androidx.annotation.VisibleForTesting import androidx.collection.LruCache +import com.android.intentresolver.inject.Background import java.util.function.Consumer +import javax.inject.Inject +import javax.inject.Qualifier import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Semaphore private const val TAG = "ImagePreviewImageLoader" +@Qualifier @MustBeDocumented @Retention(AnnotationRetention.BINARY) annotation class ThumbnailSize + +@Qualifier +@MustBeDocumented +@Retention(AnnotationRetention.BINARY) +annotation class PreviewCacheSize + /** * Implements preview image loading for the content preview UI. Provides requests deduplication, * image caching, and a limit on the number of parallel loadings. @@ -52,6 +66,26 @@ constructor( private val contentResolverSemaphore: Semaphore, ) : ImageLoader { + @Inject + constructor( + @Background dispatcher: CoroutineDispatcher, + @ThumbnailSize thumbnailSize: Int, + contentResolver: ContentResolver, + @PreviewCacheSize cacheSize: Int, + ) : this( + CoroutineScope( + SupervisorJob() + + dispatcher + + CoroutineExceptionHandler { _, exception -> + Log.w(TAG, "Uncaught exception in ImageLoader", exception) + } + + CoroutineName("ImageLoader") + ), + thumbnailSize, + contentResolver, + cacheSize, + ) + constructor( scope: CoroutineScope, thumbnailSize: Int, -- cgit v1.2.3-59-g8ed1b