summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Matt Casey <mrcasey@google.com> 2024-05-13 20:48:53 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-05-13 20:48:53 +0000
commit25c04565081fd8643e04f88e004fc09ac1c73ff3 (patch)
tree584db894c6a903ade28ee3636fd8ab8bcb06b8a6 /java/src
parenta487bbfeff7fcb4d0475e9d9aa4307539feacca2 (diff)
parent78359ff22fae3934e513ba8c498af7e8a48992fc (diff)
Merge "Read image size from URI metadata" into main
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/intentresolver/contentpreview/FileInfo.kt3
-rw-r--r--java/src/com/android/intentresolver/contentpreview/UriMetadataReader.kt14
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/CursorPreviewsInteractor.kt4
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/FetchPreviewsInteractor.kt5
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/domain/interactor/SizeExtensions.kt26
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/shared/model/PreviewModel.kt1
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt8
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselPreviewViewModel.kt1
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/viewmodel/ShareouselViewModel.kt1
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,
)
},
)