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.os.Binder;
     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 mTransientToken;
     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             mTransientToken = new Binder();
    102             mDragAndDropPermissions.takeTransient(mTransientToken);
    103         } catch (RemoteException e) {
    104             return false;
    105         }
    106         return true;
    107     }
    108 
    109     /**
    110      * Revoke permissions explicitly.
    111      */
    112     public void release() {
    113         try {
    114             mDragAndDropPermissions.release();
    115             mTransientToken = null;
    116         } catch (RemoteException e) {
    117         }
    118     }
    119 
    120     public static final Parcelable.Creator<DragAndDropPermissions> CREATOR =
    121             new Parcelable.Creator<DragAndDropPermissions> () {
    122         @Override
    123         public DragAndDropPermissions createFromParcel(Parcel source) {
    124             return new DragAndDropPermissions(source);
    125         }
    126 
    127         @Override
    128         public DragAndDropPermissions[] newArray(int size) {
    129             return new DragAndDropPermissions[size];
    130         }
    131     };
    132 
    133     @Override
    134     public int describeContents() {
    135         return 0;
    136     }
    137 
    138     @Override
    139     public void writeToParcel(Parcel destination, int flags) {
    140         destination.writeStrongInterface(mDragAndDropPermissions);
    141         destination.writeStrongBinder(mTransientToken);
    142     }
    143 
    144     private DragAndDropPermissions(Parcel in) {
    145         mDragAndDropPermissions = IDragAndDropPermissions.Stub.asInterface(in.readStrongBinder());
    146         mTransientToken = in.readStrongBinder();
    147     }
    148 }
    149