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 package com.android.intentresolver.data.model 17 18 import android.content.ComponentName 19 import android.content.Intent 20 import android.content.Intent.ACTION_SEND 21 import android.content.Intent.ACTION_SEND_MULTIPLE 22 import android.content.Intent.EXTRA_REFERRER 23 import android.content.IntentFilter 24 import android.content.IntentSender 25 import android.net.Uri 26 import android.os.Bundle 27 import android.service.chooser.ChooserAction 28 import android.service.chooser.ChooserTarget 29 import androidx.annotation.StringRes 30 import com.android.intentresolver.ContentTypeHint 31 import com.android.intentresolver.ext.hasAction 32 33 const val ANDROID_APP_SCHEME = "android-app" 34 35 /** All of the things that are consumed from an incoming share Intent (+Extras). */ 36 data class ChooserRequest( 37 /** Required. Represents the content being sent. */ 38 val targetIntent: Intent, 39 40 /** The action from [targetIntent] as retrieved with [Intent.getAction]. */ 41 val targetAction: String? = targetIntent.action, 42 43 /** 44 * Whether [targetAction] is ACTION_SEND or ACTION_SEND_MULTIPLE. These are considered the 45 * canonical "Share" actions. When handling other actions, this flag controls behavioral and 46 * visual changes. 47 */ 48 val isSendActionTarget: Boolean = targetIntent.hasAction(ACTION_SEND, ACTION_SEND_MULTIPLE), 49 50 /** The top-level content type as retrieved using [Intent.getType]. */ 51 val targetType: String? = targetIntent.type, 52 53 /** The package name of the app which started the current activity instance. */ 54 val launchedFromPackage: String, 55 56 /** A custom tile for the main UI. Ignored when the intent is ACTION_SEND(_MULTIPLE). */ 57 val title: CharSequence? = null, 58 59 /** A String resource ID to load when [title] is null. */ 60 @get:StringRes val defaultTitleResource: Int = 0, 61 62 /** 63 * The referrer value as received by the caller. It may have been supplied via [EXTRA_REFERRER] 64 * or synthesized from callerPackageName. This value is merged into outgoing intents. 65 */ 66 val referrer: Uri? = null, 67 68 /** 69 * Choices to exclude from results. 70 * 71 * Any resolved intents with a component in this list will be omitted before presentation. 72 */ 73 val filteredComponentNames: List<ComponentName> = emptyList(), 74 75 /** 76 * App provided shortcut share intents (aka "direct share targets") 77 * 78 * Normally share shortcuts are published and consumed using 79 * [ShortcutManager][android.content.pm.ShortcutManager]. This is an alternate channel to allow 80 * apps to directly inject the same information. 81 * 82 * Historical note: This option was initially integrated with other results from the 83 * ChooserTargetService API (since deprecated and removed), hence the name and data format. 84 * These are more correctly called "Share Shortcuts" now. 85 */ 86 val callerChooserTargets: List<ChooserTarget> = emptyList(), 87 88 /** 89 * Actions the user may perform. These are presented as separate affordances from the main list 90 * of choices. Selecting a choice is a terminal action which results in finishing. The item 91 * limit is [MAX_CHOOSER_ACTIONS]. This may be further constrained as appropriate. 92 */ 93 val chooserActions: List<ChooserAction> = emptyList(), 94 95 /** 96 * An action to start an Activity which for user updating of shared content. Selection is a 97 * terminal action, closing the current activity and launching the target of the action. 98 */ 99 val modifyShareAction: ChooserAction? = null, 100 101 /** 102 * When false the host activity will be [finished][android.app.Activity.finish] when stopped. 103 */ 104 @get:JvmName("shouldRetainInOnStop") val shouldRetainInOnStop: Boolean = false, 105 106 /** 107 * Intents which contain alternate representations of the content being shared. Any results from 108 * resolving these _alternate_ intents are included with the results of the primary intent as 109 * additional choices (e.g. share as image content vs. link to content). 110 */ 111 val additionalTargets: List<Intent> = emptyList(), 112 113 /** 114 * Alternate [extras][Intent.getExtras] to substitute when launching a selected app. 115 * 116 * For a given app (by package name), the Bundle describes what parameters to substitute when 117 * that app is selected. 118 * 119 * // TODO: Map<String, Bundle> 120 */ 121 val replacementExtras: Bundle? = null, 122 123 /** 124 * App-supplied choices to be presented first in the list. 125 * 126 * Custom labels and icons may be supplied using 127 * [LabeledIntent][android.content.pm.LabeledIntent]. 128 * 129 * Limit 2. 130 */ 131 val initialIntents: List<Intent> = emptyList(), 132 133 /** 134 * Provides for callers to be notified when a component is selected. 135 * 136 * The selection is reported in the Intent as [Intent.EXTRA_CHOSEN_COMPONENT] with the 137 * [ComponentName] of the item. 138 */ 139 val chosenComponentSender: IntentSender? = null, 140 141 /** 142 * Provides a mechanism for callers to post-process a target when a selection is made. 143 * 144 * The received intent will contain: 145 * * **EXTRA_INTENT** The chosen target 146 * * **EXTRA_ALTERNATE_INTENTS** Additional intents which also match the target 147 * * **EXTRA_RESULT_RECEIVER** A [ResultReceiver][android.os.ResultReceiver] providing a 148 * mechanism for the caller to return information. An updated intent to send must be included 149 * as [Intent.EXTRA_INTENT]. 150 */ 151 val refinementIntentSender: IntentSender? = null, 152 153 /** 154 * Contains the text content to share supplied by the source app. 155 * 156 * TODO: Constrain length? 157 */ 158 val sharedText: CharSequence? = null, 159 160 /** 161 * Supplied to 162 * [ShortcutManager.getShareTargets][android.content.pm.ShortcutManager.getShareTargets] to 163 * query for matching shortcuts. Specifically, only the [dataTypes][IntentFilter.hasDataType] 164 * are considered for matching share shortcuts currently. 165 */ 166 val shareTargetFilter: IntentFilter? = null, 167 168 /** A URI for additional content */ 169 val additionalContentUri: Uri? = null, 170 171 /** Focused item index (from target intent's STREAM_EXTRA) */ 172 val focusedItemPosition: Int = 0, 173 174 /** Value for [Intent.EXTRA_CHOOSER_CONTENT_TYPE_HINT] on the incoming chooser intent. */ 175 val contentTypeHint: ContentTypeHint = ContentTypeHint.NONE, 176 177 /** 178 * Metadata to be shown to the user as a part of the sharesheet window. 179 * 180 * Specified by the [Intent.EXTRA_METADATA_TEXT] 181 */ 182 val metadataText: CharSequence? = null, 183 ) { 184 val referrerPackage = referrer?.takeIf { it.scheme == ANDROID_APP_SCHEME }?.authority 185 186 fun getReferrerFillInIntent(): Intent { 187 return Intent().apply { 188 referrerPackage?.also { pkg -> 189 putExtra(EXTRA_REFERRER, Uri.parse("$ANDROID_APP_SCHEME://$pkg")) 190 } 191 } 192 } 193 194 val payloadIntents = listOf(targetIntent) + additionalTargets 195 } 196