diff options
| -rw-r--r-- | Android.mk | 1 | ||||
| -rw-r--r-- | api/current.txt | 14 | ||||
| -rw-r--r-- | api/system-current.txt | 14 | ||||
| -rw-r--r-- | core/java/android/view/DragEvent.java | 37 | ||||
| -rw-r--r-- | core/java/android/view/DropPermissionHolder.java | 161 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 39 | ||||
| -rw-r--r-- | core/java/com/android/internal/view/IDropPermissionHolder.aidl | 26 | ||||
| -rw-r--r-- | packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java | 3 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/DragState.java | 29 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 31 |
10 files changed, 335 insertions, 20 deletions
diff --git a/Android.mk b/Android.mk index d48887d17e3b..f1e16b841585 100644 --- a/Android.mk +++ b/Android.mk @@ -303,6 +303,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/IInputContext.aidl \ core/java/com/android/internal/view/IInputContextCallback.aidl \ core/java/com/android/internal/view/IInputMethod.aidl \ diff --git a/api/current.txt b/api/current.txt index 7e6f445e6ff4..2a3b5e1207d3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -34802,6 +34802,7 @@ 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(); @@ -34816,6 +34817,14 @@ 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 class FocusFinder { method public android.view.View findNearestTouchable(android.view.ViewGroup, int, int, int, int[]); method public final android.view.View findNextFocus(android.view.ViewGroup, android.view.View, int); @@ -36519,6 +36528,11 @@ package android.view { field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0 field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1 field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA; + field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100 + field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40 + field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80 + field public static final int DRAG_FLAG_GLOBAL_URI_READ = 1; // 0x1 + field public static final int DRAG_FLAG_GLOBAL_URI_WRITE = 2; // 0x2 field public static final int DRAG_FLAG_OPAQUE = 512; // 0x200 field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0 field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000 diff --git a/api/system-current.txt b/api/system-current.txt index 0a2a5212532f..7c4ced000c14 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -37096,6 +37096,7 @@ 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(); @@ -37110,6 +37111,14 @@ 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 class FocusFinder { method public android.view.View findNearestTouchable(android.view.ViewGroup, int, int, int, int[]); method public final android.view.View findNextFocus(android.view.ViewGroup, android.view.View, int); @@ -38813,6 +38822,11 @@ package android.view { field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0 field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1 field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA; + field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100 + field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40 + field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80 + field public static final int DRAG_FLAG_GLOBAL_URI_READ = 1; // 0x1 + field public static final int DRAG_FLAG_GLOBAL_URI_WRITE = 2; // 0x2 field public static final int DRAG_FLAG_OPAQUE = 512; // 0x200 field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0 field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000 diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java index f559e21f661e..34835f4a8070 100644 --- a/core/java/android/view/DragEvent.java +++ b/core/java/android/view/DragEvent.java @@ -128,6 +128,8 @@ public class DragEvent implements Parcelable { float mX, mY; ClipDescription mClipDescription; ClipData mClipData; + DropPermissionHolder mDropPermissionHolder; + Object mLocalState; boolean mDragResult; @@ -253,28 +255,30 @@ public class DragEvent implements Parcelable { } private void init(int action, float x, float y, ClipDescription description, ClipData data, - Object localState, boolean result) { + DropPermissionHolder dropPermissionHolder, Object localState, boolean result) { mAction = action; mX = x; mY = y; mClipDescription = description; mClipData = data; + mDropPermissionHolder = dropPermissionHolder; mLocalState = localState; mDragResult = result; } static DragEvent obtain() { - return DragEvent.obtain(0, 0f, 0f, null, null, null, false); + return DragEvent.obtain(0, 0f, 0f, null, null, null, null, false); } /** @hide */ public static DragEvent obtain(int action, float x, float y, Object localState, - ClipDescription description, ClipData data, boolean result) { + ClipDescription description, ClipData data, DropPermissionHolder dropPermissionHolder, + boolean result) { final DragEvent ev; synchronized (gRecyclerLock) { if (gRecyclerTop == null) { ev = new DragEvent(); - ev.init(action, x, y, description, data, localState, result); + ev.init(action, x, y, description, data, dropPermissionHolder, localState, result); return ev; } ev = gRecyclerTop; @@ -285,7 +289,7 @@ public class DragEvent implements Parcelable { ev.mRecycled = false; ev.mNext = null; - ev.init(action, x, y, description, data, localState, result); + ev.init(action, x, y, description, data, dropPermissionHolder, localState, result); return ev; } @@ -293,7 +297,8 @@ 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.mDragResult); + source.mClipDescription, source.mClipData, source.mDropPermissionHolder, + source.mDragResult); } /** @@ -358,6 +363,17 @@ 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. + * This method only returns valid data if the event action is {@link #ACTION_DROP}. + * @return The DropPermissionHolder object used to handle content URI permissions. + */ + public DropPermissionHolder getDropPermissionHolder() { + return mDropPermissionHolder; + } + + /** * Returns the local state object sent to the system as part of the call to * {@link android.view.View#startDrag(ClipData,View.DragShadowBuilder,Object,int) startDrag()}. * The object is intended to provide local information about the drag and drop operation. For @@ -477,6 +493,12 @@ public class DragEvent implements Parcelable { dest.writeInt(1); mClipDescription.writeToParcel(dest, flags); } + if (mDropPermissionHolder == null) { + dest.writeInt(0); + } else { + dest.writeInt(1); + mDropPermissionHolder.writeToParcel(dest, flags); + } } /** @@ -496,6 +518,9 @@ public class DragEvent implements Parcelable { if (in.readInt() != 0) { event.mClipDescription = ClipDescription.CREATOR.createFromParcel(in); } + if (in.readInt() != 0) { + event.mDropPermissionHolder = DropPermissionHolder.CREATOR.createFromParcel(in); + } return event; } diff --git a/core/java/android/view/DropPermissionHolder.java b/core/java/android/view/DropPermissionHolder.java new file mode 100644 index 000000000000..993e67a2578e --- /dev/null +++ b/core/java/android/view/DropPermissionHolder.java @@ -0,0 +1,161 @@ +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]; + } + }; +} diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index eb591c1bfa86..b5d76c5ba0ba 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -3641,9 +3641,44 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * with this flag set, all visible applications will be able to participate * in the drag operation and receive the dragged content. * - * @hide + * If this is the only flag set, then the drag recipient will only have access to text data + * and intents contained in the {@link ClipData} object. Access to URIs contained in the + * {@link ClipData} is determined by other DRAG_FLAG_GLOBAL_* flags. + */ + public static final int DRAG_FLAG_GLOBAL = 1 << 8; // 256 + + /** + * When this flag is used with {@link #DRAG_FLAG_GLOBAL}, the drag recipient will be able to + * request read access to the content URI(s) contained in the {@link ClipData} object. + * @see android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION + */ + public static final int DRAG_FLAG_GLOBAL_URI_READ = Intent.FLAG_GRANT_READ_URI_PERMISSION; + + /** + * When this flag is used with {@link #DRAG_FLAG_GLOBAL}, the drag recipient will be able to + * request write access to the content URI(s) contained in the {@link ClipData} object. + * @see android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION + */ + public static final int DRAG_FLAG_GLOBAL_URI_WRITE = Intent.FLAG_GRANT_WRITE_URI_PERMISSION; + + /** + * When this flag is used with {@link #DRAG_FLAG_GLOBAL_URI_READ} and/or {@link + * #DRAG_FLAG_GLOBAL_URI_WRITE}, the URI permission grant can be persisted across device + * reboots until explicitly revoked with + * {@link android.content.Context#revokeUriPermission(Uri,int) Context.revokeUriPermission}. + * @see android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION + */ + public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = + Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; + + /** + * When this flag is used with {@link #DRAG_FLAG_GLOBAL_URI_READ} and/or {@link + * #DRAG_FLAG_GLOBAL_URI_WRITE}, the URI permission grant applies to any URI that is a prefix + * match against the original granted URI. + * @see android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION */ - public static final int DRAG_FLAG_GLOBAL = 1; + public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = + Intent.FLAG_GRANT_PREFIX_URI_PERMISSION; /** * Flag indicating that the drag shadow will be opaque. When diff --git a/core/java/com/android/internal/view/IDropPermissionHolder.aidl b/core/java/com/android/internal/view/IDropPermissionHolder.aidl new file mode 100644 index 000000000000..e60ab0e516e5 --- /dev/null +++ b/core/java/com/android/internal/view/IDropPermissionHolder.aidl @@ -0,0 +1,26 @@ +/* +** 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.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(); +} diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java index 046f3df3b5d4..3202876569e0 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java @@ -1519,7 +1519,8 @@ public class DirectoryFragment extends Fragment { getClipDataFromDocuments(docs), new DrawableShadowBuilder(getDragShadowIcon(docs)), null, - View.DRAG_FLAG_GLOBAL + View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ | + View.DRAG_FLAG_GLOBAL_URI_WRITE ); return true; } diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 8f77176feb73..ddcf2a711d8b 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -27,6 +27,7 @@ import android.content.ClipDescription; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; +import android.os.Binder; import android.os.IBinder; import android.os.Message; import android.os.Process; @@ -34,6 +35,7 @@ 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; @@ -50,6 +52,7 @@ class DragState { SurfaceControl mSurfaceControl; int mFlags; IBinder mLocalWin; + int mUid; ClipData mData; ClipDescription mDataDescription; boolean mDragResult; @@ -74,6 +77,7 @@ class DragState { mSurfaceControl = surface; mFlags = flags; mLocalWin = localWin; + mUid = Binder.getCallingUid(); mNotifiedWindows = new ArrayList<WindowState>(); } @@ -225,7 +229,7 @@ class DragState { if (mDragInProgress && newWin.isPotentialDragTarget()) { DragEvent event = obtainDragEvent(newWin, DragEvent.ACTION_DRAG_STARTED, - touchX, touchY, null, desc, null, false); + touchX, touchY, null, desc, null, null, false); try { newWin.mClient.dispatchDragEvent(event); // track each window that we've notified that the drag is starting @@ -265,7 +269,7 @@ class DragState { Slog.d(WindowManagerService.TAG, "broadcasting DRAG_ENDED"); } DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_ENDED, - 0, 0, null, null, null, mDragResult); + 0, 0, null, null, null, null, mDragResult); for (WindowState ws: mNotifiedWindows) { try { ws.mClient.dispatchDragEvent(evt); @@ -331,7 +335,7 @@ class DragState { } // force DRAG_EXITED_EVENT if appropriate DragEvent evt = obtainDragEvent(mTargetWindow, DragEvent.ACTION_DRAG_EXITED, - x, y, null, null, null, false); + x, y, null, null, null, null, false); mTargetWindow.mClient.dispatchDragEvent(evt); if (myPid != mTargetWindow.mSession.mPid) { evt.recycle(); @@ -342,7 +346,7 @@ class DragState { Slog.d(WindowManagerService.TAG, "sending DRAG_LOCATION to " + touchedWin); } DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DRAG_LOCATION, - x, y, null, null, null, false); + x, y, null, null, null, null, false); touchedWin.mClient.dispatchDragEvent(evt); if (myPid != touchedWin.mSession.mPid) { evt.recycle(); @@ -354,11 +358,15 @@ class DragState { mTargetWindow = touchedWin; } + WindowState getDropTargetWinLw(float x, float y) { + return getTouchedWinAtPointLw(x, y); + } + // 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(float x, float y) { - WindowState touchedWin = getTouchedWinAtPointLw(x, y); + boolean notifyDropLw(WindowState touchedWin, DropPermissionHolder dropPermissionHolder, + float x, float y) { if (touchedWin == null) { // "drop" outside a valid window -- no recipient to apply a // timeout to, and we can send the drag-ended message immediately. @@ -372,7 +380,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, false); + null, null, mData, dropPermissionHolder, false); try { touchedWin.mClient.dispatchDragEvent(evt); @@ -438,13 +446,16 @@ class DragState { private static DragEvent obtainDragEvent(WindowState win, int action, float x, float y, Object localState, - ClipDescription description, ClipData data, boolean result) { + ClipDescription description, ClipData data, + DropPermissionHolder dropPermissionHolder, + boolean result) { float winX = x - win.mFrame.left; float winY = y - win.mFrame.top; if (win.mEnforceSizeCompat) { winX *= win.mGlobalScale; winY *= win.mGlobalScale; } - return DragEvent.obtain(action, winX, winY, localState, description, data, result); + return DragEvent.obtain(action, winX, winY, localState, description, data, + dropPermissionHolder, result); } }
\ No newline at end of file diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 554587d212f5..943e9ec0a32c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -107,6 +107,7 @@ 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.IApplicationToken; import android.view.IInputFilter; @@ -626,6 +627,13 @@ public class WindowManagerService extends IWindowManager.Stub private WindowContentFrameStats mTempWindowRenderStats; + private static final int DRAG_FLAGS_URI_ACCESS = View.DRAG_FLAG_GLOBAL_URI_READ | + View.DRAG_FLAG_GLOBAL_URI_WRITE; + + private static final int DRAG_FLAGS_URI_PERMISSIONS = DRAG_FLAGS_URI_ACCESS | + View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION | + View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION; + final class DragInputEventReceiver extends InputEventReceiver { // Set, if stylus button was down at the start of the drag. private boolean mStylusButtonDownAtStart; @@ -671,7 +679,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_DRAG) Slog.d(TAG, "Button no longer pressed; dropping at " + newX + "," + newY); synchronized (mWindowMap) { - endDrag = mDragState.notifyDropLw(newX, newY); + endDrag = completeDrop(newX, newY); } } else { synchronized (mWindowMap) { @@ -685,7 +693,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_DRAG) Slog.d(TAG, "Got UP on move channel; dropping at " + newX + "," + newY); synchronized (mWindowMap) { - endDrag = mDragState.notifyDropLw(newX, newY); + endDrag = completeDrop(newX, newY); } } break; @@ -715,6 +723,25 @@ public class WindowManagerService extends IWindowManager.Stub } } + private boolean completeDrop(float x, float y) { + WindowState dropTargetWin = mDragState.getDropTargetWinLw(x, y); + + DropPermissionHolder dropPermissionHolder = null; + if ((mDragState.mFlags & View.DRAG_FLAG_GLOBAL) != 0 && + (mDragState.mFlags & DRAG_FLAGS_URI_ACCESS) != 0) { + dropPermissionHolder = new DropPermissionHolder( + mDragState.mData, + mActivityManager, + mDragState.mUid, + dropTargetWin.getOwningPackage(), + mDragState.mFlags & DRAG_FLAGS_URI_PERMISSIONS, + UserHandle.getUserId(mDragState.mUid), + UserHandle.getUserId(dropTargetWin.getOwningUid())); + } + + return mDragState.notifyDropLw(dropTargetWin, dropPermissionHolder, x, y); + } + /** * Whether the UI is currently running in touch mode (not showing * navigational focus because the user is directly pressing the screen). |