From 78359ff22fae3934e513ba8c498af7e8a48992fc Mon Sep 17 00:00:00 2001 From: Andrey Epin Date: Wed, 8 May 2024 16:30:50 -0700 Subject: Read image size from URI metadata Read preview sizes from both URI metdata, and the additional content proivider response (the latter gets priority, when present); use them to set aspect ratio for the item preview. If the size is missing, fallback to default aspect ratio, 1:1. Bug: 339679442 Test: atest IntentResolver-tests-unit Test: manual testing with ShareTest app Change-Id: Ia6072620a79b5df0b4b4bc9ebd11fb3961cb18a6 --- .../interactor/CursorPreviewsInteractorTest.kt | 107 +++++++++++++-------- .../interactor/FetchPreviewsInteractorTest.kt | 60 +++++++----- 2 files changed, 105 insertions(+), 62 deletions(-) (limited to 'tests') diff --git a/tests/unit/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractorTest.kt b/tests/unit/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractorTest.kt index 9b786b74..ff699373 100644 --- a/tests/unit/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractorTest.kt +++ b/tests/unit/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractorTest.kt @@ -20,12 +20,16 @@ package com.android.intentresolver.contentpreview.payloadtoggle.domain.interacto import android.database.MatrixCursor import android.net.Uri +import android.provider.MediaStore.MediaColumns.HEIGHT +import android.provider.MediaStore.MediaColumns.WIDTH +import android.util.Size import androidx.core.os.bundleOf import com.android.intentresolver.contentpreview.FileInfo import com.android.intentresolver.contentpreview.UriMetadataReader import com.android.intentresolver.contentpreview.payloadtoggle.data.repository.cursorPreviewsRepository import com.android.intentresolver.contentpreview.payloadtoggle.domain.model.CursorRow import com.android.intentresolver.contentpreview.payloadtoggle.shared.model.PreviewModel +import com.android.intentresolver.contentpreview.readSize import com.android.intentresolver.contentpreview.uriMetadataReader import com.android.intentresolver.util.KosmosTestScope import com.android.intentresolver.util.cursor.CursorView @@ -46,21 +50,32 @@ class CursorPreviewsInteractorTest { cursorStartPosition: Int = cursor.count() / 2, pageSize: Int = 16, maxLoadedPages: Int = 3, + cursorSizes: Map = emptyMap(), + metadatSizes: Map = emptyMap(), block: KosmosTestScope.(TestDeps) -> Unit, ) { + val metadataUriToSize = metadatSizes.mapKeys { uri(it.key) } with(Kosmos()) { this.focusedItemIndex = focusedItemIndex this.pageSize = pageSize this.maxLoadedPages = maxLoadedPages - uriMetadataReader = UriMetadataReader { - FileInfo.Builder(it).withPreviewUri(it).withMimeType("image/bitmap").build() - } + uriMetadataReader = + object : UriMetadataReader { + override fun getMetadata(uri: Uri): FileInfo = + FileInfo.Builder(uri) + .withPreviewUri(uri) + .withMimeType("image/bitmap") + .build() + + override fun readPreviewSize(uri: Uri): Size? = metadataUriToSize[uri] + } runTest { block( TestDeps( initialSelection, cursor, cursorStartPosition, + cursorSizes, ) ) } @@ -71,54 +86,66 @@ class CursorPreviewsInteractorTest { initialSelectionRange: Iterable, private val cursorRange: Iterable, private val cursorStartPosition: Int, + private val cursorSizes: Map, ) { val cursor: CursorView = - MatrixCursor(arrayOf("uri")) + MatrixCursor(arrayOf("uri", WIDTH, HEIGHT)) .apply { extras = bundleOf("position" to cursorStartPosition) for (i in cursorRange) { - newRow().add("uri", uri(i).toString()) + val size = cursorSizes[i] + addRow( + arrayOf( + uri(i).toString(), + size?.width?.toString(), + size?.height?.toString(), + ) + ) } } - .viewBy { getString(0)?.let { uriStr -> CursorRow(Uri.parse(uriStr), null) } } + .viewBy { getString(0)?.let { uriStr -> CursorRow(Uri.parse(uriStr), readSize()) } } val initialPreviews: List = initialSelectionRange.map { i -> PreviewModel(uri = uri(i), mimeType = "image/bitmap") } - - private fun uri(index: Int) = Uri.fromParts("scheme$index", "ssp$index", "fragment$index") } @Test - fun initialCursorLoad() = runTestWithDeps { deps -> - backgroundScope.launch { - cursorPreviewsInteractor.launch(deps.cursor, deps.initialPreviews) - } - runCurrent() + fun initialCursorLoad() = + runTestWithDeps( + cursorSizes = mapOf(0 to (200 x 100)), + metadatSizes = mapOf(0 to (300 x 100), 3 to (400 x 100)) + ) { deps -> + backgroundScope.launch { + cursorPreviewsInteractor.launch(deps.cursor, deps.initialPreviews) + } + runCurrent() - assertThat(cursorPreviewsRepository.previewsModel.value).isNotNull() - assertThat(cursorPreviewsRepository.previewsModel.value!!.startIdx).isEqualTo(0) - assertThat(cursorPreviewsRepository.previewsModel.value!!.loadMoreLeft).isNull() - assertThat(cursorPreviewsRepository.previewsModel.value!!.loadMoreRight).isNull() - assertThat(cursorPreviewsRepository.previewsModel.value!!.previewModels) - .containsExactly( - PreviewModel( - uri = Uri.fromParts("scheme0", "ssp0", "fragment0"), - mimeType = "image/bitmap" - ), - PreviewModel( - uri = Uri.fromParts("scheme1", "ssp1", "fragment1"), - mimeType = "image/bitmap" - ), - PreviewModel( - uri = Uri.fromParts("scheme2", "ssp2", "fragment2"), - mimeType = "image/bitmap" - ), - PreviewModel( - uri = Uri.fromParts("scheme3", "ssp3", "fragment3"), - mimeType = "image/bitmap" - ), - ) - .inOrder() - } + assertThat(cursorPreviewsRepository.previewsModel.value).isNotNull() + assertThat(cursorPreviewsRepository.previewsModel.value!!.startIdx).isEqualTo(0) + assertThat(cursorPreviewsRepository.previewsModel.value!!.loadMoreLeft).isNull() + assertThat(cursorPreviewsRepository.previewsModel.value!!.loadMoreRight).isNull() + assertThat(cursorPreviewsRepository.previewsModel.value!!.previewModels) + .containsExactly( + PreviewModel( + uri = Uri.fromParts("scheme0", "ssp0", "fragment0"), + mimeType = "image/bitmap", + aspectRatio = 2f, + ), + PreviewModel( + uri = Uri.fromParts("scheme1", "ssp1", "fragment1"), + mimeType = "image/bitmap" + ), + PreviewModel( + uri = Uri.fromParts("scheme2", "ssp2", "fragment2"), + mimeType = "image/bitmap" + ), + PreviewModel( + uri = Uri.fromParts("scheme3", "ssp3", "fragment3"), + mimeType = "image/bitmap", + aspectRatio = 4f, + ), + ) + .inOrder() + } @Test fun loadMoreLeft_evictRight() = @@ -294,3 +321,7 @@ class CursorPreviewsInteractorTest { assertThat(cursorPreviewsRepository.previewsModel.value!!.loadMoreLeft).isNull() } } + +private fun uri(index: Int) = Uri.fromParts("scheme$index", "ssp$index", "fragment$index") + +private infix fun Int.x(height: Int) = Size(this, height) diff --git a/tests/unit/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractorTest.kt b/tests/unit/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractorTest.kt index c9f71f49..735bcb1d 100644 --- a/tests/unit/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractorTest.kt +++ b/tests/unit/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractorTest.kt @@ -20,6 +20,7 @@ package com.android.intentresolver.contentpreview.payloadtoggle.domain.interacto import android.database.MatrixCursor import android.net.Uri +import android.util.Size import androidx.core.os.bundleOf import com.android.intentresolver.contentpreview.FileInfo import com.android.intentresolver.contentpreview.UriMetadataReader @@ -53,17 +54,26 @@ class FetchPreviewsInteractorTest { cursorStartPosition: Int = cursor.count() / 2, pageSize: Int = 16, maxLoadedPages: Int = 3, + previewSizes: Map = emptyMap(), block: KosmosTestScope.() -> Unit, ) { + val previewUriToSize = previewSizes.mapKeys { uri(it.key) } with(Kosmos()) { fakeCursorResolver = FakeCursorResolver(cursorRange = cursor, cursorStartPosition = cursorStartPosition) payloadToggleCursorResolver = fakeCursorResolver contentUris = initialSelection.map { uri(it) } this.focusedItemIndex = focusedItemIndex - uriMetadataReader = UriMetadataReader { - FileInfo.Builder(it).withPreviewUri(it).withMimeType("image/bitmap").build() - } + uriMetadataReader = + object : UriMetadataReader { + override fun getMetadata(uri: Uri): FileInfo = + FileInfo.Builder(uri) + .withPreviewUri(uri) + .withMimeType("image/bitmap") + .build() + + override fun readPreviewSize(uri: Uri): Size? = previewUriToSize[uri] + } this.pageSize = pageSize this.maxLoadedPages = maxLoadedPages runKosmosTest { block() } @@ -94,30 +104,32 @@ class FetchPreviewsInteractorTest { } @Test - fun setsInitialPreviews() = runTest { - backgroundScope.launch { fetchPreviewsInteractor.activate() } - runCurrent() + fun setsInitialPreviews() = + runTest(previewSizes = mapOf(1 to Size(100, 50))) { + backgroundScope.launch { fetchPreviewsInteractor.activate() } + runCurrent() - assertThat(cursorPreviewsRepository.previewsModel.value) - .isEqualTo( - PreviewsModel( - previewModels = - setOf( - PreviewModel( - uri = Uri.fromParts("scheme1", "ssp1", "fragment1"), - mimeType = "image/bitmap", - ), - PreviewModel( - uri = Uri.fromParts("scheme2", "ssp2", "fragment2"), - mimeType = "image/bitmap", + assertThat(cursorPreviewsRepository.previewsModel.value) + .isEqualTo( + PreviewsModel( + previewModels = + setOf( + PreviewModel( + uri = Uri.fromParts("scheme1", "ssp1", "fragment1"), + mimeType = "image/bitmap", + aspectRatio = 2f + ), + PreviewModel( + uri = Uri.fromParts("scheme2", "ssp2", "fragment2"), + mimeType = "image/bitmap", + ), ), - ), - startIdx = 1, - loadMoreLeft = null, - loadMoreRight = null, + startIdx = 1, + loadMoreLeft = null, + loadMoreRight = null, + ) ) - ) - } + } @Test fun lookupCursorFromContentResolver() = runTest { -- cgit v1.2.3-59-g8ed1b