19149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev/*
29149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** Copyright 2015, The Android Open Source Project
39149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev**
49149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** Licensed under the Apache License, Version 2.0 (the "License");
59149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** you may not use this file except in compliance with the License.
69149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** You may obtain a copy of the License at
79149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev**
89149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev**     http://www.apache.org/licenses/LICENSE-2.0
99149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev**
109149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** Unless required by applicable law or agreed to in writing, software
119149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** distributed under the License is distributed on an "AS IS" BASIS,
129149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** See the License for the specific language governing permissions and
149149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev** limitations under the License.
159149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev*/
169149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev
179149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheevpackage android.view;
189149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev
19c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Leeimport android.app.Activity;
20c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheevimport android.app.ActivityManagerNative;
21b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheevimport android.os.IBinder;
22c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Leeimport android.os.Parcel;
23c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Leeimport android.os.Parcelable;
249149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheevimport android.os.RemoteException;
259149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev
26c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Leeimport com.android.internal.view.IDragAndDropPermissions;
279149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev
28b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev/**
29377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev * {@link DragAndDropPermissions} controls the access permissions for the content URIs associated
30377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev * with a {@link DragEvent}.
31b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * <p>
32b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * Permission are granted when this object is created by {@link
33377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev * android.app.Activity#requestDragAndDropPermissions(DragEvent)
34377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev * Activity.requestDragAndDropPermissions}.
35b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * Which permissions are granted is defined by the set of flags passed to {@link
36b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * View#startDragAndDrop(android.content.ClipData, View.DragShadowBuilder, Object, int)
37b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * View.startDragAndDrop} by the app that started the drag operation.
38c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * </p>
39b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * <p>
40b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * The life cycle of the permissions is bound to the activity used to call {@link
41377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev * android.app.Activity#requestDragAndDropPermissions(DragEvent) requestDragAndDropPermissions}. The
42b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * permissions are revoked when this activity is destroyed, or when {@link #release()} is called,
43b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev * whichever occurs first.
44c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * </p>
45c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * <p>
46c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * If you anticipate that your application will receive a large number of drops (e.g. document
47c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * editor), you should try to call {@link #release()} on the obtained permissions as soon as they
48c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * are no longer required. Permissions can be added to your activity's
49c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * {@link Activity#onSaveInstanceState} bundle and later retrieved in order to manually release
50c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * the permissions once they are no longer needed.
51c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee * </p>
52b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev */
53c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Leepublic final class DragAndDropPermissions implements Parcelable {
549149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev
55377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev    private final IDragAndDropPermissions mDragAndDropPermissions;
569149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev
57c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev    private IBinder mPermissionOwnerToken;
58c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev
599149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev    /**
60377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev     * Create a new {@link DragAndDropPermissions} object to control the access permissions for
61377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev     * content URIs associated with {@link DragEvent}.
62b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev     * @param dragEvent Drag event
63377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev     * @return {@link DragAndDropPermissions} object or null if there are no content URIs associated
64377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev     * with the {@link DragEvent}.
659149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev     * @hide
669149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev     */
67377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev    public static DragAndDropPermissions obtain(DragEvent dragEvent) {
68377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev        if (dragEvent.getDragAndDropPermissions() == null) {
69b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev            return null;
70b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev        }
71377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev        return new DragAndDropPermissions(dragEvent.getDragAndDropPermissions());
72b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev    }
73b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev
74b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev    /** @hide */
75377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev    private DragAndDropPermissions(IDragAndDropPermissions dragAndDropPermissions) {
76377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev        mDragAndDropPermissions = dragAndDropPermissions;
77b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev    }
78b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev
79b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev    /**
80b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev     * Take the permissions and bind their lifetime to the activity.
81b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev     * @param activityToken Binder pointing to an Activity instance to bind the lifetime to.
82b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev     * @return True if permissions are successfully taken.
83b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev     * @hide
84b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev     */
85b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev    public boolean take(IBinder activityToken) {
869149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev        try {
87377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev            mDragAndDropPermissions.take(activityToken);
889149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev        } catch (RemoteException e) {
89b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev            return false;
909149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev        }
91b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev        return true;
929149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev    }
939149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev
949149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev    /**
95c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev     * Take the permissions. Must call {@link #release} explicitly.
96c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev     * @return True if permissions are successfully taken.
97c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev     * @hide
98c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev     */
99c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev    public boolean takeTransient() {
100c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev        try {
101c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev            mPermissionOwnerToken = ActivityManagerNative.getDefault().
102c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev                    newUriPermissionOwner("drop");
103377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev            mDragAndDropPermissions.takeTransient(mPermissionOwnerToken);
104c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev        } catch (RemoteException e) {
105c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev            return false;
106c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev        }
107c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev        return true;
108c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev    }
109c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev
110c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev    /**
111b23a757aa2f3088c9e9fd226e806aa5963b68d93Vladislav Kaznacheev     * Revoke permissions explicitly.
1129149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev     */
1139149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev    public void release() {
1149149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev        try {
115377c32845bffaf68d5751d8cdf6fd60b8b3f5dc3Vladislav Kaznacheev            mDragAndDropPermissions.release();
116c14df8e73d093f839c4ea2585eade6ae6690d224Vladislav Kaznacheev            mPermissionOwnerToken = null;
1179149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev        } catch (RemoteException e) {
1189149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev        }
1199149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev    }
1209149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev
121c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    public static final Parcelable.Creator<DragAndDropPermissions> CREATOR =
122c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee            new Parcelable.Creator<DragAndDropPermissions> () {
123c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        @Override
124c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        public DragAndDropPermissions createFromParcel(Parcel source) {
125c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee            return new DragAndDropPermissions(source);
126c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        }
127c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee
128c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        @Override
129c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        public DragAndDropPermissions[] newArray(int size) {
130c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee            return new DragAndDropPermissions[size];
1319149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev        }
132c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    };
133c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee
134c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    @Override
135c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    public int describeContents() {
136c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        return 0;
137c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    }
138c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee
139c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    @Override
140c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    public void writeToParcel(Parcel destination, int flags) {
141c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        destination.writeStrongInterface(mDragAndDropPermissions);
142c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        destination.writeStrongBinder(mPermissionOwnerToken);
143c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    }
144c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee
145c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee    private DragAndDropPermissions(Parcel in) {
146c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        mDragAndDropPermissions = IDragAndDropPermissions.Stub.asInterface(in.readStrongBinder());
147c8ad0cd316cf115d666aee5c61038119473c2a32Yorke Lee        mPermissionOwnerToken = in.readStrongBinder();
1489149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev    }
1499149d2b117aef40f38a7d62c0f8c2bb76eb4e244Vladislav Kaznacheev}
150