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

Commit 03b56c22 authored by Vladislav Kaznacheev's avatar Vladislav Kaznacheev Committed by Android (Google) Code Review
Browse files

Merge "Handle content URI permissions on drop"

parents a85e6a44 ede5f548
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -303,6 +303,7 @@ LOCAL_SRC_FILES += \
	core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl \
	core/java/com/android/internal/textservice/ITextServicesManager.aidl \
	core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl \
	core/java/com/android/internal/view/IDropPermissionHolder.aidl \
	core/java/com/android/internal/view/IInputContext.aidl \
	core/java/com/android/internal/view/IInputContextCallback.aidl \
	core/java/com/android/internal/view/IInputMethod.aidl \
+14 −0
Original line number Diff line number Diff line
@@ -34810,6 +34810,7 @@ package android.view {
    method public int getAction();
    method public android.content.ClipData getClipData();
    method public android.content.ClipDescription getClipDescription();
    method public android.view.DropPermissionHolder getDropPermissionHolder();
    method public java.lang.Object getLocalState();
    method public boolean getResult();
    method public float getX();
@@ -34824,6 +34825,14 @@ package android.view {
    field public static final android.os.Parcelable.Creator<android.view.DragEvent> CREATOR;
  }
  public class DropPermissionHolder implements android.os.Parcelable {
    method public int describeContents();
    method public void grant();
    method public void revoke();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.view.DropPermissionHolder> CREATOR;
  }
  public class FocusFinder {
    method public android.view.View findNearestTouchable(android.view.ViewGroup, int, int, int, int[]);
    method public final android.view.View findNextFocus(android.view.ViewGroup, android.view.View, int);
@@ -36527,6 +36536,11 @@ package android.view {
    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
    field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
    field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
    field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
    field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
    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 public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
    field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
+14 −0
Original line number Diff line number Diff line
@@ -37104,6 +37104,7 @@ package android.view {
    method public int getAction();
    method public android.content.ClipData getClipData();
    method public android.content.ClipDescription getClipDescription();
    method public android.view.DropPermissionHolder getDropPermissionHolder();
    method public java.lang.Object getLocalState();
    method public boolean getResult();
    method public float getX();
@@ -37118,6 +37119,14 @@ package android.view {
    field public static final android.os.Parcelable.Creator<android.view.DragEvent> CREATOR;
  }
  public class DropPermissionHolder implements android.os.Parcelable {
    method public int describeContents();
    method public void grant();
    method public void revoke();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.view.DropPermissionHolder> CREATOR;
  }
  public class FocusFinder {
    method public android.view.View findNearestTouchable(android.view.ViewGroup, int, int, int, int[]);
    method public final android.view.View findNextFocus(android.view.ViewGroup, android.view.View, int);
@@ -38821,6 +38830,11 @@ package android.view {
    field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
    field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
    field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
    field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
    field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
    field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
    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 public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
    field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
+31 −6
Original line number Diff line number Diff line
@@ -128,6 +128,8 @@ public class DragEvent implements Parcelable {
    float mX, mY;
    ClipDescription mClipDescription;
    ClipData mClipData;
    DropPermissionHolder mDropPermissionHolder;

    Object mLocalState;
    boolean mDragResult;

@@ -253,28 +255,30 @@ public class DragEvent implements Parcelable {
    }

    private void init(int action, float x, float y, ClipDescription description, ClipData data,
            Object localState, boolean result) {
            DropPermissionHolder dropPermissionHolder, Object localState, boolean result) {
        mAction = action;
        mX = x;
        mY = y;
        mClipDescription = description;
        mClipData = data;
        mDropPermissionHolder = dropPermissionHolder;
        mLocalState = localState;
        mDragResult = result;
    }

    static DragEvent obtain() {
        return DragEvent.obtain(0, 0f, 0f, null, null, null, false);
        return DragEvent.obtain(0, 0f, 0f, null, null, null, null, false);
    }

    /** @hide */
    public static DragEvent obtain(int action, float x, float y, Object localState,
            ClipDescription description, ClipData data, boolean result) {
            ClipDescription description, ClipData data, DropPermissionHolder dropPermissionHolder,
            boolean result) {
        final DragEvent ev;
        synchronized (gRecyclerLock) {
            if (gRecyclerTop == null) {
                ev = new DragEvent();
                ev.init(action, x, y, description, data, localState, result);
                ev.init(action, x, y, description, data, dropPermissionHolder, localState, result);
                return ev;
            }
            ev = gRecyclerTop;
@@ -285,7 +289,7 @@ public class DragEvent implements Parcelable {
        ev.mRecycled = false;
        ev.mNext = null;

        ev.init(action, x, y, description, data, localState, result);
        ev.init(action, x, y, description, data, dropPermissionHolder, localState, result);

        return ev;
    }
@@ -293,7 +297,8 @@ public class DragEvent implements Parcelable {
    /** @hide */
    public static DragEvent obtain(DragEvent source) {
        return obtain(source.mAction, source.mX, source.mY, source.mLocalState,
                source.mClipDescription, source.mClipData, source.mDragResult);
                source.mClipDescription, source.mClipData, source.mDropPermissionHolder,
                source.mDragResult);
    }

    /**
@@ -357,6 +362,17 @@ public class DragEvent implements Parcelable {
        return mClipDescription;
    }

    /**
     * Returns the {@link android.view.DropPermissionHolder} object that can be used by the drag
     * listener to request and release the permissions for the content URIs contained in the
     * {@link android.content.ClipData} object associated with this event.
     * This method only returns valid data if the event action is {@link #ACTION_DROP}.
     * @return The DropPermissionHolder object used to handle content URI permissions.
     */
    public DropPermissionHolder getDropPermissionHolder() {
        return mDropPermissionHolder;
    }

    /**
     * Returns the local state object sent to the system as part of the call to
     * {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}.
@@ -477,6 +493,12 @@ public class DragEvent implements Parcelable {
            dest.writeInt(1);
            mClipDescription.writeToParcel(dest, flags);
        }
        if (mDropPermissionHolder == null) {
            dest.writeInt(0);
        } else {
            dest.writeInt(1);
            mDropPermissionHolder.writeToParcel(dest, flags);
        }
    }

    /**
@@ -496,6 +518,9 @@ public class DragEvent implements Parcelable {
            if (in.readInt() != 0) {
                event.mClipDescription = ClipDescription.CREATOR.createFromParcel(in);
            }
            if (in.readInt() != 0) {
                event.mDropPermissionHolder = DropPermissionHolder.CREATOR.createFromParcel(in);
            }
            return event;
        }

+161 −0
Original line number Diff line number Diff line
package android.view;

import android.app.IActivityManager;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import com.android.internal.view.IDropPermissionHolder;

import java.util.ArrayList;

public class DropPermissionHolder implements Parcelable {

    IDropPermissionHolder mDropPermissionHolder;

    /**
     * Create a new DropPermissionHolder to be passed to the client with a DragEvent.
     *
     * @hide
     */
    public DropPermissionHolder(ClipData clipData, IActivityManager activityManager,
            int sourceUid, String targetPackage, int mode, int sourceUserId, int targetUserId) {
        mDropPermissionHolder = new LocalDropPermissionHolder(clipData, activityManager,
                sourceUid, targetPackage, mode, sourceUserId, targetUserId);
    }

    private class LocalDropPermissionHolder extends IDropPermissionHolder.Stub {

        private final IActivityManager mActivityManager;
        private final int mSourceUid;
        private final String mTargetPackage;
        private final int mMode;
        private final int mSourceUserId;
        private final int mTargetUserId;

        IBinder mPermissionOwner = null;

        final private ArrayList<Uri> mUris = new ArrayList<Uri>();

        LocalDropPermissionHolder(ClipData clipData, IActivityManager activityManager,
                int sourceUid, String targetPackage, int mode, int sourceUserId, int targetUserId) {
            mActivityManager = activityManager;
            mSourceUid = sourceUid;
            mTargetPackage = targetPackage;
            mMode = mode;
            mSourceUserId = sourceUserId;
            mTargetUserId = targetUserId;

            int N = clipData.getItemCount();
            for (int i = 0; i != N; ++i) {
                ClipData.Item item = clipData.getItemAt(i);

                if (item.getUri() != null) {
                    mUris.add(item.getUri());
                }

                Intent intent = item.getIntent();
                if (intent != null && intent.getData() != null) {
                    mUris.add(intent.getData());
                }
            }
        }

        @Override
        public void grant() throws RemoteException {
            if (mPermissionOwner != null) {
                return;
            }

            mPermissionOwner = mActivityManager.newUriPermissionOwner("drop");

            long origId = Binder.clearCallingIdentity();
            try {
                for (Uri mUri : mUris) {
                    mActivityManager.grantUriPermissionFromOwner(
                            mPermissionOwner, mSourceUid, mTargetPackage, mUri, mMode,
                            mSourceUserId, mTargetUserId);
                }
            } finally {
                Binder.restoreCallingIdentity(origId);
            }

        }

        @Override
        public void revoke() throws RemoteException {
            if (mPermissionOwner == null) {
                return;
            }

            for (Uri mUri : mUris) {
                mActivityManager.revokeUriPermissionFromOwner(
                        mPermissionOwner, mUri, mMode, mSourceUserId);
            }

            mPermissionOwner = null;
        }
    }

    /**
     * Request permissions granted by the activity which started the drag.
     */
    public void grant() {
        try {
            mDropPermissionHolder.grant();
        } catch (RemoteException e) {
        }
    }

    /**
     * Revoke permissions granted by the {@link #grant()} call.
     */
    public void revoke() {
        try {
            mDropPermissionHolder.revoke();
        } catch (RemoteException e) {
        }
    }

    /**
     * Returns information about the {@link android.os.Parcel} representation of this
     * DropPermissionHolder object.
     * @return Information about the {@link android.os.Parcel} representation.
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Creates a {@link android.os.Parcel} object from this DropPermissionHolder object.
     * @param dest A {@link android.os.Parcel} object in which to put the DropPermissionHolder
     *             object.
     * @param flags Flags to store in the Parcel.
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStrongBinder(mDropPermissionHolder.asBinder());
    }

    DropPermissionHolder(Parcel in) {
        mDropPermissionHolder = IDropPermissionHolder.Stub.asInterface(in.readStrongBinder());
    }

    /**
     * A container for creating a DropPermissionHolder from a Parcel.
     */
    public static final Parcelable.Creator<DropPermissionHolder> CREATOR
            = new Parcelable.Creator<DropPermissionHolder>() {
        public DropPermissionHolder createFromParcel(Parcel in) {
            return new DropPermissionHolder(in);
        }
        public DropPermissionHolder[] newArray(int size) {
            return new DropPermissionHolder[size];
        }
    };
}
Loading