Home | History | Annotate | Download | only in view
      1 /*
      2 ** Copyright 2015, The Android Open Source Project
      3 **
      4 ** Licensed under the Apache License, Version 2.0 (the "License");
      5 ** you may not use this file except in compliance with the License.
      6 ** You may obtain a copy of the License at
      7 **
      8 **     http://www.apache.org/licenses/LICENSE-2.0
      9 **
     10 ** Unless required by applicable law or agreed to in writing, software
     11 ** distributed under the License is distributed on an "AS IS" BASIS,
     12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 ** See the License for the specific language governing permissions and
     14 ** limitations under the License.
     15 */
     16 
     17 package android.view;
     18 
     19 import android.app.Activity;
     20 import android.app.ActivityManagerNative;
     21 import android.os.IBinder;
     22 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 import android.os.RemoteException;
     25 
     26 import com.android.internal.view.IDragAndDropPermissions;
     27 
     28 /**
     29  * {@link DragAndDropPermissions} controls the access permissions for the content URIs associated
     30  * with a {@link DragEvent}.
     31  * <p>
     32  * Permission are granted when this object is created by {@link
     33  * android.app.Activity#requestDragAndDropPermissions(DragEvent)
     34  * Activity.requestDragAndDropPermissions}.
     35  * Which permissions are granted is defined by the set of flags passed to {@link
     36  * View#startDragAndDrop(android.content.ClipData, View.DragShadowBuilder, Object, int)
     37  * View.startDragAndDrop} by the app that started the drag operation.
     38  * </p>
     39  * <p>
     40  * The life cycle of the permissions is bound to the activity used to call {@link
     41  * android.app.Activity#requestDragAndDropPermissions(DragEvent) requestDragAndDropPermissions}. The
     42  * permissions are revoked when this activity is destroyed, or when {@link #release()} is called,
     43  * whichever occurs first.
     44  * </p>
     45  * <p>
     46  * If you anticipate that your application will receive a large number of drops (e.g. document
     47  * editor), you should try to call {@link #release()} on the obtained permissions as soon as they
     48  * are no longer required. Permissions can be added to your activity's
     49  * {@link Activity#onSaveInstanceState} bundle and later retrieved in order to manually release
     50  * the permissions once they are no longer needed.
     51  * </p>
     52  */
     53 public final class DragAndDropPermissions implements Parcelable {
     54 
     55     private final IDragAndDropPermissions mDragAndDropPermissions;
     56 
     57     private IBinder mPermissionOwnerToken;
     58 
     59     /**
     60      * Create a new {@link DragAndDropPermissions} object to control the access permissions for
     61      * content URIs associated with {@link DragEvent}.
     62      * @param dragEvent Drag event
     63      * @return {@link DragAndDropPermissions} object or null if there are no content URIs associated
     64      * with the {@link DragEvent}.
     65      * @hide
     66      */
     67     public static DragAndDropPermissions obtain(DragEvent dragEvent) {
     68         if (dragEvent.getDragAndDropPermissions() == null) {
     69             return null;
     70         }
     71         return new DragAndDropPermissions(dragEvent.getDragAndDropPermissions());
     72     }
     73 
     74     /** @hide */
     75     private DragAndDropPermissions(IDragAndDropPermissions dragAndDropPermissions) {
     76         mDragAndDropPermissions = dragAndDropPermissions;
     77     }
     78 
     79     /**
     80      * Take the permissions and bind their lifetime to the activity.
     81      * @param activityToken Binder pointing to an Activity instance to bind the lifetime to.
     82      * @return True if permissions are successfully taken.
     83      * @hide
     84      */
     85     public boolean take(IBinder activityToken) {
     86         try {
     87             mDragAndDropPermissions.take(activityToken);
     88         } catch (RemoteException e) {
     89             return false;
     90         }
     91         return true;
     92     }
     93 
     94     /**
     95      * Take the permissions. Must call {@link #release} explicitly.
     96      * @return True if permissions are successfully taken.
     97      * @hide
     98      */
     99     public boolean takeTransient() {
    100         try {
    101             mPermissionOwnerToken = ActivityManagerNative.getDefault().
    102                     newUriPermissionOwner("drop");
    103             mDragAndDropPermissions.takeTransient(mPermissionOwnerToken);
    104         } catch (RemoteException e) {
    105             return false;
    106         }
    107         return true;
    108     }
    109 
    110     /**
    111      * Revoke permissions explicitly.
    112      */
    113     public void release() {
    114         try {
    115             mDragAndDropPermissions.release();
    116             mPermissionOwnerToken = null;
    117         } catch (RemoteException e) {
    118         }
    119     }
    120 
    121     public static final Parcelable.Creator<DragAndDropPermissions> CREATOR =
    122             new Parcelable.Creator<DragAndDropPermissions> () {
    123         @Override
    124         public DragAndDropPermissions createFromParcel(Parcel source) {
    125             return new DragAndDropPermissions(source);
    126         }
    127 
    128         @Override
    129         public DragAndDropPermissions[] newArray(int size) {
    130             return new DragAndDropPermissions[size];
    131         }
    132     };
    133 
    134     @Override
    135     public int describeContents() {
    136         return 0;
    137     }
    138 
    139     @Override
    140     public void writeToParcel(Parcel destination, int flags) {
    141         destination.writeStrongInterface(mDragAndDropPermissions);
    142         destination.writeStrongBinder(mPermissionOwnerToken);
    143     }
    144 
    145     private DragAndDropPermissions(Parcel in) {
    146         mDragAndDropPermissions = IDragAndDropPermissions.Stub.asInterface(in.readStrongBinder());
    147         mPermissionOwnerToken = in.readStrongBinder();
    148     }
    149 }
    150