1 package com.android.sharetest 2 3 import android.content.ContentProvider 4 import android.content.ContentValues 5 import android.content.res.AssetFileDescriptor 6 import android.database.Cursor 7 import android.database.MatrixCursor 8 import android.net.Uri 9 import android.os.Bundle 10 import android.os.ParcelFileDescriptor 11 import android.os.SystemClock 12 import android.provider.MediaStore 13 import android.util.Size 14 15 class ImageContentProvider : ContentProvider() { onCreatenull16 override fun onCreate(): Boolean = true 17 18 override fun query( 19 uri: Uri, 20 projection: Array<String>?, 21 selection: String?, 22 selectionArgs: Array<String>?, 23 sortOrder: String?, 24 ): Cursor? { 25 SystemClock.sleep(getLatencyMs(queryLatency)) 26 val includeSize = runCatching { 27 uri.getQueryParameter(PARAM_SIZE_META).toBoolean() 28 }.getOrDefault(true) 29 if (!includeSize) return null 30 val size = getImageSize(uri) ?: return null 31 return MatrixCursor( 32 arrayOf( 33 MediaStore.MediaColumns.WIDTH, 34 MediaStore.MediaColumns.HEIGHT 35 ) 36 ).apply { 37 addRow(arrayOf(size.width, size.height)) 38 } 39 } 40 getTypenull41 override fun getType(uri: Uri): String? { 42 Thread.sleep(getLatencyMs(getTypeLatency)) 43 return uri.getQueryParameter(PARAM_TYPE) ?: getTypeFromUri(uri) 44 } 45 getStreamTypesnull46 override fun getStreamTypes(uri: Uri, mimeTypeFilter: String): Array<String>? { 47 val list = ArrayList<String>(2) 48 uri.getQueryParameter(PARAM_TYPE)?.let { list.add(it) } 49 getTypeFromUri(uri)?.let { list.add(it) } 50 return if (list.isEmpty()) { 51 super.getStreamTypes(uri, mimeTypeFilter) 52 } else { 53 list.toArray(emptyArray()) 54 } 55 } 56 getTypeFromUrinull57 private fun getTypeFromUri(uri: Uri): String? { 58 if (uri.lastPathSegment?.endsWith("png", true) == true) { 59 return "image/png" 60 } 61 if (uri.lastPathSegment?.endsWith("jpg", true) == true) { 62 return "image/jpg" 63 } 64 return null 65 } 66 insertnull67 override fun insert(uri: Uri, values: ContentValues?): Uri? = null 68 69 override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int = 0 70 71 override fun update( 72 uri: Uri, 73 values: ContentValues?, 74 selection: String?, 75 selectionArgs: Array<String>?, 76 ): Int = 0 77 78 override fun openTypedAssetFile( 79 uri: Uri, 80 mimeTypeFilter: String, 81 opts: Bundle?, 82 ): AssetFileDescriptor? { 83 return openAssetFile(uri, "r") 84 } 85 openAssetFilenull86 override fun openAssetFile(uri: Uri, mode: String): AssetFileDescriptor? { 87 Thread.sleep(getLatencyMs(openLatency)) 88 89 if (shouldFailOpen()) { 90 return null 91 } 92 93 return uri.lastPathSegment?.let { context?.assets?.openFd(it) } 94 } 95 openFilenull96 override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? = 97 openAssetFile(uri, mode)?.parcelFileDescriptor 98 99 private fun shouldFailOpen() = getRandomFailure(openFailureRate) 100 101 companion object { 102 private val sizeMap = mapOf( 103 "img1.jpg" to Size(1944, 2592), 104 "img2.jpg" to Size(2368, 3200), 105 "img3.jpg" to Size(3200, 2368), 106 "img4.jpg" to Size(4032, 3024), 107 "img5.jpg" to Size(2448, 3264), 108 "img6.jpg" to Size(4032, 3024), 109 "img7.jpg" to Size(3024, 4032), 110 "img8.jpg" to Size(1600, 1200), 111 ) 112 113 fun makeItemUri(idx: Int, mimeType: String, includeSize: Boolean): Uri = 114 Uri.parse("${URI_PREFIX}img${(idx % IMAGE_COUNT) + 1}.jpg") 115 .buildUpon() 116 .appendQueryParameter(PARAM_TYPE, mimeType) 117 .appendQueryParameter(PARAM_SIZE_META, includeSize.toString()) 118 .appendQueryParameter("index", idx.toString()) 119 .build() 120 121 fun getImageSize(uri: Uri): Size? { 122 val name = uri.lastPathSegment ?: return null 123 return sizeMap[name] 124 } 125 126 const val IMAGE_COUNT = 8 127 128 const val URI_PREFIX = "content://com.android.sharetest.provider/" 129 const val PARAM_TYPE = "type" 130 const val PARAM_SIZE_META = "ismeta" 131 val ICON_URI: Uri = Uri.parse("${URI_PREFIX}letter_a.png") 132 133 var getTypeLatency = 0L 134 var openLatency = 0L 135 var openFailureRate = 0f 136 var queryLatency = 0L 137 } 138 } 139 140 141