safer single fetch to prevent double success call

This commit is contained in:
Thibault Deckers 2021-09-11 10:40:19 +09:00
parent a59d9c47e5
commit c6a022ec4b

View file

@ -39,29 +39,41 @@ class MediaStoreImageProvider : ImageProvider() {
}
override fun fetchSingle(context: Context, uri: Uri, sourceMimeType: String?, callback: ImageOpCallback) {
var found = false
val fetched = arrayListOf<FieldMap>()
val id = uri.tryParseId()
val onSuccess = fun(entry: FieldMap) {
entry["uri"] = uri.toString()
callback.onSuccess(entry)
fetched.add(entry)
}
val alwaysValid = { _: Int, _: Int -> true }
if (id != null) {
if (sourceMimeType == null || isImage(sourceMimeType)) {
if (!found && (sourceMimeType == null || isImage(sourceMimeType))) {
val contentUri = ContentUris.withAppendedId(IMAGE_CONTENT_URI, id)
if (fetchFrom(context, alwaysValid, onSuccess, contentUri, IMAGE_PROJECTION)) return
found = fetchFrom(context, alwaysValid, onSuccess, contentUri, IMAGE_PROJECTION)
}
if (sourceMimeType == null || isVideo(sourceMimeType)) {
if (!found && (sourceMimeType == null || isVideo(sourceMimeType))) {
val contentUri = ContentUris.withAppendedId(VIDEO_CONTENT_URI, id)
if (fetchFrom(context, alwaysValid, onSuccess, contentUri, VIDEO_PROJECTION)) return
found = fetchFrom(context, alwaysValid, onSuccess, contentUri, VIDEO_PROJECTION)
}
}
if (!found) {
// the uri can be a file media URI (e.g. "content://0@media/external/file/30050")
// without an equivalent image/video if it is shared from a file browser
// but the file is not publicly visible
if (fetchFrom(context, alwaysValid, onSuccess, uri, BASE_PROJECTION, fileMimeType = sourceMimeType)) return
found = fetchFrom(context, alwaysValid, onSuccess, uri, BASE_PROJECTION, fileMimeType = sourceMimeType)
}
if (found && fetched.isNotEmpty()) {
if (fetched.size == 1) {
callback.onSuccess(fetched.first())
} else {
callback.onFailure(Exception("found ${fetched.size} entries at uri=$uri"))
}
} else {
callback.onFailure(Exception("failed to fetch entry at uri=$uri"))
}
}
fun checkObsoleteContentIds(context: Context, knownContentIds: List<Int>): List<Int> {
val foundContentIds = ArrayList<Int>()