summaryrefslogtreecommitdiff
path: root/java/src/com
diff options
context:
space:
mode:
author Andrey Epin <ayepin@google.com> 2024-06-07 14:33:28 -0700
committer Andrey Yepin <ayepin@google.com> 2024-07-10 13:55:33 -0700
commit8cd6138cca567e14e2cdfa132a8686c4eb324d52 (patch)
tree62bd332d481e657e0396774f2b486a3958f6091d /java/src/com
parent1ff97c2f2070038344297e9141e108f20bc102d2 (diff)
Delete unused class ChooserRequestParameters
Bug: N/A Test: presubmits Flag: EXEMPT refactor Change-Id: I84573929396492bfe10a2f835783c9edd58f8c5c
Diffstat (limited to 'java/src/com')
-rw-r--r--java/src/com/android/intentresolver/ChooserRequestParameters.java500
1 files changed, 0 insertions, 500 deletions
diff --git a/java/src/com/android/intentresolver/ChooserRequestParameters.java b/java/src/com/android/intentresolver/ChooserRequestParameters.java
deleted file mode 100644
index 66bb66ef..00000000
--- a/java/src/com/android/intentresolver/ChooserRequestParameters.java
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Copyright (C) 2008 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.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.PatternMatcher;
-import android.service.chooser.ChooserAction;
-import android.service.chooser.ChooserTarget;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.intentresolver.util.UriFilters;
-
-import com.google.common.collect.ImmutableList;
-
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collector;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Utility to parse and validate parameters from the client-supplied {@link Intent} that launched
- * the Sharesheet {@link ChooserActivity}. The validated parameters are stored as immutable ivars.
- *
- * TODO: field nullability in this class reflects legacy use, and typically would indicate that the
- * client's intent didn't provide the respective data. In some cases we may be able to provide
- * defaults instead of nulls -- especially for methods that return nullable lists or arrays, if the
- * client code could instead handle empty collections equally well.
- *
- * TODO: some of these fields (especially getTargetIntent() and any other getters that delegate to
- * it internally) differ from the legacy model because they're computed directly from the initial
- * Chooser intent, where in the past they've been relayed up to ResolverActivity and then retrieved
- * through methods on the base class. The base always seems to return them exactly as they were
- * provided, so this should be safe -- and clients can reasonably switch to retrieving through these
- * parameters instead. For now, the other convention is still used in some places. Ideally we'd like
- * to normalize on a single source of truth, but we'll have to clean up the delegation up to the
- * resolver (or perhaps this needs to be a subclass of some `ResolverRequestParameters` class?).
- */
-public class ChooserRequestParameters {
- private static final String TAG = "ChooserActivity";
-
- private static final int LAUNCH_FLAGS_FOR_SEND_ACTION =
- Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
- private static final int MAX_CHOOSER_ACTIONS = 5;
-
- private final Intent mTarget;
- private final String mReferrerPackageName;
- private final Pair<CharSequence, Integer> mTitleSpec;
- private final Intent mReferrerFillInIntent;
- private final ImmutableList<ComponentName> mFilteredComponentNames;
- private final ImmutableList<ChooserTarget> mCallerChooserTargets;
- private final @NonNull ImmutableList<ChooserAction> mChooserActions;
- private final ChooserAction mModifyShareAction;
- private final boolean mRetainInOnStop;
-
- @Nullable
- private final ImmutableList<Intent> mAdditionalTargets;
-
- @Nullable
- private final Bundle mReplacementExtras;
-
- @Nullable
- private final ImmutableList<Intent> mInitialIntents;
-
- @Nullable
- private final IntentSender mChosenComponentSender;
-
- @Nullable
- private final IntentSender mRefinementIntentSender;
-
- @Nullable
- private final String mSharedText;
-
- @Nullable
- private final IntentFilter mTargetIntentFilter;
-
- @Nullable
- private final CharSequence mMetadataText;
-
- public ChooserRequestParameters(
- final Intent clientIntent,
- String referrerPackageName,
- final Uri referrer) {
- final Intent requestedTarget = parseTargetIntentExtra(
- clientIntent.getParcelableExtra(Intent.EXTRA_INTENT));
- mTarget = intentWithModifiedLaunchFlags(requestedTarget);
-
- mReferrerPackageName = referrerPackageName;
-
- mAdditionalTargets = intentsWithModifiedLaunchFlagsFromExtraIfPresent(
- clientIntent, Intent.EXTRA_ALTERNATE_INTENTS);
-
- mReplacementExtras = clientIntent.getBundleExtra(Intent.EXTRA_REPLACEMENT_EXTRAS);
-
- mTitleSpec = makeTitleSpec(
- clientIntent.getCharSequenceExtra(Intent.EXTRA_TITLE),
- isSendAction(mTarget.getAction()));
-
- mInitialIntents = intentsWithModifiedLaunchFlagsFromExtraIfPresent(
- clientIntent, Intent.EXTRA_INITIAL_INTENTS);
-
- mReferrerFillInIntent = new Intent().putExtra(Intent.EXTRA_REFERRER, referrer);
-
- mChosenComponentSender =
- Optional.ofNullable(
- clientIntent.getParcelableExtra(Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER,
- IntentSender.class))
- .orElse(clientIntent.getParcelableExtra(
- Intent.EXTRA_CHOOSER_RESULT_INTENT_SENDER,
- IntentSender.class));
-
- mRefinementIntentSender = clientIntent.getParcelableExtra(
- Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER);
-
- ComponentName[] filteredComponents = clientIntent.getParcelableArrayExtra(
- Intent.EXTRA_EXCLUDE_COMPONENTS, ComponentName.class);
- mFilteredComponentNames = filteredComponents != null
- ? ImmutableList.copyOf(filteredComponents)
- : ImmutableList.of();
-
- mCallerChooserTargets = parseCallerTargetsFromClientIntent(clientIntent);
-
- mRetainInOnStop = clientIntent.getBooleanExtra(
- ChooserActivity.EXTRA_PRIVATE_RETAIN_IN_ON_STOP, false);
-
- mSharedText = mTarget.getStringExtra(Intent.EXTRA_TEXT);
-
- mTargetIntentFilter = getTargetIntentFilter(mTarget);
-
- mChooserActions = getChooserActions(clientIntent);
- mModifyShareAction = getModifyShareAction(clientIntent);
-
- mMetadataText = clientIntent.getCharSequenceExtra(Intent.EXTRA_METADATA_TEXT);
- }
-
- public Intent getTargetIntent() {
- return mTarget;
- }
-
- @Nullable
- public String getTargetAction() {
- return getTargetIntent().getAction();
- }
-
- public boolean isSendActionTarget() {
- return isSendAction(getTargetAction());
- }
-
- @Nullable
- public String getTargetType() {
- return getTargetIntent().getType();
- }
-
- public String getReferrerPackageName() {
- return mReferrerPackageName;
- }
-
- @Nullable
- public CharSequence getTitle() {
- return mTitleSpec.first;
- }
-
- public int getDefaultTitleResource() {
- return mTitleSpec.second;
- }
-
- public Intent getReferrerFillInIntent() {
- return mReferrerFillInIntent;
- }
-
- public ImmutableList<ComponentName> getFilteredComponentNames() {
- return mFilteredComponentNames;
- }
-
- public ImmutableList<ChooserTarget> getCallerChooserTargets() {
- return mCallerChooserTargets;
- }
-
- @NonNull
- public ImmutableList<ChooserAction> getChooserActions() {
- return mChooserActions;
- }
-
- @Nullable
- public ChooserAction getModifyShareAction() {
- return mModifyShareAction;
- }
-
- /**
- * Whether the {@link ChooserActivity#EXTRA_PRIVATE_RETAIN_IN_ON_STOP} behavior was requested.
- */
- public boolean shouldRetainInOnStop() {
- return mRetainInOnStop;
- }
-
- /**
- * TODO: this returns a nullable array for convenience, but if the legacy APIs can be
- * refactored, returning {@link #mAdditionalTargets} directly is simpler and safer.
- */
- @Nullable
- public Intent[] getAdditionalTargets() {
- return (mAdditionalTargets == null) ? null : mAdditionalTargets.toArray(new Intent[0]);
- }
-
- @Nullable
- public Bundle getReplacementExtras() {
- return mReplacementExtras;
- }
-
- /**
- * TODO: this returns a nullable array for convenience, but if the legacy APIs can be
- * refactored, returning {@link #mInitialIntents} directly is simpler and safer.
- */
- @Nullable
- public Intent[] getInitialIntents() {
- return (mInitialIntents == null) ? null : mInitialIntents.toArray(new Intent[0]);
- }
-
- @Nullable
- public IntentSender getChosenComponentSender() {
- return mChosenComponentSender;
- }
-
- @Nullable
- public IntentSender getRefinementIntentSender() {
- return mRefinementIntentSender;
- }
-
- @Nullable
- public String getSharedText() {
- return mSharedText;
- }
-
- @Nullable
- public IntentFilter getTargetIntentFilter() {
- return mTargetIntentFilter;
- }
-
- @Nullable
- public CharSequence getMetadataText() {
- return mMetadataText;
- }
-
- private static boolean isSendAction(@Nullable String action) {
- return (Intent.ACTION_SEND.equals(action) || Intent.ACTION_SEND_MULTIPLE.equals(action));
- }
-
- private static Intent parseTargetIntentExtra(@Nullable Parcelable targetParcelable) {
- if (targetParcelable instanceof Uri) {
- try {
- targetParcelable = Intent.parseUri(targetParcelable.toString(),
- Intent.URI_INTENT_SCHEME);
- } catch (URISyntaxException ex) {
- throw new IllegalArgumentException("Failed to parse EXTRA_INTENT from URI", ex);
- }
- }
-
- if (!(targetParcelable instanceof Intent)) {
- throw new IllegalArgumentException(
- "EXTRA_INTENT is neither an Intent nor a Uri: " + targetParcelable);
- }
-
- return ((Intent) targetParcelable);
- }
-
- private static Intent intentWithModifiedLaunchFlags(Intent intent) {
- if (isSendAction(intent.getAction())) {
- intent.addFlags(LAUNCH_FLAGS_FOR_SEND_ACTION);
- }
- return intent;
- }
-
- /**
- * Build a pair of values specifying the title to use from the client request. The first
- * ({@link CharSequence}) value is the client-specified title, if there was one and their
- * requested target <em>wasn't</em> a send action; otherwise it is null. The second value is
- * the resource ID of a default title string; this is nonzero only if the first value is null.
- *
- * TODO: change the API for how these are passed up to {@link ResolverActivity#onCreate}, or
- * create a real type (not {@link Pair}) to express the semantics described in this comment.
- */
- private static Pair<CharSequence, Integer> makeTitleSpec(
- @Nullable CharSequence requestedTitle, boolean hasSendActionTarget) {
- if (hasSendActionTarget && (requestedTitle != null)) {
- // Do not allow the title to be changed when sharing content
- Log.w(TAG, "Ignoring intent's EXTRA_TITLE, deprecated in P. You may wish to set a"
- + " preview title by using EXTRA_TITLE property of the wrapped"
- + " EXTRA_INTENT.");
- requestedTitle = null;
- }
-
- int defaultTitleRes = (requestedTitle == null) ? R.string.chooseActivity : 0;
-
- return Pair.create(requestedTitle, defaultTitleRes);
- }
-
- private static ImmutableList<ChooserTarget> parseCallerTargetsFromClientIntent(
- Intent clientIntent) {
- return
- streamParcelableArrayExtra(
- clientIntent, Intent.EXTRA_CHOOSER_TARGETS, ChooserTarget.class, true, true)
- .collect(toImmutableList());
- }
-
- @NonNull
- private static ImmutableList<ChooserAction> getChooserActions(Intent intent) {
- return streamParcelableArrayExtra(
- intent,
- Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS,
- ChooserAction.class,
- true,
- true)
- .filter(UriFilters::hasValidIcon)
- .limit(MAX_CHOOSER_ACTIONS)
- .collect(toImmutableList());
- }
-
- @Nullable
- private static ChooserAction getModifyShareAction(Intent intent) {
- try {
- return intent.getParcelableExtra(
- Intent.EXTRA_CHOOSER_MODIFY_SHARE_ACTION,
- ChooserAction.class);
- } catch (Throwable t) {
- Log.w(
- TAG,
- "Unable to retrieve Intent.EXTRA_CHOOSER_MODIFY_SHARE_ACTION argument",
- t);
- return null;
- }
- }
-
- private static <T> Collector<T, ?, ImmutableList<T>> toImmutableList() {
- return Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf);
- }
-
- @Nullable
- private static ImmutableList<Intent> intentsWithModifiedLaunchFlagsFromExtraIfPresent(
- Intent clientIntent, String extra) {
- Stream<Intent> intents =
- streamParcelableArrayExtra(clientIntent, extra, Intent.class, true, false);
- if (intents == null) {
- return null;
- }
- return intents
- .map(ChooserRequestParameters::intentWithModifiedLaunchFlags)
- .collect(toImmutableList());
- }
-
- /**
- * Make a {@link Stream} of the {@link Parcelable} objects given in the provided {@link Intent}
- * as the optional parcelable array extra with key {@code extra}. The stream elements, if any,
- * are all of the type specified by {@code clazz}.
- *
- * @param intent The intent that may contain the optional extras.
- * @param extra The extras key to identify the parcelable array.
- * @param clazz A class that is assignable from any elements in the result stream.
- * @param warnOnTypeError Whether to log a warning (and ignore) if the client extra doesn't have
- * the required type. If false, throw an {@link IllegalArgumentException} if the extra is
- * non-null but can't be assigned to variables of type {@code T}.
- * @param streamEmptyIfNull Whether to return an empty stream if the optional extra isn't
- * present in the intent (or if it had the wrong type, but <em>warnOnTypeError</em> is true).
- * If false, return null in these cases, and only return an empty stream if the intent
- * explicitly provided an empty array for the specified extra.
- */
- @Nullable
- private static <T extends Parcelable> Stream<T> streamParcelableArrayExtra(
- final Intent intent,
- String extra,
- @NonNull Class<T> clazz,
- boolean warnOnTypeError,
- boolean streamEmptyIfNull) {
- T[] result = null;
-
- try {
- result = getParcelableArrayExtraIfPresent(intent, extra, clazz);
- } catch (IllegalArgumentException e) {
- if (warnOnTypeError) {
- Log.w(TAG, "Ignoring client-requested " + extra, e);
- } else {
- throw e;
- }
- }
-
- if (result != null) {
- return Arrays.stream(result);
- } else if (streamEmptyIfNull) {
- return Stream.empty();
- } else {
- return null;
- }
- }
-
- /**
- * If the specified {@code extra} is provided in the {@code intent}, cast it to type {@code T[]}
- * or throw an {@code IllegalArgumentException} if the cast fails. If the {@code extra} isn't
- * present in the {@code intent}, return null.
- */
- @Nullable
- private static <T extends Parcelable> T[] getParcelableArrayExtraIfPresent(
- final Intent intent, String extra, @NonNull Class<T> clazz) throws
- IllegalArgumentException {
- if (!intent.hasExtra(extra)) {
- return null;
- }
-
- T[] castResult = intent.getParcelableArrayExtra(extra, clazz);
- if (castResult == null) {
- Parcelable[] actualExtrasArray = intent.getParcelableArrayExtra(extra);
- if (actualExtrasArray != null) {
- throw new IllegalArgumentException(
- String.format(
- "%s is not of type %s[]: %s",
- extra,
- clazz.getSimpleName(),
- Arrays.toString(actualExtrasArray)));
- } else if (intent.getParcelableExtra(extra) != null) {
- throw new IllegalArgumentException(
- String.format(
- "%s is not of type %s[] (or any array type): %s",
- extra,
- clazz.getSimpleName(),
- intent.getParcelableExtra(extra)));
- } else {
- throw new IllegalArgumentException(
- String.format(
- "%s is not of type %s (or any Parcelable type): %s",
- extra,
- clazz.getSimpleName(),
- intent.getExtras().get(extra)));
- }
- }
-
- return castResult;
- }
-
- private static IntentFilter getTargetIntentFilter(final Intent intent) {
- try {
- String dataString = intent.getDataString();
- if (intent.getType() == null) {
- if (!TextUtils.isEmpty(dataString)) {
- return new IntentFilter(intent.getAction(), dataString);
- }
- Log.e(TAG, "Failed to get target intent filter: intent data and type are null");
- return null;
- }
- IntentFilter intentFilter = new IntentFilter(intent.getAction(), intent.getType());
- List<Uri> contentUris = new ArrayList<>();
- if (Intent.ACTION_SEND.equals(intent.getAction())) {
- Uri uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
- if (uri != null) {
- contentUris.add(uri);
- }
- } else {
- List<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
- if (uris != null) {
- contentUris.addAll(uris);
- }
- }
- for (Uri uri : contentUris) {
- intentFilter.addDataScheme(uri.getScheme());
- intentFilter.addDataAuthority(uri.getAuthority(), null);
- intentFilter.addDataPath(uri.getPath(), PatternMatcher.PATTERN_LITERAL);
- }
- return intentFilter;
- } catch (Exception e) {
- Log.e(TAG, "Failed to get target intent filter", e);
- return null;
- }
- }
-}