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

Commit a0bddd85 authored by Nikita Dubrovsky's avatar Nikita Dubrovsky Committed by Automerger Merge Worker
Browse files

Merge "Update logic for drag-and-drop URI permissions for editable TextViews"...

Merge "Update logic for drag-and-drop URI permissions for editable TextViews" into sc-dev am: 00a7febe

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13606244

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I33c6497d5b1298ab583d49138f8bdb6369253562
parents c50af4fe 00a7febe
Loading
Loading
Loading
Loading
+50 −9
Original line number Diff line number Diff line
@@ -16,12 +16,15 @@

package android.view;

import static java.lang.Integer.toHexString;

import android.app.Activity;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.view.IDragAndDropPermissions;

@@ -56,9 +59,28 @@ import com.android.internal.view.IDragAndDropPermissions;
 */
public final class DragAndDropPermissions implements Parcelable {

    private final IDragAndDropPermissions mDragAndDropPermissions;
    private static final String TAG = "DragAndDrop";
    private static final boolean DEBUG = false;

    private IBinder mTransientToken;
    /**
     * Permissions for a drop can be granted in one of two ways:
     * <ol>
     *     <li>An app can explicitly request permissions using
     *     {@link Activity#requestDragAndDropPermissions(DragEvent)}. In this case permissions are
     *     revoked automatically when then activity is destroyed. See {@link #take(IBinder)}.
     *     <li>The platform can request permissions on behalf of the app (e.g. in
     *     {@link android.widget.Editor}). In this case permissions are revoked automatically when
     *     the app process terminates. See {@link #takeTransient()}.
     * </ol>
     *
     * <p>In order to implement the second case above, we create a static token object here. This
     * ensures that the token stays alive for the lifetime of the app process, allowing us to
     * revoke permissions when the app process terminates using {@link IBinder#linkToDeath} in
     * {@code DragAndDropPermissionsHandler}.
     */
    private static IBinder sAppToken;

    private final IDragAndDropPermissions mDragAndDropPermissions;

    /**
     * Create a new {@link DragAndDropPermissions} object to control the access permissions for
@@ -81,30 +103,51 @@ public final class DragAndDropPermissions implements Parcelable {
    }

    /**
     * Take the permissions and bind their lifetime to the activity.
     * Take permissions, binding their lifetime to the activity.
     *
     * <p>Note: This API is exposed to apps via
     * {@link Activity#requestDragAndDropPermissions(DragEvent)}.
     *
     * @param activityToken Binder pointing to an Activity instance to bind the lifetime to.
     * @return True if permissions are successfully taken.
     *
     * @hide
     */
    public boolean take(IBinder activityToken) {
        try {
            if (DEBUG) {
                Log.d(TAG, this + ": calling take() with activity-bound token: "
                        + toHexString(activityToken.hashCode()));
            }
            mDragAndDropPermissions.take(activityToken);
        } catch (RemoteException e) {
            Log.w(TAG, this + ": take() failed with a RemoteException", e);
            return false;
        }
        return true;
    }

