diff options
| -rw-r--r-- | core/api/current.txt | 15 | ||||
| -rw-r--r-- | core/java/android/content/Intent.java | 22 | ||||
| -rw-r--r-- | core/java/android/service/chooser/ChooserResult.java | 173 | ||||
| -rw-r--r-- | core/java/android/service/chooser/flags.aconfig | 7 |
4 files changed, 216 insertions, 1 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 3fde9a69c5fb..e8ba1f64cb45 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -11284,6 +11284,8 @@ package android.content { field public static final String EXTRA_CHOOSER_CUSTOM_ACTIONS = "android.intent.extra.CHOOSER_CUSTOM_ACTIONS"; field public static final String EXTRA_CHOOSER_MODIFY_SHARE_ACTION = "android.intent.extra.CHOOSER_MODIFY_SHARE_ACTION"; field public static final String EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER = "android.intent.extra.CHOOSER_REFINEMENT_INTENT_SENDER"; + field @FlaggedApi("android.service.chooser.enable_chooser_result") public static final String EXTRA_CHOOSER_RESULT = "android.intent.extra.CHOOSER_RESULT"; + field @FlaggedApi("android.service.chooser.enable_chooser_result") public static final String EXTRA_CHOOSER_RESULT_INTENT_SENDER = "android.intent.extra.CHOOSER_RESULT_INTENT_SENDER"; field public static final String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS"; field public static final String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT"; field public static final String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER"; @@ -40127,6 +40129,19 @@ package android.service.chooser { method @NonNull public android.service.chooser.ChooserAction build(); } + @FlaggedApi("android.service.chooser.enable_chooser_result") public final class ChooserResult implements android.os.Parcelable { + method public int describeContents(); + method @Nullable public android.content.ComponentName getSelectedComponent(); + method public int getType(); + method public boolean isShortcut(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int CHOOSER_RESULT_COPY = 1; // 0x1 + field public static final int CHOOSER_RESULT_EDIT = 2; // 0x2 + field public static final int CHOOSER_RESULT_SELECTED_COMPONENT = 0; // 0x0 + field public static final int CHOOSER_RESULT_UNKNOWN = -1; // 0xffffffff + field @NonNull public static final android.os.Parcelable.Creator<android.service.chooser.ChooserResult> CREATOR; + } + @Deprecated public final class ChooserTarget implements android.os.Parcelable { ctor @Deprecated public ChooserTarget(CharSequence, android.graphics.drawable.Icon, float, android.content.ComponentName, @Nullable android.os.Bundle); method @Deprecated public int describeContents(); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 08871d4644c0..fac5f3c38bc5 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -73,6 +73,7 @@ import android.provider.DocumentsProvider; import android.provider.MediaStore; import android.provider.OpenableColumns; import android.service.chooser.ChooserAction; +import android.service.chooser.ChooserResult; import android.telecom.PhoneAccount; import android.telecom.TelecomManager; import android.text.TextUtils; @@ -1059,7 +1060,7 @@ public class Intent implements Parcelable, Cloneable { } if (sender != null) { - intent.putExtra(EXTRA_CHOSEN_COMPONENT_INTENT_SENDER, sender); + intent.putExtra(EXTRA_CHOOSER_RESULT_INTENT_SENDER, sender); } // Migrate any clip data and flags from target. @@ -6296,6 +6297,25 @@ public class Intent implements Parcelable, Cloneable { "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER"; /** + * An {@link IntentSender} that will be notified when a user successfully chooses a target + * component or initiates an action such as copy or edit within an {@link #ACTION_CHOOSER} + * activity. The IntentSender will have the extra {@link #EXTRA_CHOOSER_RESULT} describing + * the result. + */ + @FlaggedApi(android.service.chooser.Flags.FLAG_ENABLE_CHOOSER_RESULT) + public static final String EXTRA_CHOOSER_RESULT_INTENT_SENDER = + "android.intent.extra.CHOOSER_RESULT_INTENT_SENDER"; + + /** + * A {@link ChooserResult} which describes how the sharing session completed. + * <p> + * An instance is supplied to the optional IntentSender provided to + * {@link #createChooser(Intent, CharSequence, IntentSender)} when the session completes. + */ + @FlaggedApi(android.service.chooser.Flags.FLAG_ENABLE_CHOOSER_RESULT) + public static final String EXTRA_CHOOSER_RESULT = "android.intent.extra.CHOOSER_RESULT"; + + /** * The {@link ComponentName} chosen by the user to complete an action. * * @see #EXTRA_CHOSEN_COMPONENT_INTENT_SENDER diff --git a/core/java/android/service/chooser/ChooserResult.java b/core/java/android/service/chooser/ChooserResult.java new file mode 100644 index 000000000000..4603be114508 --- /dev/null +++ b/core/java/android/service/chooser/ChooserResult.java @@ -0,0 +1,173 @@ +/* + * 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 android.service.chooser; + +import android.annotation.FlaggedApi; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; +import android.compat.annotation.Overridable; +import android.content.ComponentName; +import android.content.Intent; +import android.content.IntentSender; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * An event reported to a supplied [IntentSender] by the system chooser when an activity is selected + * or other actions are taken to complete the session. + * + * @see Intent#EXTRA_CHOOSER_RESULT_INTENT_SENDER + */ +@FlaggedApi(android.service.chooser.Flags.FLAG_ENABLE_CHOOSER_RESULT) +public final class ChooserResult implements Parcelable { + + /** + * Controls whether to send ChooserResult to the optional IntentSender supplied to the Chooser. + * <p> + * When enabled, ChooserResult is added to the provided Intent as + * {@link Intent#EXTRA_CHOOSER_RESULT}, and sent for actions such as copy and edit, in addition + * to activity selection. When disabled, only the selected component + * is provided in {@link Intent#EXTRA_CHOSEN_COMPONENT}. + * <p> + * See: {@link Intent#createChooser(Intent, CharSequence, IntentSender)} + * + * @hide + */ + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) + @Overridable + public static final long SEND_CHOOSER_RESULT = 263474465L; + + /** @hide */ + @IntDef({ + CHOOSER_RESULT_UNKNOWN, + CHOOSER_RESULT_SELECTED_COMPONENT, + CHOOSER_RESULT_COPY, + CHOOSER_RESULT_EDIT + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ResultType { } + + /** An unknown action was taken to complete the session. */ + public static final int CHOOSER_RESULT_UNKNOWN = -1; + /** The session was completed by selecting an activity to launch. */ + public static final int CHOOSER_RESULT_SELECTED_COMPONENT = 0; + /** The session was completed by invoking the copy action. */ + public static final int CHOOSER_RESULT_COPY = 1; + /** The session was completed by invoking the edit action. */ + public static final int CHOOSER_RESULT_EDIT = 2; + + @ResultType + private final int mType; + private final ComponentName mSelectedComponent; + private final boolean mIsShortcut; + + private ChooserResult(@NonNull Parcel source) { + mType = source.readInt(); + mSelectedComponent = ComponentName.readFromParcel(source); + mIsShortcut = source.readBoolean(); + } + + /** @hide */ + public ChooserResult(@ResultType int type, @Nullable ComponentName componentName, + boolean isShortcut) { + mType = type; + mSelectedComponent = componentName; + mIsShortcut = isShortcut; + } + + /** + * The type of the result. + * + * @return the type of the result + */ + @ResultType + public int getType() { + return mType; + } + + /** + * Provides the component of the Activity selected for results with type + * when type is {@link ChooserResult#CHOOSER_RESULT_SELECTED_COMPONENT}. + * <p> + * For all other types, this value is null. + * + * @return the component name selected + */ + @Nullable + public ComponentName getSelectedComponent() { + return mSelectedComponent; + } + + /** + * Whether the selected component was provided by the app from as a shortcut. + * + * @return true if the selected component is a shortcut, false otherwise + */ + public boolean isShortcut() { + return mIsShortcut; + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull + public static final Parcelable.Creator<ChooserResult> CREATOR = + new Creator<>() { + @Override + public ChooserResult createFromParcel(Parcel source) { + return new ChooserResult(source); + } + + @Override + public ChooserResult[] newArray(int size) { + return new ChooserResult[0]; + } + }; + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeInt(mType); + ComponentName.writeToParcel(mSelectedComponent, dest); + dest.writeBoolean(mIsShortcut); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ChooserResult that = (ChooserResult) o; + return mType == that.mType + && mIsShortcut == that.mIsShortcut + && Objects.equals(mSelectedComponent, that.mSelectedComponent); + } + + @Override + public int hashCode() { + return Objects.hash(mType, mSelectedComponent, mIsShortcut); + } +} diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig index 3cc7f5a6ee04..b1172b212317 100644 --- a/core/java/android/service/chooser/flags.aconfig +++ b/core/java/android/service/chooser/flags.aconfig @@ -20,3 +20,10 @@ flag { description: "This flag controls content toggling in Chooser" bug: "302691505" } + +flag { + name: "enable_chooser_result" + namespace: "intentresolver" + description: "Provides additional callbacks with information about user actions in ChooserResult" + bug: "263474465" +} |