summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Andrey Epin <ayepin@google.com> 2024-02-08 23:34:46 -0800
committer Andrey Epin <ayepin@google.com> 2024-02-12 21:43:49 -0800
commitfbde775360396f6e9df8d6cb8abd8189b75d0979 (patch)
tree85f576f208c2eba11d259746b7e23b08bed98b64 /java/src
parent7c3a34ea571c1c8571f33d3fe72afac7a175c055 (diff)
Show payload toggling UI
Show payload toggling UI if the flag is enabled. Bug: 302691505 Test: enable feature flag and verify that payload toggling UI is gets shown Change-Id: If3c70088e58977f5345066d5abec31e298e1f4fe
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java9
-rw-r--r--java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt2
-rw-r--r--java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt2
-rw-r--r--java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt29
-rw-r--r--java/src/com/android/intentresolver/v2/ChooserActivity.java21
-rw-r--r--java/src/com/android/intentresolver/v2/JavaFlowHelper.kt28
6 files changed, 87 insertions, 4 deletions
diff --git a/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java b/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
index 471a33e6..acdf6ec6 100644
--- a/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
+++ b/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
@@ -18,12 +18,14 @@ package com.android.intentresolver.contentpreview;
import static com.android.intentresolver.contentpreview.ContentPreviewType.CONTENT_PREVIEW_FILE;
import static com.android.intentresolver.contentpreview.ContentPreviewType.CONTENT_PREVIEW_IMAGE;
+import static com.android.intentresolver.contentpreview.ContentPreviewType.CONTENT_PREVIEW_PAYLOAD_SELECTION;
import static com.android.intentresolver.contentpreview.ContentPreviewType.CONTENT_PREVIEW_TEXT;
import android.content.ClipData;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
+import android.service.chooser.Flags;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -154,6 +156,13 @@ public final class ChooserContentPreviewUi {
}
return fileContentPreviewUi;
}
+
+ //TODO: use flags injection
+ if (previewType == CONTENT_PREVIEW_PAYLOAD_SELECTION && Flags.chooserPayloadToggling()) {
+ transitionElementStatusCallback.onAllTransitionElementsReady(); // TODO
+ return new ShareouselContentPreviewUi(actionFactory);
+ }
+
boolean isSingleImageShare = previewData.getUriCount() == 1
&& typeClassifier.isImageType(previewData.getFirstFileInfo().getMimeType());
CharSequence text = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
diff --git a/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt b/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
index 3393dcfc..8a34e6a9 100644
--- a/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
+++ b/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
@@ -27,6 +27,7 @@ import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.channels.BufferOverflow.DROP_LATEST
@@ -40,6 +41,7 @@ import kotlinx.coroutines.launch
private const val TAG = "PayloadToggleInteractor"
+@OptIn(ExperimentalCoroutinesApi::class)
class PayloadToggleInteractor(
// must use single-thread dispatcher (or we should enforce it with a lock)
private val scope: CoroutineScope,
diff --git a/java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt b/java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt
index 51a3cb14..4dd0d3f5 100644
--- a/java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt
+++ b/java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt
@@ -63,7 +63,7 @@ internal class ShareouselContentPreviewUi(
val vm: BasePreviewViewModel = viewModel()
val interactor =
requireNotNull(vm.payloadToggleInteractor) { "Should not be null" }
- val viewModel = interactor.toShareouselViewModel(vm.imageLoader)
+ val viewModel = interactor.toShareouselViewModel(vm.imageLoader, actionFactory)
if (headlineViewParent != null) {
LaunchedEffect(Unit) {
diff --git a/java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt b/java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt
index 05523c7e..fae439e5 100644
--- a/java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt
+++ b/java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt
@@ -16,11 +16,17 @@
package com.android.intentresolver.contentpreview.shareousel.ui.viewmodel
import android.graphics.Bitmap
+import androidx.core.graphics.drawable.toBitmap
+import com.android.intentresolver.contentpreview.ChooserContentPreviewUi.ActionFactory
import com.android.intentresolver.contentpreview.ImageLoader
+import com.android.intentresolver.contentpreview.MutableActionFactory
import com.android.intentresolver.contentpreview.PayloadToggleInteractor
+import com.android.intentresolver.icon.BitmapIcon
import com.android.intentresolver.icon.ComposeIcon
+import com.android.intentresolver.widget.ActionRow.Action
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
data class ShareouselViewModel(
@@ -41,11 +47,23 @@ data class ShareouselImageViewModel(
val setSelected: (Boolean) -> Unit,
)
-fun PayloadToggleInteractor.toShareouselViewModel(imageLoader: ImageLoader): ShareouselViewModel {
+fun PayloadToggleInteractor.toShareouselViewModel(
+ imageLoader: ImageLoader,
+ actionFactory: ActionFactory
+): ShareouselViewModel {
return ShareouselViewModel(
headline = MutableStateFlow("Shareousel"),
previewKeys = previewKeys,
- actions = MutableStateFlow(emptyList()),
+ actions =
+ if (actionFactory is MutableActionFactory) {
+ actionFactory.customActionsFlow.map { actions ->
+ actions.map { it.toActionChipViewModel() }
+ }
+ } else {
+ flow {
+ emit(actionFactory.createCustomActions().map { it.toActionChipViewModel() })
+ }
+ },
centerIndex = targetPosition,
previewForKey = { key ->
val previewInteractor = previewInteractor(key)
@@ -59,3 +77,10 @@ fun PayloadToggleInteractor.toShareouselViewModel(imageLoader: ImageLoader): Sha
previewRowKey = { getKey(it) },
)
}
+
+private fun Action.toActionChipViewModel() =
+ ActionChipViewModel(
+ label?.toString() ?: "",
+ icon?.let { BitmapIcon(it.toBitmap()) },
+ onClick = { onClicked.run() }
+ )
diff --git a/java/src/com/android/intentresolver/v2/ChooserActivity.java b/java/src/com/android/intentresolver/v2/ChooserActivity.java
index 2ffd31d8..cdc05b95 100644
--- a/java/src/com/android/intentresolver/v2/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/v2/ChooserActivity.java
@@ -29,6 +29,7 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE
import static androidx.lifecycle.LifecycleKt.getCoroutineScope;
+import static com.android.intentresolver.contentpreview.ContentPreviewType.CONTENT_PREVIEW_PAYLOAD_SELECTION;
import static com.android.intentresolver.v2.ext.CreationExtrasExtKt.addDefaultArgs;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PROTECTED;
import static com.android.internal.util.LatencyTracker.ACTION_LOAD_SHARE_SHEET;
@@ -122,6 +123,7 @@ import com.android.intentresolver.chooser.TargetInfo;
import com.android.intentresolver.contentpreview.BasePreviewViewModel;
import com.android.intentresolver.contentpreview.ChooserContentPreviewUi;
import com.android.intentresolver.contentpreview.HeadlineGeneratorImpl;
+import com.android.intentresolver.contentpreview.PayloadToggleInteractor;
import com.android.intentresolver.contentpreview.PreviewViewModel;
import com.android.intentresolver.emptystate.CompositeEmptyStateProvider;
import com.android.intentresolver.emptystate.CrossProfileIntentsChecker;
@@ -487,12 +489,29 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
chooserRequest.getAdditionalContentUri(),
chooserRequest.getFocusedItemPosition(),
mChooserServiceFeatureFlags.chooserPayloadToggling());
+ ChooserActionFactory chooserActionFactory = createChooserActionFactory();
+ ChooserContentPreviewUi.ActionFactory actionFactory = chooserActionFactory;
+ if (previewViewModel.getPreviewDataProvider().getPreviewType()
+ == CONTENT_PREVIEW_PAYLOAD_SELECTION
+ && android.service.chooser.Flags.chooserPayloadToggling()) {
+ PayloadToggleInteractor payloadToggleInteractor =
+ previewViewModel.getPayloadToggleInteractor();
+ if (payloadToggleInteractor != null) {
+ ChooserMutableActionFactory mutableActionFactory =
+ new ChooserMutableActionFactory(chooserActionFactory);
+ actionFactory = mutableActionFactory;
+ JavaFlowHelper.collect(
+ getCoroutineScope(getLifecycle()),
+ payloadToggleInteractor.getCustomActions(),
+ mutableActionFactory::updateCustomActions);
+ }
+ }
mChooserContentPreviewUi = new ChooserContentPreviewUi(
getCoroutineScope(getLifecycle()),
previewViewModel.getPreviewDataProvider(),
chooserRequest.getTargetIntent(),
previewViewModel.getImageLoader(),
- createChooserActionFactory(),
+ actionFactory,
mEnterTransitionAnimationDelegate,
new HeadlineGeneratorImpl(this),
chooserRequest.getContentTypeHint(),
diff --git a/java/src/com/android/intentresolver/v2/JavaFlowHelper.kt b/java/src/com/android/intentresolver/v2/JavaFlowHelper.kt
new file mode 100644
index 00000000..c6c977f6
--- /dev/null
+++ b/java/src/com/android/intentresolver/v2/JavaFlowHelper.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:JvmName("JavaFlowHelper")
+
+package com.android.intentresolver.v2
+
+import java.util.function.Consumer
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.launch
+
+fun <T> collect(scope: CoroutineScope, flow: Flow<T>, collector: Consumer<T>): Job =
+ scope.launch { flow.collect { collector.accept(it) } }