summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
author Matt Casey <mrcasey@google.com> 2024-02-09 15:16:02 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-02-09 15:16:02 +0000
commit13b9c24c24381dfadbec63936b02ea72cae43a3e (patch)
treed6dab99181787d941028f7c5e1d2bb8ff3bd0eaf /java/src
parent1831ffd4f04f1be892fe6b69ddd4d687cb0f67c8 (diff)
parentac931a751ce024dfcd603a4ef9899dfe152927a6 (diff)
Merge "Add album headline override support to Chooser" into main
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/intentresolver/ChooserActivity.java3
-rw-r--r--java/src/com/android/intentresolver/ContentTypeHint.kt25
-rw-r--r--java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java22
-rw-r--r--java/src/com/android/intentresolver/contentpreview/HeadlineGenerator.kt6
-rw-r--r--java/src/com/android/intentresolver/contentpreview/HeadlineGeneratorImpl.kt4
-rw-r--r--java/src/com/android/intentresolver/contentpreview/TextContentPreviewUi.java11
-rw-r--r--java/src/com/android/intentresolver/v2/ChooserActivity.java3
-rw-r--r--java/src/com/android/intentresolver/v2/ui/model/ChooserRequest.kt4
-rw-r--r--java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserRequestReader.kt21
-rw-r--r--java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserViewModel.kt7
10 files changed, 88 insertions, 18 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java
index c3b13527..708538de 100644
--- a/java/src/com/android/intentresolver/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/ChooserActivity.java
@@ -310,7 +310,8 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
previewViewModel.getImageLoader(),
createChooserActionFactory(),
mEnterTransitionAnimationDelegate,
- new HeadlineGeneratorImpl(this));
+ new HeadlineGeneratorImpl(this),
+ ContentTypeHint.NONE);
updateStickyContentPreview();
if (shouldShowStickyContentPreview()
diff --git a/java/src/com/android/intentresolver/ContentTypeHint.kt b/java/src/com/android/intentresolver/ContentTypeHint.kt
new file mode 100644
index 00000000..f607e4ae
--- /dev/null
+++ b/java/src/com/android/intentresolver/ContentTypeHint.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.intentresolver
+
+import android.content.Intent
+
+/** Enum reflecting the value of [Intent.EXTRA_CHOOSER_CONTENT_TYPE_HINT]. */
+enum class ContentTypeHint {
+ NONE,
+ ALBUM,
+}
diff --git a/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java b/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
index a015147d..5b4cb682 100644
--- a/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
+++ b/java/src/com/android/intentresolver/contentpreview/ChooserContentPreviewUi.java
@@ -32,6 +32,7 @@ import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.intentresolver.ContentTypeHint;
import com.android.intentresolver.widget.ActionRow;
import com.android.intentresolver.widget.ImagePreviewView.TransitionElementStatusCallback;
@@ -98,7 +99,8 @@ public final class ChooserContentPreviewUi {
ImageLoader imageLoader,
ActionFactory actionFactory,
TransitionElementStatusCallback transitionElementStatusCallback,
- HeadlineGenerator headlineGenerator) {
+ HeadlineGenerator headlineGenerator,
+ ContentTypeHint contentTypeHint) {
mScope = scope;
mContentPreviewUi = createContentPreview(
previewData,
@@ -107,7 +109,8 @@ public final class ChooserContentPreviewUi {
imageLoader,
actionFactory,
transitionElementStatusCallback,
- headlineGenerator);
+ headlineGenerator,
+ contentTypeHint);
if (mContentPreviewUi.getType() != CONTENT_PREVIEW_IMAGE) {
transitionElementStatusCallback.onAllTransitionElementsReady();
}
@@ -120,7 +123,8 @@ public final class ChooserContentPreviewUi {
ImageLoader imageLoader,
ActionFactory actionFactory,
TransitionElementStatusCallback transitionElementStatusCallback,
- HeadlineGenerator headlineGenerator) {
+ HeadlineGenerator headlineGenerator,
+ ContentTypeHint contentTypeHint) {
int previewType = previewData.getPreviewType();
if (previewType == CONTENT_PREVIEW_TEXT) {
@@ -129,7 +133,8 @@ public final class ChooserContentPreviewUi {
targetIntent,
actionFactory,
imageLoader,
- headlineGenerator);
+ headlineGenerator,
+ contentTypeHint);
}
if (previewType == CONTENT_PREVIEW_FILE) {
FileContentPreviewUi fileContentPreviewUi = new FileContentPreviewUi(
@@ -142,7 +147,7 @@ public final class ChooserContentPreviewUi {
return fileContentPreviewUi;
}
boolean isSingleImageShare = previewData.getUriCount() == 1
- && typeClassifier.isImageType(previewData.getFirstFileInfo().getMimeType());
+ && typeClassifier.isImageType(previewData.getFirstFileInfo().getMimeType());
CharSequence text = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
if (!TextUtils.isEmpty(text)) {
FilesPlusTextContentPreviewUi previewUi =
@@ -200,7 +205,8 @@ public final class ChooserContentPreviewUi {
Intent targetIntent,
ChooserContentPreviewUi.ActionFactory actionFactory,
ImageLoader imageLoader,
- HeadlineGenerator headlineGenerator) {
+ HeadlineGenerator headlineGenerator,
+ ContentTypeHint contentTypeHint) {
CharSequence sharingText = targetIntent.getCharSequenceExtra(Intent.EXTRA_TEXT);
CharSequence previewTitle = targetIntent.getCharSequenceExtra(Intent.EXTRA_TITLE);
ClipData previewData = targetIntent.getClipData();
@@ -211,6 +217,7 @@ public final class ChooserContentPreviewUi {
previewThumbnail = previewDataItem.getUri();
}
}
+
return new TextContentPreviewUi(
scope,
sharingText,
@@ -218,6 +225,7 @@ public final class ChooserContentPreviewUi {
previewThumbnail,
actionFactory,
imageLoader,
- headlineGenerator);
+ headlineGenerator,
+ contentTypeHint);
}
}
diff --git a/java/src/com/android/intentresolver/contentpreview/HeadlineGenerator.kt b/java/src/com/android/intentresolver/contentpreview/HeadlineGenerator.kt
index 5f87c924..21308341 100644
--- a/java/src/com/android/intentresolver/contentpreview/HeadlineGenerator.kt
+++ b/java/src/com/android/intentresolver/contentpreview/HeadlineGenerator.kt
@@ -17,12 +17,14 @@
package com.android.intentresolver.contentpreview
/**
- * HeadlineGenerator generates the text to show at the top of the sharesheet as a brief
- * description of the content being shared.
+ * HeadlineGenerator generates the text to show at the top of the sharesheet as a brief description
+ * of the content being shared.
*/
interface HeadlineGenerator {
fun getTextHeadline(text: CharSequence): String
+ fun getAlbumHeadline(): String
+
fun getImagesWithTextHeadline(text: CharSequence, count: Int): String
fun getVideosWithTextHeadline(text: CharSequence, count: Int): String
diff --git a/java/src/com/android/intentresolver/contentpreview/HeadlineGeneratorImpl.kt b/java/src/com/android/intentresolver/contentpreview/HeadlineGeneratorImpl.kt
index ef1e55d8..6e126822 100644
--- a/java/src/com/android/intentresolver/contentpreview/HeadlineGeneratorImpl.kt
+++ b/java/src/com/android/intentresolver/contentpreview/HeadlineGeneratorImpl.kt
@@ -34,6 +34,10 @@ class HeadlineGeneratorImpl(private val context: Context) : HeadlineGenerator {
)
}
+ override fun getAlbumHeadline(): String {
+ return context.getString(R.string.sharing_album)
+ }
+
override fun getImagesWithTextHeadline(text: CharSequence, count: Int): String {
return getPluralString(
getTemplateResource(
diff --git a/java/src/com/android/intentresolver/contentpreview/TextContentPreviewUi.java b/java/src/com/android/intentresolver/contentpreview/TextContentPreviewUi.java
index b0dc3c58..df2896d7 100644
--- a/java/src/com/android/intentresolver/contentpreview/TextContentPreviewUi.java
+++ b/java/src/com/android/intentresolver/contentpreview/TextContentPreviewUi.java
@@ -30,6 +30,7 @@ import android.widget.TextView;
import androidx.annotation.Nullable;
+import com.android.intentresolver.ContentTypeHint;
import com.android.intentresolver.R;
import com.android.intentresolver.widget.ActionRow;
@@ -46,6 +47,7 @@ class TextContentPreviewUi extends ContentPreviewUi {
private final ImageLoader mImageLoader;
private final ChooserContentPreviewUi.ActionFactory mActionFactory;
private final HeadlineGenerator mHeadlineGenerator;
+ private final ContentTypeHint mContentTypeHint;
TextContentPreviewUi(
CoroutineScope scope,
@@ -54,7 +56,8 @@ class TextContentPreviewUi extends ContentPreviewUi {
@Nullable Uri previewThumbnail,
ChooserContentPreviewUi.ActionFactory actionFactory,
ImageLoader imageLoader,
- HeadlineGenerator headlineGenerator) {
+ HeadlineGenerator headlineGenerator,
+ ContentTypeHint contentTypeHint) {
mScope = scope;
mSharingText = sharingText;
mPreviewTitle = previewTitle;
@@ -62,6 +65,7 @@ class TextContentPreviewUi extends ContentPreviewUi {
mImageLoader = imageLoader;
mActionFactory = actionFactory;
mHeadlineGenerator = headlineGenerator;
+ mContentTypeHint = contentTypeHint;
}
@Override
@@ -139,7 +143,10 @@ class TextContentPreviewUi extends ContentPreviewUi {
copyButton.setVisibility(View.GONE);
}
- displayHeadline(headlineViewParent, mHeadlineGenerator.getTextHeadline(mSharingText));
+ String headlineText = (mContentTypeHint == ContentTypeHint.ALBUM)
+ ? mHeadlineGenerator.getAlbumHeadline()
+ : mHeadlineGenerator.getTextHeadline(mSharingText);
+ displayHeadline(headlineViewParent, headlineText);
return contentPreviewLayout;
}
diff --git a/java/src/com/android/intentresolver/v2/ChooserActivity.java b/java/src/com/android/intentresolver/v2/ChooserActivity.java
index b9cf53b6..247f6529 100644
--- a/java/src/com/android/intentresolver/v2/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/v2/ChooserActivity.java
@@ -477,7 +477,8 @@ public class ChooserActivity extends Hilt_ChooserActivity implements
previewViewModel.getImageLoader(),
createChooserActionFactory(),
mEnterTransitionAnimationDelegate,
- new HeadlineGeneratorImpl(this));
+ new HeadlineGeneratorImpl(this),
+ chooserRequest.getContentTypeHint());
updateStickyContentPreview();
if (shouldShowStickyContentPreview()
|| mChooserMultiProfilePagerAdapter
diff --git a/java/src/com/android/intentresolver/v2/ui/model/ChooserRequest.kt b/java/src/com/android/intentresolver/v2/ui/model/ChooserRequest.kt
index 5c785675..4fc2e46a 100644
--- a/java/src/com/android/intentresolver/v2/ui/model/ChooserRequest.kt
+++ b/java/src/com/android/intentresolver/v2/ui/model/ChooserRequest.kt
@@ -27,6 +27,7 @@ import android.os.Bundle
import android.service.chooser.ChooserAction
import android.service.chooser.ChooserTarget
import androidx.annotation.StringRes
+import com.android.intentresolver.ContentTypeHint
import com.android.intentresolver.v2.ext.hasAction
const val ANDROID_APP_SCHEME = "android-app"
@@ -169,6 +170,9 @@ data class ChooserRequest(
/** Focused item index (from target intent's STREAM_EXTRA) */
val focusedItemPosition: Int = 0,
+
+ /** Value for [Intent.EXTRA_CHOOSER_CONTENT_TYPE_HINT] on the incoming chooser intent. */
+ val contentTypeHint: ContentTypeHint = ContentTypeHint.NONE
) {
val referrerPackage = referrer?.takeIf { it.scheme == ANDROID_APP_SCHEME }?.authority
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 167c441f..558e54c9 100644
--- a/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserRequestReader.kt
+++ b/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserRequestReader.kt
@@ -40,9 +40,10 @@ import android.net.Uri
import android.os.Bundle
import android.service.chooser.ChooserAction
import android.service.chooser.ChooserTarget
-import android.service.chooser.Flags
import com.android.intentresolver.ChooserActivity
+import com.android.intentresolver.ContentTypeHint
import com.android.intentresolver.R
+import com.android.intentresolver.inject.ChooserServiceFlags
import com.android.intentresolver.util.hasValidIcon
import com.android.intentresolver.v2.ext.hasAction
import com.android.intentresolver.v2.ext.ifMatch
@@ -72,7 +73,10 @@ internal fun Intent.maybeAddSendActionFlags() =
addFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
}
-fun readChooserRequest(launch: ActivityLaunch): ValidationResult<ChooserRequest> {
+fun readChooserRequest(
+ launch: ActivityLaunch,
+ flags: ChooserServiceFlags
+): ValidationResult<ChooserRequest> {
val extras = launch.intent.extras ?: Bundle()
@Suppress("DEPRECATION")
return validateFrom(extras::get) {
@@ -135,7 +139,7 @@ fun readChooserRequest(launch: ActivityLaunch): ValidationResult<ChooserRequest>
val additionalContentUri: Uri?
val focusedItemPos: Int
- if (isSendAction && Flags.chooserPayloadToggling()) {
+ if (isSendAction && flags.chooserPayloadToggling()) {
additionalContentUri = optional(value<Uri>(EXTRA_CHOOSER_ADDITIONAL_CONTENT_URI))
focusedItemPos = optional(value<Int>(EXTRA_CHOOSER_FOCUSED_ITEM_POSITION)) ?: 0
} else {
@@ -143,6 +147,16 @@ fun readChooserRequest(launch: ActivityLaunch): ValidationResult<ChooserRequest>
focusedItemPos = 0
}
+ val contentTypeHint =
+ if (flags.chooserAlbumText()) {
+ when (optional(value<Int>(Intent.EXTRA_CHOOSER_CONTENT_TYPE_HINT))) {
+ Intent.CHOOSER_CONTENT_TYPE_ALBUM -> ContentTypeHint.ALBUM
+ else -> ContentTypeHint.NONE
+ }
+ } else {
+ ContentTypeHint.NONE
+ }
+
ChooserRequest(
targetIntent = targetIntent,
targetAction = targetIntent.action,
@@ -169,6 +183,7 @@ fun readChooserRequest(launch: ActivityLaunch): ValidationResult<ChooserRequest>
shareTargetFilter = targetIntent.toShareTargetFilter(),
additionalContentUri = additionalContentUri,
focusedItemPosition = focusedItemPos,
+ contentTypeHint = contentTypeHint,
)
}
}
diff --git a/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserViewModel.kt b/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserViewModel.kt
index 17b1e664..776bc1cb 100644
--- a/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserViewModel.kt
+++ b/java/src/com/android/intentresolver/v2/ui/viewmodel/ChooserViewModel.kt
@@ -18,6 +18,7 @@ package com.android.intentresolver.v2.ui.viewmodel
import android.util.Log
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
+import com.android.intentresolver.inject.ChooserServiceFlags
import com.android.intentresolver.v2.ui.model.ActivityLaunch
import com.android.intentresolver.v2.ui.model.ActivityLaunch.Companion.ACTIVITY_LAUNCH_KEY
import com.android.intentresolver.v2.ui.model.ChooserRequest
@@ -28,7 +29,8 @@ import javax.inject.Inject
private const val TAG = "ChooserViewModel"
@HiltViewModel
-class ChooserViewModel @Inject constructor(args: SavedStateHandle) : ViewModel() {
+class ChooserViewModel @Inject constructor(args: SavedStateHandle, flags: ChooserServiceFlags) :
+ ViewModel() {
private val mActivityLaunch: ActivityLaunch =
requireNotNull(args[ACTIVITY_LAUNCH_KEY]) {
@@ -36,7 +38,8 @@ class ChooserViewModel @Inject constructor(args: SavedStateHandle) : ViewModel()
}
/** The result of reading and validating the inputs provided in savedState. */
- private val status: ValidationResult<ChooserRequest> = readChooserRequest(mActivityLaunch)
+ private val status: ValidationResult<ChooserRequest> =
+ readChooserRequest(mActivityLaunch, flags)
val chooserRequest: ChooserRequest by lazy { status.getOrThrow() }