Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 193145ff authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Update unhandled drag apis based on api council feedback" into main

parents 3e1917f8 af270ce4
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -10089,7 +10089,7 @@ package android.content {
    method public CharSequence coerceToText(android.content.Context);
    method public String getHtmlText();
    method public android.content.Intent getIntent();
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @Nullable public android.app.PendingIntent getPendingIntent();
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @Nullable public android.content.IntentSender getIntentSender();
    method public CharSequence getText();
    method @Nullable public android.view.textclassifier.TextLinks getTextLinks();
    method public android.net.Uri getUri();
@@ -10100,7 +10100,7 @@ package android.content {
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @NonNull public android.content.ClipData.Item build();
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @NonNull public android.content.ClipData.Item.Builder setHtmlText(@Nullable String);
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @NonNull public android.content.ClipData.Item.Builder setIntent(@Nullable android.content.Intent);
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @NonNull public android.content.ClipData.Item.Builder setPendingIntent(@Nullable android.app.PendingIntent);
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @NonNull public android.content.ClipData.Item.Builder setIntentSender(@Nullable android.content.IntentSender);
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @NonNull public android.content.ClipData.Item.Builder setText(@Nullable CharSequence);
    method @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") @NonNull public android.content.ClipData.Item.Builder setUri(@Nullable android.net.Uri);
  }
@@ -53137,7 +53137,7 @@ package android.view {
    field public static final int DRAG_FLAG_GLOBAL_URI_READ = 1; // 0x1
    field public static final int DRAG_FLAG_GLOBAL_URI_WRITE = 2; // 0x2
    field public static final int DRAG_FLAG_OPAQUE = 512; // 0x200
    field @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") public static final int DRAG_FLAG_START_PENDING_INTENT_ON_UNHANDLED_DRAG = 8192; // 0x2000
    field @FlaggedApi("com.android.window.flags.delegate_unhandled_drags") public static final int DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG = 8192; // 0x2000
    field @Deprecated public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
    field @Deprecated public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
    field @Deprecated public static final int DRAWING_CACHE_QUALITY_LOW = 524288; // 0x80000
+22 −52
Original line number Diff line number Diff line
@@ -26,8 +26,6 @@ import static com.android.window.flags.Flags.FLAG_DELEGATE_UNHANDLED_DRAGS;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.res.AssetFileDescriptor;
@@ -213,7 +211,7 @@ public class ClipData implements Parcelable {
        final CharSequence mText;
        final String mHtmlText;
        final Intent mIntent;
        final PendingIntent mPendingIntent;
        final IntentSender mIntentSender;
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        Uri mUri;
        private TextLinks mTextLinks;
@@ -225,12 +223,11 @@ public class ClipData implements Parcelable {
         * A builder for a ClipData Item.
         */
        @FlaggedApi(FLAG_DELEGATE_UNHANDLED_DRAGS)
        @SuppressLint("PackageLayering")
        public static final class Builder {
            private CharSequence mText;
            private String mHtmlText;
            private Intent mIntent;
            private PendingIntent mPendingIntent;
            private IntentSender mIntentSender;
            private Uri mUri;

            /**
@@ -264,18 +261,20 @@ public class ClipData implements Parcelable {
            }

            /**
             * Sets the PendingIntent for the item to be constructed. To prevent receiving apps from
             * improperly manipulating the intent to launch another activity as this caller, the
             * provided PendingIntent must be immutable (see {@link PendingIntent#FLAG_IMMUTABLE}).
             * The system will clean up the PendingIntent when it is no longer used.
             * Sets the {@link IntentSender} for the item to be constructed. To prevent receiving
             * apps from improperly manipulating the intent to launch another activity as this
             * caller, the provided IntentSender must be immutable.
             *
             * If there is a fixed lifetime for this ClipData (ie. for drag and drop), the system
             * will cancel the IntentSender when it is no longer used.
             */
            @FlaggedApi(FLAG_DELEGATE_UNHANDLED_DRAGS)
            @NonNull
            public Builder setPendingIntent(@Nullable PendingIntent pendingIntent) {
                if (pendingIntent != null && !pendingIntent.isImmutable()) {
                    throw new IllegalArgumentException("Expected pending intent to be immutable");
            public Builder setIntentSender(@Nullable IntentSender intentSender) {
                if (intentSender != null && !intentSender.isImmutable()) {
                    throw new IllegalArgumentException("Expected intent sender to be immutable");
                }
                mPendingIntent = pendingIntent;
                mIntentSender = intentSender;
                return this;
            }

@@ -295,7 +294,7 @@ public class ClipData implements Parcelable {
            @FlaggedApi(FLAG_DELEGATE_UNHANDLED_DRAGS)
            @NonNull
            public Item build() {
                return new Item(mText, mHtmlText, mIntent, mPendingIntent, mUri);
                return new Item(mText, mHtmlText, mIntent, mIntentSender, mUri);
            }
        }

@@ -305,7 +304,7 @@ public class ClipData implements Parcelable {
            mText = other.mText;
            mHtmlText = other.mHtmlText;
            mIntent = other.mIntent;
            mPendingIntent = other.mPendingIntent;
            mIntentSender = other.mIntentSender;
            mUri = other.mUri;
            mActivityInfo = other.mActivityInfo;
            mTextLinks = other.mTextLinks;
@@ -366,7 +365,7 @@ public class ClipData implements Parcelable {
        /**
         * Builder ctor.
         */
        private Item(CharSequence text, String htmlText, Intent intent, PendingIntent pendingIntent,
        private Item(CharSequence text, String htmlText, Intent intent, IntentSender intentSender,
                Uri uri) {
            if (htmlText != null && text == null) {
                throw new IllegalArgumentException(
@@ -375,7 +374,7 @@ public class ClipData implements Parcelable {
            mText = text;
            mHtmlText = htmlText;
            mIntent = intent;
            mPendingIntent = pendingIntent;
            mIntentSender = intentSender;
            mUri = uri;
        }

@@ -401,12 +400,12 @@ public class ClipData implements Parcelable {
        }

        /**
         * Returns the pending intent in this Item.
         * Returns the {@link IntentSender} in this Item.
         */
        @FlaggedApi(FLAG_DELEGATE_UNHANDLED_DRAGS)
        @Nullable
        public PendingIntent getPendingIntent() {
            return mPendingIntent;
        public IntentSender getIntentSender() {
            return mIntentSender;
        }

        /**
@@ -1130,35 +1129,6 @@ public class ClipData implements Parcelable {
        prepareToLeaveProcess(leavingPackage, Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }

    /**
     * Checks if this clip data has a pending intent that is an activity type.
     * @hide
     */
    public boolean hasActivityPendingIntents() {
        final int size = mItems.size();
        for (int i = 0; i < size; i++) {
            final Item item = mItems.get(i);
            if (item.mPendingIntent != null && item.mPendingIntent.isActivity()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Cleans up all pending intents in the ClipData.
     * @hide
     */
    public void cleanUpPendingIntents() {
        final int size = mItems.size();
        for (int i = 0; i < size; i++) {
            final Item item = mItems.get(i);
            if (item.mPendingIntent != null) {
                item.mPendingIntent.cancel();
            }
        }
    }

    /**
     * Prepare this {@link ClipData} to leave an app process.
     *
@@ -1361,7 +1331,7 @@ public class ClipData implements Parcelable {
            TextUtils.writeToParcel(item.mText, dest, flags);
            dest.writeString8(item.mHtmlText);
            dest.writeTypedObject(item.mIntent, flags);
            dest.writeTypedObject(item.mPendingIntent, flags);
            dest.writeTypedObject(item.mIntentSender, flags);
            dest.writeTypedObject(item.mUri, flags);
            dest.writeTypedObject(mParcelItemActivityInfos ? item.mActivityInfo : null, flags);
            dest.writeTypedObject(item.mTextLinks, flags);
@@ -1381,11 +1351,11 @@ public class ClipData implements Parcelable {
            CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
            String htmlText = in.readString8();
            Intent intent = in.readTypedObject(Intent.CREATOR);
            PendingIntent pendingIntent = in.readTypedObject(PendingIntent.CREATOR);
            IntentSender intentSender = in.readTypedObject(IntentSender.CREATOR);
            Uri uri = in.readTypedObject(Uri.CREATOR);
            ActivityInfo info = in.readTypedObject(ActivityInfo.CREATOR);
            TextLinks textLinks = in.readTypedObject(TextLinks.CREATOR);
            Item item = new Item(text, htmlText, intent, pendingIntent, uri);
            Item item = new Item(text, htmlText, intent, intentSender, uri);
            item.setActivityInfo(info);
            item.setTextLinks(textLinks);
            mItems.add(item);
+41 −7
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ import android.content.ClipDescription;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentSender;
import android.content.res.ColorStateList;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -5357,16 +5358,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
    /**
     * Flag indicating that an unhandled drag should be delegated to the system to be started if no
     * visible window wishes to handle the drop. When using this flag, the caller must provide
     * ClipData with an Item that contains an immutable PendingIntent to an activity to be launched
     * ClipData with an Item that contains an immutable IntentSender to an activity to be launched
     * (not a broadcast, service, etc).  See
     * {@link ClipData.Item.Builder#setPendingIntent(PendingIntent)}.
     * {@link ClipData.Item.Builder#setIntentSender(IntentSender)}.
     *
     * The system can decide to launch the intent or not based on factors like the current screen
     * size or windowing mode. If the system does not launch the intent, it will be canceled via the
     * normal drag and drop flow.
     */
    @FlaggedApi(FLAG_DELEGATE_UNHANDLED_DRAGS)
    public static final int DRAG_FLAG_START_PENDING_INTENT_ON_UNHANDLED_DRAG = 1 << 13;
    public static final int DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG = 1 << 13;
    /**
     * Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
@@ -28665,10 +28666,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
            if (com.android.window.flags.Flags.delegateUnhandledDrags()) {
                data.prepareToLeaveProcess(
                        (flags & (DRAG_FLAG_GLOBAL_SAME_APPLICATION | DRAG_FLAG_GLOBAL)) != 0);
                if ((flags & DRAG_FLAG_START_PENDING_INTENT_ON_UNHANDLED_DRAG) != 0) {
                    if (!data.hasActivityPendingIntents()) {
                if ((flags & DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG) != 0) {
                    if (!hasActivityPendingIntents(data)) {
                        // Reset the flag if there is no launchable activity intent
                        flags &= ~DRAG_FLAG_START_PENDING_INTENT_ON_UNHANDLED_DRAG;
                        flags &= ~DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG;
                        Log.w(VIEW_LOG_TAG, "startDragAndDrop called with "
                                + "DRAG_FLAG_START_INTENT_ON_UNHANDLED_DRAG but the clip data "
                                + "contains non-activity PendingIntents");
@@ -28781,7 +28782,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                    mAttachInfo.mDragSurface.release();
                }
                if (mAttachInfo.mDragData != null) {
                    mAttachInfo.mDragData.cleanUpPendingIntents();
                    View.cleanUpPendingIntents(mAttachInfo.mDragData);
                }
                mAttachInfo.mDragSurface = surface;
                mAttachInfo.mDragToken = token;
@@ -28806,6 +28807,39 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        }
    }
     /**
     * Checks if this clip data has a pending intent that is an activity type.
     * @hide
     */
    static boolean hasActivityPendingIntents(ClipData data) {
        final int size = data.getItemCount();
        for (int i = 0; i < size; i++) {
            final ClipData.Item item = data.getItemAt(i);
            if (item.getIntentSender() != null) {
                final PendingIntent pi = new PendingIntent(item.getIntentSender().getTarget());
                if (pi.isActivity()) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * Cleans up all pending intents in the ClipData.
     * @hide
     */
    static void cleanUpPendingIntents(ClipData data) {
        final int size = data.getItemCount();
        for (int i = 0; i < size; i++) {
            final ClipData.Item item = data.getItemAt(i);
            if (item.getIntentSender() != null) {
                final PendingIntent pi = new PendingIntent(item.getIntentSender().getTarget());
                pi.cancel();
            }
        }
    }
    void setAccessibilityDragStarted(boolean started) {
        int pflags4 = mPrivateFlags4;
        if (started) {
+1 −1
Original line number Diff line number Diff line
@@ -8626,7 +8626,7 @@ public final class ViewRootImpl implements ViewParent,
                        mAttachInfo.mDragSurface = null;
                    }
                    if (mAttachInfo.mDragData != null) {
                        mAttachInfo.mDragData.cleanUpPendingIntents();
                        View.cleanUpPendingIntents(mAttachInfo.mDragData);
                        mAttachInfo.mDragData = null;
                    }
                }