    /**
     * Take the permissions. Must call {@link #release} explicitly.
     * Take permissions transiently. Permissions will be revoked when the app process terminates.
     *
     * <p>Note: This API is not exposed to apps.
     *
     * @return True if permissions are successfully taken.
     *
     * @hide
     */
    public boolean takeTransient() {
        try {
            mTransientToken = new Binder();
            mDragAndDropPermissions.takeTransient(mTransientToken);
            if (sAppToken == null) {
                sAppToken = new Binder();
            }
            if (DEBUG) {
                Log.d(TAG, this + ": calling takeTransient() with process-bound token: "
                        + toHexString(sAppToken.hashCode()));
            }
            mDragAndDropPermissions.takeTransient(sAppToken);
        } catch (RemoteException e) {
            Log.w(TAG, this + ": takeTransient() failed with a RemoteException", e);
            return false;
        }
        return true;
@@ -116,8 +159,8 @@ public final class DragAndDropPermissions implements Parcelable {
    public void release() {
        try {
            mDragAndDropPermissions.release();
            mTransientToken = null;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

@@ -142,11 +185,9 @@ public final class DragAndDropPermissions implements Parcelable {
    @Override
    public void writeToParcel(Parcel destination, int flags) {
        destination.writeStrongInterface(mDragAndDropPermissions);
        destination.writeStrongBinder(mTransientToken);
    }

    private DragAndDropPermissions(Parcel in) {
        mDragAndDropPermissions = IDragAndDropPermissions.Stub.asInterface(in.readStrongBinder());
        mTransientToken = in.readStrongBinder();
    }
}
+0 −3
Original line number Diff line number Diff line
@@ -2904,9 +2904,6 @@ public class Editor {
        } finally {
            mTextView.endBatchEdit();
            mUndoInputFilter.freezeLastEdit();
            if (permissions != null) {
                permissions.release();
            }
        }
    }

+29 −6
Original line number Diff line number Diff line
@@ -16,12 +16,15 @@

package com.android.server.wm;

import static java.lang.Integer.toHexString;

import android.app.UriGrantsManager;
import android.content.ClipData;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.view.IDragAndDropPermissions;
import com.android.server.LocalServices;
@@ -32,6 +35,9 @@ import java.util.ArrayList;
class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub
        implements IBinder.DeathRecipient {

    private static final String TAG = "DragAndDrop";
    private static final boolean DEBUG = false;

    private final WindowManagerGlobalLock mGlobalLock;
    private final int mSourceUid;
    private final String mTargetPackage;
@@ -43,7 +49,7 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub

    private IBinder mActivityToken = null;
    private IBinder mPermissionOwnerToken = null;
    private IBinder mTransientToken = null;
    private IBinder mAppToken = null;

    DragAndDropPermissionsHandler(WindowManagerGlobalLock lock, ClipData clipData, int sourceUid,
            String targetPackage, int mode, int sourceUserId, int targetUserId) {
@@ -62,6 +68,10 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub
        if (mActivityToken != null || mPermissionOwnerToken != null) {
            return;
        }
        if (DEBUG) {
            Log.d(TAG, this + ": taking permissions bound to activity: "
                    + toHexString(activityToken.hashCode()));
        }
        mActivityToken = activityToken;

        // Will throw if Activity is not found.
@@ -84,14 +94,18 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub
    }

    @Override
    public void takeTransient(IBinder transientToken) throws RemoteException {
    public void takeTransient(IBinder appToken) throws RemoteException {
        if (mActivityToken != null || mPermissionOwnerToken != null) {
            return;
        }
        if (DEBUG) {
            Log.d(TAG, this + ": taking permissions bound to app process: "
                    + toHexString(appToken.hashCode()));
        }
        mPermissionOwnerToken = LocalServices.getService(UriGrantsManagerInternal.class)
                .newUriPermissionOwner("drop");
        mTransientToken = transientToken;
        mTransientToken.linkToDeath(this, 0);
        mAppToken = appToken;
        mAppToken.linkToDeath(this, 0);

        doTake(mPermissionOwnerToken);
    }
@@ -112,11 +126,17 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub
            } finally {
                mActivityToken = null;
            }
            if (DEBUG) {
                Log.d(TAG, this + ": releasing activity-bound permissions");
            }
        } else {
            permissionOwner = mPermissionOwnerToken;
            mPermissionOwnerToken = null;
            mTransientToken.unlinkToDeath(this, 0);
            mTransientToken = null;
            mAppToken.unlinkToDeath(this, 0);
            mAppToken = null;
            if (DEBUG) {
                Log.d(TAG, this + ": releasing process-bound permissions");
            }
        }

        UriGrantsManagerInternal ugm = LocalServices.getService(UriGrantsManagerInternal.class);
@@ -139,6 +159,9 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub

    @Override
    public void binderDied() {
        if (DEBUG) {
            Log.d(TAG, this + ": app process died: " + toHexString(mAppToken.hashCode()));
        }
        try {
            release();
        } catch (RemoteException e) {