summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Andrey Epin <ayepin@google.com> 2024-02-14 15:39:46 -0800
committer Andrey Epin <ayepin@google.com> 2024-02-21 11:23:52 -0800
commit94f2cf048d55c36745542000f2f3276e2d04448f (patch)
tree2f2bde90604c717b0cb5858bedfe5f326958d90c /java/src
parent0511077086852d8b987e70eb57ab30dfc0148a7b (diff)
Parse remaining payload selection callback result arguments
Bug: 302691505 Test: atest IntentResolver-tests-unit Change-Id: I93ab3abb9605a32b4ce44572a027c478c3ea1210
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt21
-rw-r--r--java/src/com/android/intentresolver/contentpreview/SelectionChangeCallback.kt55
-rw-r--r--java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserRequestReader.kt22
3 files changed, 67 insertions, 31 deletions
diff --git a/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt b/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
index 003f6884..6f4f5167 100644
--- a/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
+++ b/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
@@ -17,8 +17,10 @@
package com.android.intentresolver.contentpreview
import android.content.Intent
+import android.content.IntentSender
import android.net.Uri
import android.service.chooser.ChooserAction
+import android.service.chooser.ChooserTarget
import android.util.Log
import android.util.SparseArray
import java.io.Closeable
@@ -43,7 +45,7 @@ private const val TAG = "PayloadToggleInteractor"
@OptIn(ExperimentalCoroutinesApi::class)
class PayloadToggleInteractor(
- // must use single-thread dispatcher (or we should enforce it with a lock)
+ // TODO: a single-thread dispatcher is currently expected. iterate on the synchronization logic.
private val scope: CoroutineScope,
private val initiallySharedUris: List<Uri>,
private val focusedUriIdx: Int,
@@ -51,7 +53,7 @@ class PayloadToggleInteractor(
private val cursorReaderProvider: suspend () -> CursorReader,
private val uriMetadataReader: (Uri) -> FileInfo,
private val targetIntentModifier: (List<Item>) -> Intent,
- private val selectionCallback: (Intent) -> CallbackResult?,
+ private val selectionCallback: (Intent) -> ShareouselUpdate?,
) {
private var cursorDataRef = CompletableDeferred<CursorData?>()
private val records = LinkedList<Record>()
@@ -183,7 +185,7 @@ class PayloadToggleInteractor(
val (reader, selectionTracker) = waitForCursorData() ?: return
if (!reader.hasMoreBefore) return
- val newItems = reader.readPageBefore().toRecords()
+ val newItems = reader.readPageBefore().toItems()
selectionTracker.onStartItemsAdded(newItems)
for (i in newItems.size() - 1 downTo 0) {
records.add(
@@ -224,7 +226,7 @@ class PayloadToggleInteractor(
val (reader, selectionTracker) = waitForCursorData() ?: return
if (!reader.hasMoreAfter) return
- val newItems = reader.readPageAfter().toRecords()
+ val newItems = reader.readPageAfter().toItems()
selectionTracker.onEndItemsAdded(newItems)
for (i in 0 until newItems.size()) {
val key = newItems.keyAt(i)
@@ -254,7 +256,7 @@ class PayloadToggleInteractor(
}
}
- private fun SparseArray<Uri>.toRecords(): SparseArray<Item> {
+ private fun SparseArray<Uri>.toItems(): SparseArray<Item> {
val items = SparseArray<Item>(size())
for (i in 0 until size()) {
val key = keyAt(i)
@@ -335,7 +337,14 @@ class PayloadToggleInteractor(
val isSelected = MutableStateFlow(false)
}
- data class CallbackResult(val customActions: List<ChooserAction>?)
+ data class ShareouselUpdate(
+ // for all properties, null value means no change
+ val customActions: List<ChooserAction>? = null,
+ val modifyShareAction: ChooserAction? = null,
+ val alternateIntents: List<Intent>? = null,
+ val callerTargets: List<ChooserTarget>? = null,
+ val refinementIntentSender: IntentSender? = null,
+ )
private data class CursorData(
val reader: CursorReader,
diff --git a/java/src/com/android/intentresolver/contentpreview/SelectionChangeCallback.kt b/java/src/com/android/intentresolver/contentpreview/SelectionChangeCallback.kt
index 4e2e37b8..5c916882 100644
--- a/java/src/com/android/intentresolver/contentpreview/SelectionChangeCallback.kt
+++ b/java/src/com/android/intentresolver/contentpreview/SelectionChangeCallback.kt
@@ -18,13 +18,25 @@ package com.android.intentresolver.contentpreview
import android.content.ContentInterface
import android.content.Intent
-import android.content.Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS
+import android.content.Intent.EXTRA_CHOOSER_MODIFY_SHARE_ACTION
+import android.content.Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER
+import android.content.Intent.EXTRA_CHOOSER_TARGETS
import android.content.Intent.EXTRA_INTENT
+import android.content.IntentSender
import android.net.Uri
import android.os.Bundle
import android.service.chooser.AdditionalContentContract.MethodNames.ON_SELECTION_CHANGED
import android.service.chooser.ChooserAction
-import com.android.intentresolver.contentpreview.PayloadToggleInteractor.CallbackResult
+import android.service.chooser.ChooserTarget
+import com.android.intentresolver.contentpreview.PayloadToggleInteractor.ShareouselUpdate
+import com.android.intentresolver.v2.ui.viewmodel.readAlternateIntents
+import com.android.intentresolver.v2.ui.viewmodel.readChooserActions
+import com.android.intentresolver.v2.validation.ValidationResult
+import com.android.intentresolver.v2.validation.types.array
+import com.android.intentresolver.v2.validation.types.value
+import com.android.intentresolver.v2.validation.validateFrom
+
+private const val TAG = "SelectionChangeCallback"
/**
* Encapsulates payload change callback invocation to the sharing app; handles callback arguments
@@ -34,8 +46,8 @@ class SelectionChangeCallback(
private val uri: Uri,
private val chooserIntent: Intent,
private val contentResolver: ContentInterface,
-) : (Intent) -> CallbackResult? {
- fun onSelectionChanged(targetIntent: Intent): CallbackResult? =
+) : (Intent) -> ShareouselUpdate? {
+ fun onSelectionChanged(targetIntent: Intent): ShareouselUpdate? =
contentResolver
.call(
requireNotNull(uri.authority) { "URI authority can not be null" },
@@ -49,20 +61,35 @@ class SelectionChangeCallback(
}
)
?.let { bundle ->
- val actions =
- if (bundle.containsKey(EXTRA_CHOOSER_CUSTOM_ACTIONS)) {
- bundle
- .getParcelableArray(
- EXTRA_CHOOSER_CUSTOM_ACTIONS,
- ChooserAction::class.java
- )
- ?.filterNotNull()
- ?: emptyList()
+ readCallbackResponse(bundle).let { validation ->
+ if (validation.isSuccess()) {
+ validation.value
} else {
+ validation.reportToLogcat(TAG)
null
}
- CallbackResult(actions)
+ }
}
override fun invoke(targetIntent: Intent) = onSelectionChanged(targetIntent)
+
+ private fun readCallbackResponse(bundle: Bundle): ValidationResult<ShareouselUpdate> {
+ return validateFrom(bundle::get) {
+ val customActions = readChooserActions()
+ val modifyShareAction =
+ optional(value<ChooserAction>(EXTRA_CHOOSER_MODIFY_SHARE_ACTION))
+ val alternateIntents = readAlternateIntents()
+ val callerTargets = optional(array<ChooserTarget>(EXTRA_CHOOSER_TARGETS))
+ val refinementIntentSender =
+ optional(value<IntentSender>(EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER))
+
+ ShareouselUpdate(
+ customActions,
+ modifyShareAction,
+ alternateIntents,
+ callerTargets,
+ refinementIntentSender,
+ )
+ }
+ }
}
diff --git a/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserRequestReader.kt b/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserRequestReader.kt
index e32d69b0..f8ab6fcb 100644
--- a/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserRequestReader.kt
+++ b/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserRequestReader.kt
@@ -28,7 +28,6 @@ import android.content.Intent.EXTRA_EXCLUDE_COMPONENTS
import android.content.Intent.EXTRA_INITIAL_INTENTS
import android.content.Intent.EXTRA_INTENT
import android.content.Intent.EXTRA_METADATA_TEXT
-import android.content.Intent.EXTRA_REFERRER
import android.content.Intent.EXTRA_REPLACEMENT_EXTRAS
import android.content.Intent.EXTRA_TEXT
import android.content.Intent.EXTRA_TITLE
@@ -49,6 +48,7 @@ import com.android.intentresolver.v2.ext.hasSendAction
import com.android.intentresolver.v2.ext.ifMatch
import com.android.intentresolver.v2.ui.model.ActivityLaunch
import com.android.intentresolver.v2.ui.model.ChooserRequest
+import com.android.intentresolver.v2.validation.Validation
import com.android.intentresolver.v2.validation.ValidationResult
import com.android.intentresolver.v2.validation.types.IntentOrUri
import com.android.intentresolver.v2.validation.types.array
@@ -75,9 +75,7 @@ fun readChooserRequest(
val isSendAction = targetIntent.hasSendAction()
- val additionalTargets =
- optional(array<Intent>(EXTRA_ALTERNATE_INTENTS))?.map { it.maybeAddSendActionFlags() }
- ?: emptyList()
+ val additionalTargets = readAlternateIntents() ?: emptyList()
val replacementExtras = optional(value<Bundle>(EXTRA_REPLACEMENT_EXTRAS))
@@ -119,16 +117,10 @@ fun readChooserRequest(
val sharedText = optional(value<CharSequence>(EXTRA_TEXT))
- val chooserActions =
- optional(array<ChooserAction>(EXTRA_CHOOSER_CUSTOM_ACTIONS))
- ?.filter { hasValidIcon(it) }
- ?.take(MAX_CHOOSER_ACTIONS)
- ?: emptyList()
+ val chooserActions = readChooserActions() ?: emptyList()
val modifyShareAction = optional(value<ChooserAction>(EXTRA_CHOOSER_MODIFY_SHARE_ACTION))
- val referrerFillIn = Intent().putExtra(EXTRA_REFERRER, launch.referrer)
-
val additionalContentUri: Uri?
val focusedItemPos: Int
if (isSendAction && flags.chooserPayloadToggling()) {
@@ -188,6 +180,14 @@ fun readChooserRequest(
}
}
+fun Validation.readAlternateIntents(): List<Intent>? =
+ optional(array<Intent>(EXTRA_ALTERNATE_INTENTS))?.map { it.maybeAddSendActionFlags() }
+
+fun Validation.readChooserActions(): List<ChooserAction>? =
+ optional(array<ChooserAction>(EXTRA_CHOOSER_CUSTOM_ACTIONS))
+ ?.filter { hasValidIcon(it) }
+ ?.take(MAX_CHOOSER_ACTIONS)
+
private fun Intent.toShareTargetFilter(): IntentFilter? {
return type?.let {
IntentFilter().apply {