summaryrefslogtreecommitdiff
path: root/java/src/com
diff options
context:
space:
mode:
author Andrey Epin <ayepin@google.com> 2022-12-12 09:17:29 -0800
committer Andrey Epin <ayepin@google.com> 2023-01-05 10:18:51 -0800
commit49b65f54be53ec48d53a550e783759100e8812dc (patch)
treea9c9a5ba553f0fddaae5a74b6dec9641d6c18881 /java/src/com
parentc317e6a26b75da0a693cbb14f673ecdd7152c433 (diff)
Add Chooser custom actions
Add Chooser custom action support under a compile-time flag. Bug: 262278109 Test: manual testing of the basic functionality Test: manual custom actions testing with a test app Test: atest IntentResolverUnitTests (with the both flag values) Change-Id: Ib6f6b46aa4f693a544e0e52a6d1a3e63ba57b162
Diffstat (limited to 'java/src/com')
-rw-r--r--java/src/com/android/intentresolver/ChooserActivity.java47
-rw-r--r--java/src/com/android/intentresolver/ChooserContentPreviewUi.java27
-rw-r--r--java/src/com/android/intentresolver/ChooserRequestParameters.java23
3 files changed, 91 insertions, 6 deletions
diff --git a/java/src/com/android/intentresolver/ChooserActivity.java b/java/src/com/android/intentresolver/ChooserActivity.java
index ceab62b2..55904fc1 100644
--- a/java/src/com/android/intentresolver/ChooserActivity.java
+++ b/java/src/com/android/intentresolver/ChooserActivity.java
@@ -32,6 +32,7 @@ import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityOptions;
+import android.app.PendingIntent;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
@@ -70,6 +71,7 @@ import android.os.UserManager;
import android.os.storage.StorageManager;
import android.provider.DeviceConfig;
import android.provider.Settings;
+import android.service.chooser.ChooserAction;
import android.service.chooser.ChooserTarget;
import android.text.TextUtils;
import android.util.Log;
@@ -112,6 +114,8 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.FrameworkStatsLog;
+import com.google.common.collect.ImmutableList;
+
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
@@ -158,6 +162,7 @@ public class ChooserActivity extends ResolverActivity implements
private static final String CHIP_ICON_METADATA_KEY = "android.service.chooser.chip_icon";
private static final boolean DEBUG = true;
+ static final boolean ENABLE_CUSTOM_ACTIONS = false;
public static final String LAUNCH_LOCATION_DIRECT_SHARE = "direct_share";
private static final String SHORTCUT_TARGET = "shortcut_target";
@@ -265,7 +270,7 @@ public class ChooserActivity extends ResolverActivity implements
try {
mChooserRequest = new ChooserRequestParameters(
- getIntent(), getReferrer(), getNearbySharingComponent());
+ getIntent(), getReferrer(), getNearbySharingComponent(), ENABLE_CUSTOM_ACTIONS);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Caller provided invalid Chooser request parameters", e);
finish();
@@ -732,6 +737,20 @@ public class ChooserActivity extends ResolverActivity implements
public ActionRow.Action createNearbyButton() {
return ChooserActivity.this.createNearbyAction(targetIntent);
}
+
+ @Override
+ public List<ActionRow.Action> createCustomActions() {
+ ImmutableList<ChooserAction> customActions =
+ mChooserRequest.getChooserActions();
+ List<ActionRow.Action> actions = new ArrayList<>(customActions.size());
+ for (ChooserAction customAction : customActions) {
+ ActionRow.Action action = createCustomAction(customAction);
+ if (action != null) {
+ actions.add(action);
+ }
+ }
+ return actions;
+ }
};
ViewGroup layout = ChooserContentPreviewUi.displayContentPreview(
@@ -740,7 +759,9 @@ public class ChooserActivity extends ResolverActivity implements
getResources(),
getLayoutInflater(),
actionFactory,
- R.layout.chooser_action_row,
+ ENABLE_CUSTOM_ACTIONS
+ ? R.layout.scrollable_chooser_action_row
+ : R.layout.chooser_action_row,
parent,
previewCoordinator,
mEnterTransitionAnimationDelegate::markImagePreviewReady,
@@ -928,6 +949,28 @@ public class ChooserActivity extends ResolverActivity implements
}
@Nullable
+ private ActionRow.Action createCustomAction(ChooserAction action) {
+ Drawable icon = action.getIcon().loadDrawable(this);
+ if (icon == null && TextUtils.isEmpty(action.getLabel())) {
+ return null;
+ }
+ return new ActionRow.Action(
+ action.getLabel(),
+ icon,
+ () -> {
+ try {
+ action.getAction().send();
+ } catch (PendingIntent.CanceledException e) {
+ Log.d(TAG, "Custom action, " + action.getLabel() + ", has been cancelled");
+ }
+ // TODO: add reporting
+ setResult(RESULT_OK);
+ finish();
+ }
+ );
+ }
+
+ @Nullable
private View getFirstVisibleImgPreviewView() {
View firstImage = findViewById(com.android.internal.R.id.content_preview_image_1_large);
return firstImage != null && firstImage.isVisibleToUser() ? firstImage : null;
diff --git a/java/src/com/android/intentresolver/ChooserContentPreviewUi.java b/java/src/com/android/intentresolver/ChooserContentPreviewUi.java
index ff88e5e1..daded28b 100644
--- a/java/src/com/android/intentresolver/ChooserContentPreviewUi.java
+++ b/java/src/com/android/intentresolver/ChooserContentPreviewUi.java
@@ -102,6 +102,9 @@ public final class ChooserContentPreviewUi {
/** Create an "Share to Nearby" action. */
@Nullable
ActionRow.Action createNearbyButton();
+
+ /** Create custom actions */
+ List<ActionRow.Action> createCustomActions();
}
/**
@@ -187,12 +190,15 @@ public final class ChooserContentPreviewUi {
ImageMimeTypeClassifier imageClassifier) {
ViewGroup layout = null;
+ List<ActionRow.Action> customActions = actionFactory.createCustomActions();
switch (previewType) {
case CONTENT_PREVIEW_TEXT:
layout = displayTextContentPreview(
targetIntent,
layoutInflater,
- createTextPreviewActions(actionFactory),
+ createActions(
+ createTextPreviewActions(actionFactory),
+ customActions),
parent,
previewCoord,
actionRowLayout);
@@ -201,7 +207,9 @@ public final class ChooserContentPreviewUi {
layout = displayImageContentPreview(
targetIntent,
layoutInflater,
- createImagePreviewActions(actionFactory),
+ createActions(
+ createImagePreviewActions(actionFactory),
+ customActions),
parent,
previewCoord,
onTransitionTargetReady,
@@ -214,7 +222,9 @@ public final class ChooserContentPreviewUi {
targetIntent,
resources,
layoutInflater,
- createFilePreviewActions(actionFactory),
+ createActions(
+ createFilePreviewActions(actionFactory),
+ customActions),
parent,
previewCoord,
contentResolver,
@@ -227,6 +237,17 @@ public final class ChooserContentPreviewUi {
return layout;
}
+ private static List<ActionRow.Action> createActions(
+ List<ActionRow.Action> systemActions, List<ActionRow.Action> customActions) {
+ ArrayList<ActionRow.Action> actions =
+ new ArrayList<>(systemActions.size() + customActions.size());
+ actions.addAll(systemActions);
+ if (ChooserActivity.ENABLE_CUSTOM_ACTIONS) {
+ actions.addAll(customActions);
+ }
+ return actions;
+ }
+
private static Cursor queryResolver(ContentResolver resolver, Uri uri) {
return resolver.query(uri, null, null, null, null);
}
diff --git a/java/src/com/android/intentresolver/ChooserRequestParameters.java b/java/src/com/android/intentresolver/ChooserRequestParameters.java
index 81481bf1..a7e543a5 100644
--- a/java/src/com/android/intentresolver/ChooserRequestParameters.java
+++ b/java/src/com/android/intentresolver/ChooserRequestParameters.java
@@ -26,6 +26,7 @@ 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;
@@ -70,6 +71,7 @@ public class ChooserRequestParameters {
private final Intent mReferrerFillInIntent;
private final ImmutableList<ComponentName> mFilteredComponentNames;
private final ImmutableList<ChooserTarget> mCallerChooserTargets;
+ private final ImmutableList<ChooserAction> mChooserActions;
private final boolean mRetainInOnStop;
@Nullable
@@ -96,7 +98,8 @@ public class ChooserRequestParameters {
public ChooserRequestParameters(
final Intent clientIntent,
final Uri referrer,
- @Nullable final ComponentName nearbySharingComponent) {
+ @Nullable final ComponentName nearbySharingComponent,
+ boolean extractCustomActions) {
final Intent requestedTarget = parseTargetIntentExtra(
clientIntent.getParcelableExtra(Intent.EXTRA_INTENT));
mTarget = intentWithModifiedLaunchFlags(requestedTarget);
@@ -130,6 +133,10 @@ public class ChooserRequestParameters {
mSharedText = mTarget.getStringExtra(Intent.EXTRA_TEXT);
mTargetIntentFilter = getTargetIntentFilter(mTarget);
+
+ mChooserActions = extractCustomActions
+ ? getChooserActions(clientIntent)
+ : ImmutableList.of();
}
public Intent getTargetIntent() {
@@ -171,6 +178,10 @@ public class ChooserRequestParameters {
return mCallerChooserTargets;
}
+ public ImmutableList<ChooserAction> getChooserActions() {
+ return mChooserActions;
+ }
+
/**
* Whether the {@link ChooserActivity.EXTRA_PRIVATE_RETAIN_IN_ON_STOP} behavior was requested.
*/
@@ -300,6 +311,16 @@ public class ChooserRequestParameters {
.collect(toImmutableList());
}
+ private static ImmutableList<ChooserAction> getChooserActions(Intent intent) {
+ return streamParcelableArrayExtra(
+ intent,
+ Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS,
+ ChooserAction.class,
+ true,
+ true)
+ .collect(toImmutableList());
+ }
+
private static <T> Collector<T, ?, ImmutableList<T>> toImmutableList() {
return Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf);
}