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) { override fun fetchSingle(context: Context, uri: Uri, sourceMimeType: String?, callback: ImageOpCallback) {
var found = false
val fetched = arrayListOf<FieldMap>()
val id = uri.tryParseId() val id = uri.tryParseId()
val onSuccess = fun(entry: FieldMap) { val onSuccess = fun(entry: FieldMap) {
entry["uri"] = uri.toString() entry["uri"] = uri.toString()
callback.onSuccess(entry) fetched.add(entry)
} }
val alwaysValid = { _: Int, _: Int -> true } val alwaysValid = { _: Int, _: Int -> true }
if (id != null) { if (id != null) {
if (sourceMimeType == null || isImage(sourceMimeType)) { if (!found && (sourceMimeType == null || isImage(sourceMimeType))) {
val contentUri = ContentUris.withAppendedId(IMAGE_CONTENT_URI, id) 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) 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") // 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 // without an equivalent image/video if it is shared from a file browser
// but the file is not publicly visible // 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")) callback.onFailure(Exception("failed to fetch entry at uri=$uri"))
} }
}
fun checkObsoleteContentIds(context: Context, knownContentIds: List<Int>): List<Int> { fun checkObsoleteContentIds(context: Context, knownContentIds: List<Int>): List<Int> {
val foundContentIds = ArrayList<Int>() val foundContentIds = ArrayList<Int>()