diff options
| author | 2024-05-13 20:48:53 +0000 | |
|---|---|---|
| committer | 2024-05-13 20:48:53 +0000 | |
| commit | 25c04565081fd8643e04f88e004fc09ac1c73ff3 (patch) | |
| tree | 584db894c6a903ade28ee3636fd8ab8bcb06b8a6 /java/src | |
| parent | a487bbfeff7fcb4d0475e9d9aa4307539feacca2 (diff) | |
| parent | 78359ff22fae3934e513ba8c498af7e8a48992fc (diff) | |
Merge "Read image size from URI metadata" into main
Diffstat (limited to 'java/src')
9 files changed, 58 insertions, 5 deletions
diff --git a/java/src/com/android/intentresolver/contentpreview/FileInfo.kt b/java/src/com/android/intentresolver/contentpreview/FileInfo.kt index fe35365b..16a948df 100644 --- a/java/src/com/android/intentresolver/contentpreview/FileInfo.kt +++ b/java/src/com/android/intentresolver/contentpreview/FileInfo.kt @@ -22,8 +22,11 @@ class FileInfo private constructor(val uri: Uri, val previewUri: Uri?, val mimeT @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) class Builder(val uri: Uri) { var previewUri: Uri? = null + @Synchronized get private set + var mimeType: String? = null + @Synchronized get private set @Synchronized fun withPreviewUri(uri: Uri?): Builder = apply { previewUri = uri } diff --git a/java/src/com/android/intentresolver/contentpreview/UriMetadataReader.kt b/java/src/com/android/intentresolver/contentpreview/UriMetadataReader.kt index b5361889..4e403c22 100644 --- a/java/src/com/android/intentresolver/contentpreview/UriMetadataReader.kt +++ b/java/src/com/android/intentresolver/contentpreview/UriMetadataReader.kt @@ -20,6 +20,8 @@ import android.content.ContentInterface import android.media.MediaMetadata import android.net.Uri import android.provider.DocumentsContract +import android.provider.MediaStore.MediaColumns +import android.util.Size import dagger.Binds import dagger.Module import dagger.Provides @@ -29,6 +31,7 @@ import javax.inject.Inject fun interface UriMetadataReader { fun getMetadata(uri: Uri): FileInfo + fun readPreviewSize(uri: Uri): Size? = null } class UriMetadataReaderImpl @@ -56,6 +59,8 @@ constructor( return builder.build() } + override fun readPreviewSize(uri: Uri): Size? = contentResolver.readPreviewSize(uri) + private fun ContentInterface.supportsImageType(uri: Uri): Boolean = getStreamTypesSafe(uri).firstOrNull { typeClassifier.isImageType(it) } != null @@ -73,6 +78,15 @@ constructor( null } } + + private fun ContentInterface.readPreviewSize(uri: Uri): Size? = + querySafe(uri, arrayOf(MediaColumns.WIDTH, MediaColumns.HEIGHT))?.use { cursor -> + if (cursor.moveToFirst()) { + cursor.readSize() + } else { + null + } + } } @Module diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractor.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractor.kt index c7d29a72..97b087e1 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractor.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractor.kt @@ -242,10 +242,14 @@ constructor( ): PreviewModel = unclaimedRecords.remove(row.uri)?.second ?: uriMetadataReader.getMetadata(row.uri).let { metadata -> + val size = + row.previewSize + ?: metadata.previewUri?.let { uriMetadataReader.readPreviewSize(it) } PreviewModel( uri = row.uri, previewUri = metadata.previewUri, mimeType = metadata.mimeType, + aspectRatio = size.aspectRatioOrDefault(1f), ) } diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractor.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractor.kt index c87504e1..80cd03d9 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractor.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractor.kt @@ -65,6 +65,11 @@ constructor( uri = uri, previewUri = metadata.previewUri, mimeType = metadata.mimeType, + aspectRatio = + metadata.previewUri?.let { + uriMetadataReader.readPreviewSize(it).aspectRatioOrDefault(1f) + } + ?: 1f, ) } .toSet() diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SizeExtensions.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SizeExtensions.kt new file mode 100644 index 00000000..4cf10414 --- /dev/null +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SizeExtensions.kt @@ -0,0 +1,26 @@ +/* + * 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.payloadtoggle.domain.interactor + +import android.util.Size + +internal fun Size?.aspectRatioOrDefault(default: Float): Float = + when { + this == null -> default + width >= 0 && height > 0 -> width.toFloat() / height.toFloat() + else -> default + } diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/shared/model/PreviewModel.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/shared/model/PreviewModel.kt index 6b805391..85c70004 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/shared/model/PreviewModel.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/shared/model/PreviewModel.kt @@ -26,4 +26,5 @@ data class PreviewModel( val previewUri: Uri? = uri, /** Mimetype for the data [uri] points to. */ val mimeType: String?, + val aspectRatio: Float = 1f, ) diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt index 0a431c2a..85ad6ab3 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt @@ -115,11 +115,9 @@ private fun ShareouselCard(viewModel: ShareouselPreviewViewModel) { val scope = rememberCoroutineScope() ShareouselCard( image = { + // TODO: max ratio is actually equal to the viewport ratio + val aspectRatio = viewModel.aspectRatio.coerceIn(MIN_ASPECT_RATIO, MAX_ASPECT_RATIO) bitmap?.let { bitmap -> - val aspectRatio = - (bitmap.width.toFloat() / bitmap.height.toFloat()) - // TODO: max ratio is actually equal to the viewport ratio - .coerceIn(MIN_ASPECT_RATIO, MAX_ASPECT_RATIO) Image( bitmap = bitmap.asImageBitmap(), contentDescription = null, @@ -129,7 +127,7 @@ private fun ShareouselCard(viewModel: ShareouselPreviewViewModel) { } ?: run { // TODO: look at ScrollableImagePreviewView.setLoading() - Box(modifier = Modifier.fillMaxHeight().aspectRatio(2f / 5f)) + Box(modifier = Modifier.fillMaxHeight().aspectRatio(aspectRatio)) } }, contentType = contentType, diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt index a245b3e3..9827fcd4 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt @@ -29,6 +29,7 @@ data class ShareouselPreviewViewModel( val isSelected: Flow<Boolean>, /** Sets whether this preview has been selected by the user. */ val setSelected: suspend (Boolean) -> Unit, + val aspectRatio: Float, ) /** Type of the content being previewed. */ diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt index cf118934..8b2dd818 100644 --- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt +++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt @@ -117,6 +117,7 @@ object ShareouselViewModelModule { contentType = flowOf(ContentType.Image), // TODO: convert from metadata isSelected = previewInteractor.isSelected, setSelected = previewInteractor::setSelected, + aspectRatio = key.aspectRatio, ) }, ) |