<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