DragAndDropPermissions.java revision 377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3
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
17package android.view;
18
19import android.app.ActivityManagerNative;
20import android.os.IBinder;
21import android.os.RemoteException;
22import com.android.internal.view.IDragAndDropPermissions;
23import dalvik.system.CloseGuard;
24
25
26/**
27 * {@link DragAndDropPermissions} controls the access permissions for the content URIs associated
28 * with a {@link DragEvent}.
29 * <p>
30 * Permission are granted when this object is created by {@link
31 * android.app.Activity#requestDragAndDropPermissions(DragEvent)
32 * Activity.requestDragAndDropPermissions}.
33 * Which permissions are granted is defined by the set of flags passed to {@link
34 * View#startDragAndDrop(android.content.ClipData, View.DragShadowBuilder, Object, int)
35 * View.startDragAndDrop} by the app that started the drag operation.
36 * <p>
37 * The life cycle of the permissions is bound to the activity used to call {@link
38 * android.app.Activity#requestDragAndDropPermissions(DragEvent) requestDragAndDropPermissions}. The
39 * permissions are revoked when this activity is destroyed, or when {@link #release()} is called,
40 * whichever occurs first.
41 */
42public final class DragAndDropPermissions {
43
44    private final IDragAndDropPermissions mDragAndDropPermissions;
45
46    private IBinder mPermissionOwnerToken;
47
48    private final CloseGuard mCloseGuard = CloseGuard.get();
49
50    /**
51     * Create a new {@link DragAndDropPermissions} object to control the access permissions for
52     * content URIs associated with {@link DragEvent}.
53     * @param dragEvent Drag event
54     * @return {@link DragAndDropPermissions} object or null if there are no content URIs associated
55     * with the {@link DragEvent}.
56     * @hide
57     */
58    public static DragAndDropPermissions obtain(DragEvent dragEvent) {
59        if (dragEvent.getDragAndDropPermissions() == null) {
60            return null;
61        }
62        return new DragAndDropPermissions(dragEvent.getDragAndDropPermissions());
63    }
64
65    /** @hide */
66    private DragAndDropPermissions(IDragAndDropPermissions dragAndDropPermissions) {
67        mDragAndDropPermissions = dragAndDropPermissions;
68    }
69
70    /**
71     * Take the permissions and bind their lifetime to the activity.
72     * @param activityToken Binder pointing to an Activity instance to bind the lifetime to.
73     * @return True if permissions are successfully taken.
74     * @hide
75     */
76    public boolean take(IBinder activityToken) {
77        try {
78            mDragAndDropPermissions.take(activityToken);
79        } catch (RemoteException e) {
80            return false;
81        }
82        mCloseGuard.open("release");
83        return true;
84    }
85
86    /**
87     * Take the permissions. Must call {@link #release} explicitly.
88     * @return True if permissions are successfully taken.
89     * @hide
90     */
91    public boolean takeTransient() {
92        try {
93            mPermissionOwnerToken = ActivityManagerNative.getDefault().
94                    newUriPermissionOwner("drop");
95            mDragAndDropPermissions.takeTransient(mPermissionOwnerToken);
96        } catch (RemoteException e) {
97            return false;
98        }
99        mCloseGuard.open("release");
100        return true;
101    }
102
103    /**
104     * Revoke permissions explicitly.
105     */
106    public void release() {
107        try {
108            mDragAndDropPermissions.release();
109            mPermissionOwnerToken = null;
110        } catch (RemoteException e) {
111        }
112        mCloseGuard.close();
113    }
114
115    @Override
116    protected void finalize() throws Throwable {
117        try {
118            if (mCloseGuard != null) {
119                mCloseGuard.warnIfOpen();
120            }
121            release();
122        } finally {
123            super.finalize();
124        }
125    }
126}
127