<lambda>null1 package com.android.sharetest
2
3 import android.content.ContentProvider
4 import android.content.ContentValues
5 import android.content.Intent
6 import android.database.Cursor
7 import android.database.MatrixCursor
8 import android.net.Uri
9 import android.os.Bundle
10 import android.os.CancellationSignal
11 import android.os.SystemClock
12 import android.service.chooser.AdditionalContentContract
13 import kotlin.random.Random
14
15 class AdditionalContentProvider : ContentProvider() {
16 override fun onCreate(): Boolean {
17 return true
18 }
19
20 override fun query(
21 uri: Uri,
22 projection: Array<String>?,
23 queryArgs: Bundle?,
24 cancellationSignal: CancellationSignal?,
25 ): Cursor? {
26 val context = context ?: return null
27 val cursor = MatrixCursor(arrayOf(AdditionalContentContract.Columns.URI))
28 val chooserIntent =
29 queryArgs?.getParcelable(Intent.EXTRA_INTENT, Intent::class.java) ?: return cursor
30 val count = runCatching {
31 uri.getQueryParameter(PARAM_COUNT)?.toInt()
32 }.getOrNull() ?: ImageContentProvider.IMAGE_COUNT
33 val includeSize = runCatching {
34 uri.getQueryParameter(PARAM_SIZE_META).toBoolean()
35 }.getOrDefault(true)
36 val mimeTypes = kotlin.runCatching {
37 uri.getQueryParameters(PARAM_MIME_TYPE)
38 }.getOrNull() ?: listOf("image/jpeg")
39 // Images are img1 ... img8
40 val uris = Array(count) { idx ->
41 ImageContentProvider.makeItemUri(idx, mimeTypes[idx % mimeTypes.size], includeSize)
42 }
43 val callingPackage = getCallingPackage()
44 for (u in uris) {
45 cursor.addRow(arrayOf(u.toString()))
46 context.grantUriPermission(callingPackage, u, Intent.FLAG_GRANT_READ_URI_PERMISSION)
47 }
48 val startPos = chooserIntent.getIntExtra(CURSOR_START_POSITION, -1)
49 if (startPos >= 0) {
50 var cursorExtras = cursor.extras
51 cursorExtras = if (cursorExtras == null) {
52 Bundle()
53 } else {
54 Bundle(cursorExtras)
55 }
56 cursorExtras.putInt(AdditionalContentContract.CursorExtraKeys.POSITION, startPos)
57 cursor.extras = cursorExtras
58 }
59 return cursor
60 }
61
62 override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
63 val context = context ?: return null
64 val result = Bundle()
65 val customActionFactory = CustomActionFactory(context)
66
67 val chooserIntent =
68 extras?.getParcelable(Intent.EXTRA_INTENT, Intent::class.java) ?: return result
69
70 // If the chooser intent has a custom action, make a random number of custom actions each
71 // time they change something.
72 if (chooserIntent.hasExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS)) {
73 result.putParcelableArray(
74 Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS,
75 customActionFactory.getCustomActions(Random.nextInt(5))
76 )
77 }
78
79 // Update alternate intent if the chooser intent has one.
80 if (chooserIntent.hasExtra(Intent.EXTRA_ALTERNATE_INTENTS)) {
81 chooserIntent.getParcelableExtra(Intent.EXTRA_INTENT, Intent::class.java)
82 ?.let { targetIntent ->
83 result.putParcelableArray(
84 Intent.EXTRA_ALTERNATE_INTENTS,
85 arrayOf(createAlternateIntent(targetIntent))
86 )
87 }
88 }
89
90 if (chooserIntent.hasExtra(Intent.EXTRA_CHOOSER_MODIFY_SHARE_ACTION)) {
91 result.setModifyShareAction(
92 context,
93 chooserIntent.getParcelableExtra(
94 Intent.EXTRA_INTENT,
95 Intent::class.java
96 )?.extraStream?.size ?: -1
97 )
98 }
99
100 if (chooserIntent.hasExtra(Intent.EXTRA_CHOOSER_TARGETS)) {
101 result.putParcelableArray(
102 Intent.EXTRA_CHOOSER_TARGETS,
103 arrayOf(
104 createCallerTarget(
105 context,
106 buildString {
107 append("Modified Caller Target. Shared URIs:")
108 chooserIntent.getParcelableExtra(
109 Intent.EXTRA_INTENT,
110 Intent::class.java
111 )?.extraStream?.forEach {
112 append("\n * $it")
113 }
114 }
115 )
116 )
117 )
118 }
119
120 if (chooserIntent.hasExtra(Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER)) {
121 result.putParcelable(
122 Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER,
123 createRefinementIntentSender(context, false)
124 )
125 }
126
127 val latency = chooserIntent.getIntExtra(EXTRA_SELECTION_LATENCY, 0)
128 if (latency > 0) {
129 SystemClock.sleep(latency.toLong())
130 }
131
132 return result
133 }
134
135 override fun query(
136 uri: Uri,
137 projection: Array<String>?,
138 selection: String?,
139 selectionArgs: Array<String>?,
140 sortOrder: String?,
141 ): Cursor? {
142 return null
143 }
144
145 override fun getType(uri: Uri): String? {
146 return null
147 }
148
149 override fun insert(uri: Uri, values: ContentValues?): Uri? {
150 return null
151 }
152
153 override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
154 return 0
155 }
156
157 override fun update(
158 uri: Uri,
159 values: ContentValues?,
160 selection: String?,
161 selectionArgs: Array<String>?,
162 ): Int {
163 return 0
164 }
165
166 companion object {
167 val ADDITIONAL_CONTENT_URI = Uri.parse("content://com.android.sharetest.additionalcontent")
168 val CURSOR_START_POSITION = "com.android.sharetest.CURSOR_START_POS"
169 val EXTRA_SELECTION_LATENCY = "latency"
170 val PARAM_COUNT = "count"
171 val PARAM_SIZE_META = "ismeta"
172 val PARAM_MIME_TYPE = "mimetype"
173 }
174 }
175
176