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