blob: 2a729bf8b1efe57353c029df9cc5176edbe7c844 [file] [log] [blame]
package com.android.sharetest
import android.content.ContentProvider
import android.content.ContentValues
import android.content.res.AssetFileDescriptor
import android.database.Cursor
import android.database.MatrixCursor
import android.net.Uri
import android.os.Bundle
import android.os.ParcelFileDescriptor
import android.os.SystemClock
import android.provider.MediaStore
import android.util.Size
class ImageContentProvider : ContentProvider() {
override fun onCreate(): Boolean = true
override fun query(
uri: Uri,
projection: Array<String>?,
selection: String?,
selectionArgs: Array<String>?,
sortOrder: String?,
): Cursor? {
SystemClock.sleep(getLatencyMs(queryLatency))
val includeSize = runCatching {
uri.getQueryParameter(PARAM_SIZE_META).toBoolean()
}.getOrDefault(true)
if (!includeSize) return null
val size = getImageSize(uri) ?: return null
return MatrixCursor(
arrayOf(
MediaStore.MediaColumns.WIDTH,
MediaStore.MediaColumns.HEIGHT
)
).apply {
addRow(arrayOf(size.width, size.height))
}
}
override fun getType(uri: Uri): String? {
Thread.sleep(getLatencyMs(getTypeLatency))
return uri.getQueryParameter(PARAM_TYPE) ?: getTypeFromUri(uri)
}
override fun getStreamTypes(uri: Uri, mimeTypeFilter: String): Array<String>? {
val list = ArrayList<String>(2)
uri.getQueryParameter(PARAM_TYPE)?.let { list.add(it) }
getTypeFromUri(uri)?.let { list.add(it) }
return if (list.isEmpty()) {
super.getStreamTypes(uri, mimeTypeFilter)
} else {
list.toArray(emptyArray())
}
}
private fun getTypeFromUri(uri: Uri): String? {
if (uri.lastPathSegment?.endsWith("png", true) == true) {
return "image/png"
}
if (uri.lastPathSegment?.endsWith("jpg", true) == true) {
return "image/jpg"
}
return null
}
override fun insert(uri: Uri, values: ContentValues?): Uri? = null
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int = 0
override fun update(
uri: Uri,
values: ContentValues?,
selection: String?,
selectionArgs: Array<String>?,
): Int = 0
override fun openTypedAssetFile(
uri: Uri,
mimeTypeFilter: String,
opts: Bundle?,
): AssetFileDescriptor? {
return openAssetFile(uri, "r")
}
override fun openAssetFile(uri: Uri, mode: String): AssetFileDescriptor? {
Thread.sleep(getLatencyMs(openLatency))
if (shouldFailOpen()) {
return null
}
return uri.lastPathSegment?.let { context?.assets?.openFd(it) }
}
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? =
openAssetFile(uri, mode)?.parcelFileDescriptor
private fun shouldFailOpen() = getRandomFailure(openFailureRate)
companion object {
private val sizeMap = mapOf(
"img1.jpg" to Size(1944, 2592),
"img2.jpg" to Size(2368, 3200),
"img3.jpg" to Size(3200, 2368),
"img4.jpg" to Size(4032, 3024),
"img5.jpg" to Size(2448, 3264),
"img6.jpg" to Size(4032, 3024),
"img7.jpg" to Size(3024, 4032),
"img8.jpg" to Size(1600, 1200),
)
fun makeItemUri(idx: Int, mimeType: String, includeSize: Boolean): Uri =
Uri.parse("${URI_PREFIX}img${(idx % IMAGE_COUNT) + 1}.jpg")
.buildUpon()
.appendQueryParameter(PARAM_TYPE, mimeType)
.appendQueryParameter(PARAM_SIZE_META, includeSize.toString())
.appendQueryParameter("index", idx.toString())
.build()
fun getImageSize(uri: Uri): Size? {
val name = uri.lastPathSegment ?: return null
return sizeMap[name]
}
const val IMAGE_COUNT = 8
const val URI_PREFIX = "content://com.android.sharetest.provider/"
const val PARAM_TYPE = "type"
const val PARAM_SIZE_META = "ismeta"
val ICON_URI: Uri = Uri.parse("${URI_PREFIX}letter_a.png")
var getTypeLatency = 0L
var openLatency = 0L
var openFailureRate = 0f
var queryLatency = 0L
}
}