xref: /aosp_15_r20/development/apps/ShareTest/src/com/android/sharetest/AdditionalContentProvider.kt (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)

<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