Rename and simplify DropPermissionHolder

Rename DropPermissionHolder to DropPermissions and move
all server-side implementation details into a separate class.
Rename DragEvent.getDropPermissionHolder to
requestDropPermissions and make it take the permissions
implicitly.

Change-Id: Ia83f7cb8af07ce13ba9536d24b0f9d63331d8736
This commit is contained in:
Vladislav Kaznacheev
2015-12-15 12:16:28 -08:00
parent 3a0ea6254d
commit 9149d2b117
12 changed files with 221 additions and 214 deletions

View File

@@ -308,7 +308,7 @@ LOCAL_SRC_FILES += \
core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl \
core/java/com/android/internal/textservice/ITextServicesManager.aidl \
core/java/com/android/internal/textservice/ITextServicesSessionListener.aidl \
core/java/com/android/internal/view/IDropPermissionHolder.aidl \
core/java/com/android/internal/view/IDropPermissions.aidl \
core/java/com/android/internal/view/IInputContext.aidl \
core/java/com/android/internal/view/IInputContextCallback.aidl \
core/java/com/android/internal/view/IInputMethod.aidl \

View File

@@ -39298,11 +39298,11 @@ package android.view {
method public int getAction();
method public android.content.ClipData getClipData();
method public android.content.ClipDescription getClipDescription();
method public android.view.DropPermissionHolder getDropPermissionHolder();
method public java.lang.Object getLocalState();
method public boolean getResult();
method public float getX();
method public float getY();
method public android.view.DropPermissions requestDropPermissions();
method public void writeToParcel(android.os.Parcel, int);
field public static final int ACTION_DRAG_ENDED = 4; // 0x4
field public static final int ACTION_DRAG_ENTERED = 5; // 0x5
@@ -39313,12 +39313,8 @@ package android.view {
field public static final android.os.Parcelable.Creator<android.view.DragEvent> CREATOR;
}
public class DropPermissionHolder implements android.os.Parcelable {
method public int describeContents();
method public void grant();
method public void revoke();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.DropPermissionHolder> CREATOR;
public final class DropPermissions {
method public void release();
}
public class FocusFinder {

View File

@@ -41650,11 +41650,11 @@ package android.view {
method public int getAction();
method public android.content.ClipData getClipData();
method public android.content.ClipDescription getClipDescription();
method public android.view.DropPermissionHolder getDropPermissionHolder();
method public java.lang.Object getLocalState();
method public boolean getResult();
method public float getX();
method public float getY();
method public android.view.DropPermissions requestDropPermissions();
method public void writeToParcel(android.os.Parcel, int);
field public static final int ACTION_DRAG_ENDED = 4; // 0x4
field public static final int ACTION_DRAG_ENTERED = 5; // 0x5
@@ -41665,12 +41665,8 @@ package android.view {
field public static final android.os.Parcelable.Creator<android.view.DragEvent> CREATOR;
}
public class DropPermissionHolder implements android.os.Parcelable {
method public int describeContents();
method public void grant();
method public void revoke();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.DropPermissionHolder> CREATOR;
public final class DropPermissions {
method public void release();
}
public class FocusFinder {

View File

@@ -39300,11 +39300,11 @@ package android.view {
method public int getAction();
method public android.content.ClipData getClipData();
method public android.content.ClipDescription getClipDescription();
method public android.view.DropPermissionHolder getDropPermissionHolder();
method public java.lang.Object getLocalState();
method public boolean getResult();
method public float getX();
method public float getY();
method public android.view.DropPermissions requestDropPermissions();
method public void writeToParcel(android.os.Parcel, int);
field public static final int ACTION_DRAG_ENDED = 4; // 0x4
field public static final int ACTION_DRAG_ENTERED = 5; // 0x5
@@ -39315,12 +39315,8 @@ package android.view {
field public static final android.os.Parcelable.Creator<android.view.DragEvent> CREATOR;
}
public class DropPermissionHolder implements android.os.Parcelable {
method public int describeContents();
method public void grant();
method public void revoke();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.DropPermissionHolder> CREATOR;
public final class DropPermissions {
method public void release();
}
public class FocusFinder {

View File

@@ -36,6 +36,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
* Representation of a clipped data on the clipboard.
@@ -914,6 +915,27 @@ public class ClipData implements Parcelable {
}
}
/** @hide */
public void collectUris(List<Uri> out) {
for (int i = 0; i < mItems.size(); ++i) {
ClipData.Item item = getItemAt(i);
if (item.getUri() != null) {
out.add(item.getUri());
}
Intent intent = item.getIntent();
if (intent != null) {
if (intent.getData() != null) {
out.add(intent.getData());
}
if (intent.getClipData() != null) {
intent.getClipData().collectUris(out);
}
}
}
}
@Override
public int describeContents() {
return 0;

View File

@@ -21,6 +21,8 @@ import android.content.ClipDescription;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.view.IDropPermissions;
//TODO: Improve Javadoc
/**
* Represents an event that is sent out by the system at various times during a drag and drop
@@ -128,7 +130,7 @@ public class DragEvent implements Parcelable {
float mX, mY;
ClipDescription mClipDescription;
ClipData mClipData;
DropPermissionHolder mDropPermissionHolder;
IDropPermissions mDropPermissions;
Object mLocalState;
boolean mDragResult;
@@ -146,7 +148,7 @@ public class DragEvent implements Parcelable {
* Action constant returned by {@link #getAction()}: Signals the start of a
* drag and drop operation. The View should return {@code true} from its
* {@link View#onDragEvent(DragEvent) onDragEvent()} handler method or
* {@link View.View.OnDragListener#onDrag(View,DragEvent) OnDragListener.onDrag()} listener
* {@link View.OnDragListener#onDrag(View,DragEvent) OnDragListener.onDrag()} listener
* if it can accept a drop. The onDragEvent() or onDrag() methods usually inspect the metadata
* from {@link #getClipDescription()} to determine if they can accept the data contained in
* this drag. For an operation that doesn't represent data transfer, these methods may
@@ -190,7 +192,7 @@ public class DragEvent implements Parcelable {
* within the View object's bounding box.
* <p>
* The View should return {@code true} from its {@link View#onDragEvent(DragEvent)}
* handler or {@link View.View.OnDragListener#onDrag(View,DragEvent) OnDragListener.onDrag()}
* handler or {@link View.OnDragListener#onDrag(View,DragEvent) OnDragListener.onDrag()}
* listener if it accepted the drop, and {@code false} if it ignored the drop.
* </p>
* <p>
@@ -255,13 +257,13 @@ public class DragEvent implements Parcelable {
}
private void init(int action, float x, float y, ClipDescription description, ClipData data,
DropPermissionHolder dropPermissionHolder, Object localState, boolean result) {
IDropPermissions dropPermissions, Object localState, boolean result) {
mAction = action;
mX = x;
mY = y;
mClipDescription = description;
mClipData = data;
mDropPermissionHolder = dropPermissionHolder;
mDropPermissions = dropPermissions;
mLocalState = localState;
mDragResult = result;
}
@@ -272,13 +274,13 @@ public class DragEvent implements Parcelable {
/** @hide */
public static DragEvent obtain(int action, float x, float y, Object localState,
ClipDescription description, ClipData data, DropPermissionHolder dropPermissionHolder,
ClipDescription description, ClipData data, IDropPermissions dropPermissions,
boolean result) {
final DragEvent ev;
synchronized (gRecyclerLock) {
if (gRecyclerTop == null) {
ev = new DragEvent();
ev.init(action, x, y, description, data, dropPermissionHolder, localState, result);
ev.init(action, x, y, description, data, dropPermissions, localState, result);
return ev;
}
ev = gRecyclerTop;
@@ -289,7 +291,7 @@ public class DragEvent implements Parcelable {
ev.mRecycled = false;
ev.mNext = null;
ev.init(action, x, y, description, data, dropPermissionHolder, localState, result);
ev.init(action, x, y, description, data, dropPermissions, localState, result);
return ev;
}
@@ -297,7 +299,7 @@ public class DragEvent implements Parcelable {
/** @hide */
public static DragEvent obtain(DragEvent source) {
return obtain(source.mAction, source.mX, source.mY, source.mLocalState,
source.mClipDescription, source.mClipData, source.mDropPermissionHolder,
source.mClipDescription, source.mClipData, source.mDropPermissions,
source.mDragResult);
}
@@ -363,14 +365,19 @@ public class DragEvent implements Parcelable {
}
/**
* Returns the {@link android.view.DropPermissionHolder} object that can be used by the drag
* listener to request and release the permissions for the content URIs contained in the
* {@link android.content.ClipData} object associated with this event.
* Requests the permissions for the content URIs contained in {@link android.content.ClipData}
* object associated with this event. Which permissions will be granted is defined by the set of
* flags passed to {@link View#startDragAndDrop(ClipData, View.DragShadowBuilder, Object, int)}.
* Returns the {@link DropPermissions} object that can be used by the receiving app to release
* the permissions for the content URIs when they are no longer needed.
* This method only returns valid data if the event action is {@link #ACTION_DROP}.
* @return The DropPermissionHolder object used to handle content URI permissions.
* @return The DropPermissions object used to control access to the content URIs.
*/
public DropPermissionHolder getDropPermissionHolder() {
return mDropPermissionHolder;
public DropPermissions requestDropPermissions() {
if (mDropPermissions == null) {
return null;
}
return new DropPermissions(mDropPermissions);
}
/**
@@ -493,11 +500,11 @@ public class DragEvent implements Parcelable {
dest.writeInt(1);
mClipDescription.writeToParcel(dest, flags);
}
if (mDropPermissionHolder == null) {
if (mDropPermissions == null) {
dest.writeInt(0);
} else {
dest.writeInt(1);
mDropPermissionHolder.writeToParcel(dest, flags);
dest.writeStrongBinder(mDropPermissions.asBinder());
}
}
@@ -519,7 +526,7 @@ public class DragEvent implements Parcelable {
event.mClipDescription = ClipDescription.CREATOR.createFromParcel(in);
}
if (in.readInt() != 0) {
event.mDropPermissionHolder = DropPermissionHolder.CREATOR.createFromParcel(in);
event.mDropPermissions = IDropPermissions.Stub.asInterface(in.readStrongBinder());;
}
return event;
}

View File

@@ -1,161 +0,0 @@
package android.view;
import android.app.IActivityManager;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import com.android.internal.view.IDropPermissionHolder;
import java.util.ArrayList;
public class DropPermissionHolder implements Parcelable {
IDropPermissionHolder mDropPermissionHolder;
/**
* Create a new DropPermissionHolder to be passed to the client with a DragEvent.
*
* @hide
*/
public DropPermissionHolder(ClipData clipData, IActivityManager activityManager,
int sourceUid, String targetPackage, int mode, int sourceUserId, int targetUserId) {
mDropPermissionHolder = new LocalDropPermissionHolder(clipData, activityManager,
sourceUid, targetPackage, mode, sourceUserId, targetUserId);
}
private class LocalDropPermissionHolder extends IDropPermissionHolder.Stub {
private final IActivityManager mActivityManager;
private final int mSourceUid;
private final String mTargetPackage;
private final int mMode;
private final int mSourceUserId;
private final int mTargetUserId;
IBinder mPermissionOwner = null;
final private ArrayList<Uri> mUris = new ArrayList<Uri>();
LocalDropPermissionHolder(ClipData clipData, IActivityManager activityManager,
int sourceUid, String targetPackage, int mode, int sourceUserId, int targetUserId) {
mActivityManager = activityManager;
mSourceUid = sourceUid;
mTargetPackage = targetPackage;
mMode = mode;
mSourceUserId = sourceUserId;
mTargetUserId = targetUserId;
int N = clipData.getItemCount();
for (int i = 0; i != N; ++i) {
ClipData.Item item = clipData.getItemAt(i);
if (item.getUri() != null) {
mUris.add(item.getUri());
}
Intent intent = item.getIntent();
if (intent != null && intent.getData() != null) {
mUris.add(intent.getData());
}
}
}
@Override
public void grant() throws RemoteException {
if (mPermissionOwner != null) {
return;
}
mPermissionOwner = mActivityManager.newUriPermissionOwner("drop");
long origId = Binder.clearCallingIdentity();
try {
for (Uri mUri : mUris) {
mActivityManager.grantUriPermissionFromOwner(
mPermissionOwner, mSourceUid, mTargetPackage, mUri, mMode,
mSourceUserId, mTargetUserId);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
@Override
public void revoke() throws RemoteException {
if (mPermissionOwner == null) {
return;
}
for (Uri mUri : mUris) {
mActivityManager.revokeUriPermissionFromOwner(
mPermissionOwner, mUri, mMode, mSourceUserId);
}
mPermissionOwner = null;
}
}
/**
* Request permissions granted by the activity which started the drag.
*/
public void grant() {
try {
mDropPermissionHolder.grant();
} catch (RemoteException e) {
}
}
/**
* Revoke permissions granted by the {@link #grant()} call.
*/
public void revoke() {
try {
mDropPermissionHolder.revoke();
} catch (RemoteException e) {
}
}
/**
* Returns information about the {@link android.os.Parcel} representation of this
* DropPermissionHolder object.
* @return Information about the {@link android.os.Parcel} representation.
*/
@Override
public int describeContents() {
return 0;
}
/**
* Creates a {@link android.os.Parcel} object from this DropPermissionHolder object.
* @param dest A {@link android.os.Parcel} object in which to put the DropPermissionHolder
* object.
* @param flags Flags to store in the Parcel.
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStrongBinder(mDropPermissionHolder.asBinder());
}
DropPermissionHolder(Parcel in) {
mDropPermissionHolder = IDropPermissionHolder.Stub.asInterface(in.readStrongBinder());
}
/**
* A container for creating a DropPermissionHolder from a Parcel.
*/
public static final Parcelable.Creator<DropPermissionHolder> CREATOR
= new Parcelable.Creator<DropPermissionHolder>() {
public DropPermissionHolder createFromParcel(Parcel in) {
return new DropPermissionHolder(in);
}
public DropPermissionHolder[] newArray(int size) {
return new DropPermissionHolder[size];
}
};
}

View File

@@ -0,0 +1,66 @@
/*
** Copyright 2015, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package android.view;
import android.os.RemoteException;
import com.android.internal.view.IDropPermissions;
import dalvik.system.CloseGuard;
public final class DropPermissions {
private final IDropPermissions mDropPermissions;
private final CloseGuard mCloseGuard = CloseGuard.get();
/**
* Create a new DropPermissions object to be passed to the client with a DragEvent.
*
* @hide
*/
DropPermissions(IDropPermissions dropPermissions) {
mDropPermissions = dropPermissions;
try {
mDropPermissions.take();
} catch (RemoteException e) {
}
mCloseGuard.open("release");
}
/**
* Revoke permissions taken by {@link DragEvent#requestDropPermissions()}.
*/
public void release() {
try {
mDropPermissions.release();
} catch (RemoteException e) {
}
mCloseGuard.close();
}
@Override
protected void finalize() throws Throwable {
try {
if (mCloseGuard != null) {
mCloseGuard.warnIfOpen();
}
release();
} finally {
super.finalize();
}
}
}

View File

@@ -20,7 +20,7 @@ package com.android.internal.view;
* Interface to allow a drop receiver to request permissions for URIs passed along with ClipData
* contained in DragEvent.
*/
interface IDropPermissionHolder {
void grant();
void revoke();
interface IDropPermissions {
void take();
void release();
}

View File

@@ -35,7 +35,6 @@ import android.os.RemoteException;
import android.util.Slog;
import android.view.Display;
import android.view.DragEvent;
import android.view.DropPermissionHolder;
import android.view.InputChannel;
import android.view.SurfaceControl;
import android.view.View;
@@ -54,6 +53,8 @@ import com.android.server.input.InputWindowHandle;
import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
import com.android.server.wm.WindowManagerService.H;
import com.android.internal.view.IDropPermissions;
import java.util.ArrayList;
/**
@@ -428,7 +429,7 @@ class DragState {
// Tell the drop target about the data. Returns 'true' if we can immediately
// dispatch the global drag-ended message, 'false' if we need to wait for a
// result from the recipient.
boolean notifyDropLw(WindowState touchedWin, DropPermissionHolder dropPermissionHolder,
boolean notifyDropLw(WindowState touchedWin, IDropPermissions dropPermissions,
float x, float y) {
if (mAnimation != null) {
return false;
@@ -449,7 +450,7 @@ class DragState {
final int myPid = Process.myPid();
final IBinder token = touchedWin.mClient.asBinder();
DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DROP, x, y,
null, null, mData, dropPermissionHolder, false);
null, null, mData, dropPermissions, false);
try {
touchedWin.mClient.dispatchDragEvent(evt);
@@ -516,7 +517,7 @@ class DragState {
private static DragEvent obtainDragEvent(WindowState win, int action,
float x, float y, Object localState,
ClipDescription description, ClipData data,
DropPermissionHolder dropPermissionHolder,
IDropPermissions dropPermissions,
boolean result) {
float winX = x - win.mFrame.left;
float winY = y - win.mFrame.top;
@@ -525,7 +526,7 @@ class DragState {
winY *= win.mGlobalScale;
}
return DragEvent.obtain(action, winX, winY, localState, description, data,
dropPermissionHolder, result);
dropPermissions, result);
}
boolean stepAnimationLocked(long currentTimeMs) {

View File

@@ -0,0 +1,86 @@
/*
** Copyright 2015, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package com.android.server.wm;
import android.app.ActivityManagerNative;
import android.content.ClipData;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import com.android.internal.view.IDropPermissions;
import java.util.ArrayList;
class DropPermissionsHandler extends IDropPermissions.Stub {
private final int mSourceUid;
private final String mTargetPackage;
private final int mMode;
private final int mSourceUserId;
private final int mTargetUserId;
private final ArrayList<Uri> mUris = new ArrayList<Uri>();
private IBinder mPermissionOwner = null;
DropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode,
int sourceUserId, int targetUserId) {
mSourceUid = sourceUid;
mTargetPackage = targetPackage;
mMode = mode;
mSourceUserId = sourceUserId;
mTargetUserId = targetUserId;
clipData.collectUris(mUris);
}
@Override
public void take() throws RemoteException {
if (mPermissionOwner != null) {
return;
}
mPermissionOwner = ActivityManagerNative.getDefault().newUriPermissionOwner("drop");
long origId = Binder.clearCallingIdentity();
try {
for (int i = 0; i < mUris.size(); i++) {
ActivityManagerNative.getDefault().grantUriPermissionFromOwner(
mPermissionOwner, mSourceUid, mTargetPackage, mUris.get(i), mMode,
mSourceUserId, mTargetUserId);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
@Override
public void release() throws RemoteException {
if (mPermissionOwner == null) {
return;
}
for (int i = 0; i < mUris.size(); ++i) {
ActivityManagerNative.getDefault().revokeUriPermissionFromOwner(
mPermissionOwner, mUris.get(i), mMode, mSourceUserId);
}
mPermissionOwner = null;
}
}

View File

@@ -153,7 +153,6 @@ import android.view.AppTransitionAnimationSpec;
import android.view.Choreographer;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.DropPermissionHolder;
import android.view.Gravity;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.IApplicationToken;
@@ -758,13 +757,12 @@ public class WindowManagerService extends IWindowManager.Stub
private boolean completeDropLw(float x, float y) {
WindowState dropTargetWin = mDragState.getDropTargetWinLw(x, y);
DropPermissionHolder dropPermissionHolder = null;
DropPermissionsHandler dropPermissions = null;
if (dropTargetWin != null &&
(mDragState.mFlags & View.DRAG_FLAG_GLOBAL) != 0 &&
(mDragState.mFlags & DRAG_FLAGS_URI_ACCESS) != 0) {
dropPermissionHolder = new DropPermissionHolder(
dropPermissions = new DropPermissionsHandler(
mDragState.mData,
mActivityManager,
mDragState.mUid,
dropTargetWin.getOwningPackage(),
mDragState.mFlags & DRAG_FLAGS_URI_PERMISSIONS,
@@ -772,7 +770,7 @@ public class WindowManagerService extends IWindowManager.Stub
UserHandle.getUserId(dropTargetWin.getOwningUid()));
}
return mDragState.notifyDropLw(dropTargetWin, dropPermissionHolder, x, y);
return mDragState.notifyDropLw(dropTargetWin, dropPermissions, x, y);
}
/**