• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.sharetest
18 
19 import android.app.PendingIntent
20 import android.content.ComponentName
21 import android.content.Context
22 import android.content.Intent
23 import android.graphics.drawable.Icon
24 import android.net.Uri
25 import android.os.Bundle
26 import android.service.chooser.ChooserAction
27 import android.service.chooser.ChooserTarget
28 import android.text.TextUtils
29 import androidx.core.os.bundleOf
30 import java.util.concurrent.atomic.AtomicInteger
31 import kotlin.math.roundToLong
32 
33 const val REFINEMENT_ACTION = "com.android.sharetest.REFINEMENT"
34 private const val EXTRA_IS_INITIAL = "com.android.sharetest.IS_INITIAL"
35 private const val EXTRA_ID = "com.android.sharetest.ID"
36 
37 fun createAlternateIntent(intent: Intent): Intent {
38     val text = buildString {
39         append("Shared URIs:")
40         intent.extraStream.forEach { append("\n * $it") }
41     }
42     return Intent(Intent.ACTION_SEND).apply { setText(text) }
43 }
44 
Intentnull45 fun Intent.setText(text: CharSequence) {
46     if (TextUtils.isEmpty(type)) {
47         type = "text/plain"
48     }
49     putExtra(Intent.EXTRA_TEXT, text)
50 }
51 
setModifyShareActionnull52 fun Intent.setModifyShareAction(context: Context) {
53     val modifyShareAction = createModifyShareAction(context, true, 0)
54     putExtra(Intent.EXTRA_CHOOSER_MODIFY_SHARE_ACTION, modifyShareAction)
55 }
56 
Bundlenull57 fun Bundle.setModifyShareAction(context: Context, count: Int) {
58     val modifyShareAction = createModifyShareAction(context, false, count)
59     putParcelable(Intent.EXTRA_CHOOSER_MODIFY_SHARE_ACTION, modifyShareAction)
60 }
61 
62 // Provide some gaussian noise around the preferred average latency
getLatencyMsnull63 fun getLatencyMs(avg: Long): Long {
64     // Using avg/4 as the standard deviation.
65     val noise = avg / 4 * random.nextGaussian()
66     return (avg + noise).roundToLong().coerceAtLeast(0)
67 }
68 
getRandomFailurenull69 fun getRandomFailure(failureRate: Float): Boolean = random.nextFloat() < failureRate
70 
71 private val random by lazy { java.util.Random() }
72 
createModifyShareActionnull73 private fun createModifyShareAction(
74     context: Context,
75     isInitial: Boolean,
76     count: Int,
77 ): ChooserAction {
78     val pendingIntent =
79         PendingIntent.getBroadcast(
80             context,
81             1,
82             Intent(CustomActionFactory.BROADCAST_ACTION).apply { this.isInitial = isInitial },
83             PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT,
84         )
85     return ChooserAction.Builder(
86             Icon.createWithResource(context, R.drawable.testicon),
87             buildString {
88                 append("Modify Share")
89                 if (!isInitial) {
90                     append(" (items: $count)")
91                 }
92             },
93             pendingIntent,
94         )
95         .build()
96 }
97 
98 val Intent.extraStream: List<Uri>
<lambda>null99     get() = buildList {
100         when (action) {
101             Intent.ACTION_SEND ->
102                 getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)?.let { add(it) }
103 
104             Intent.ACTION_SEND_MULTIPLE ->
105                 getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java)?.let { uris ->
106                     for (uri in uris) {
107                         if (uri != null) {
108                             add(uri)
109                         }
110                     }
111                 }
112         }
113     }
114 
115 var Intent.isInitial: Boolean
116     set(value) {
117         putExtra(EXTRA_IS_INITIAL, value)
118     }
119     get() = getBooleanExtra(EXTRA_IS_INITIAL, true)
120 
121 var Intent.id: Int
122     set(value) {
123         putExtra(EXTRA_ID, value)
124     }
125     get() = getIntExtra(EXTRA_ID, -1)
126 
createCallerTargetnull127 fun createCallerTarget(context: Context, text: String) =
128     ChooserTarget(
129         "Caller Target",
130         Icon.createWithResource(context, R.drawable.launcher_icon),
131         1f,
132         ComponentName(context, CallerDirectTargetActivity::class.java),
133         bundleOf(Intent.EXTRA_TEXT to text),
134     )
135 
136 private val refinementCounter = AtomicInteger(0)
137 
138 fun createRefinementIntentSender(context: Context, isInitial: Boolean) =
139     PendingIntent.getBroadcast(
140             context,
141             1,
142             Intent(REFINEMENT_ACTION).apply {
143                 setPackage(context.packageName)
144                 this.isInitial = isInitial
145                 id = refinementCounter.incrementAndGet()
146             },
147             PendingIntent.FLAG_MUTABLE or
148                 PendingIntent.FLAG_CANCEL_CURRENT or
149                 PendingIntent.FLAG_CANCEL_CURRENT,
150         )
151         .intentSender
152 
153 private val resultIntentSenderCounter = AtomicInteger(0)
154 
createResultIntentSendernull155 fun createResultIntentSender(context: Context) =
156     PendingIntent.getBroadcast(
157             context,
158             0,
159             Intent(context, ChosenComponentBroadcastReceiver::class.java).apply {
160                 id = resultIntentSenderCounter.incrementAndGet()
161             },
162             PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
163         )
164         .intentSender
165 
166 val Any.hashId: String
167     get() = System.identityHashCode(this).toString(Character.MAX_RADIX)
168