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