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
diff --git a/Android.mk b/Android.mk
index 137ef85..a098379 100644
--- a/Android.mk
+++ b/Android.mk
@@ -308,7 +308,7 @@
 	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 \
diff --git a/api/current.txt b/api/current.txt
index 622a8b7..ec38436 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -39298,11 +39298,11 @@
     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 @@
     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 {
diff --git a/api/system-current.txt b/api/system-current.txt
index e51b7d5..297efc2 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -41650,11 +41650,11 @@
     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 @@
     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 {
diff --git a/api/test-current.txt b/api/test-current.txt
index 2377a9b..7cc7cb6 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -39300,11 +39300,11 @@
     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 @@
     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 {
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index c934e8d..0b80f8a 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -36,6 +36,7 @@
 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 @@
         }
     }
 
+    /** @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;
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 34835f4..5903d4a 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -21,6 +21,8 @@
 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 @@
     float mX, mY;
     ClipDescription mClipDescription;
     ClipData mClipData;
-    DropPermissionHolder mDropPermissionHolder;
+    IDropPermissions mDropPermissions;
 
     Object mLocalState;
     boolean mDragResult;
@@ -146,7 +148,7 @@
      * 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 @@
      * 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 @@
     }
 
     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 @@
 
     /** @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 @@
         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 @@
     /** @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 @@
     }
 
     /**
-     * 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 @@
             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 @@
                 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;
         }
diff --git a/core/java/android/view/DropPermissionHolder.java b/core/java/android/view/DropPermissionHolder.java
deleted file mode 100644
index 993e67a..0000000
--- a/core/java/android/view/DropPermissionHolder.java
+++ /dev/null
@@ -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];
-        }
-    };
-}
diff --git a/core/java/android/view/DropPermissions.java b/core/java/android/view/DropPermissions.java
new file mode 100644
index 0000000..780461f
--- /dev/null
+++ b/core/java/android/view/DropPermissions.java
@@ -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();
+        }
+    }
+}
diff --git a/core/java/com/android/internal/view/IDropPermissionHolder.aidl b/core/java/com/android/internal/view/IDropPermissions.aidl
similarity index 91%
rename from core/java/com/android/internal/view/IDropPermissionHolder.aidl
rename to core/java/com/android/internal/view/IDropPermissions.aidl
index e60ab0e..86d27e7 100644
--- a/core/java/com/android/internal/view/IDropPermissionHolder.aidl
+++ b/core/java/com/android/internal/view/IDropPermissions.aidl
@@ -20,7 +20,7 @@
  * 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();
 }
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index da89481..7b0a8d7 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -35,7 +35,6 @@
 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.wm.WindowManagerService.DragInputEventReceiver;
 import com.android.server.wm.WindowManagerService.H;
 
+import com.android.internal.view.IDropPermissions;
+
 import java.util.ArrayList;
 
 /**
@@ -428,7 +429,7 @@
     // 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 @@
         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 @@
     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 @@
             winY *= win.mGlobalScale;
         }
         return DragEvent.obtain(action, winX, winY, localState, description, data,
-                dropPermissionHolder, result);
+                dropPermissions, result);
     }
 
     boolean stepAnimationLocked(long currentTimeMs) {
diff --git a/services/core/java/com/android/server/wm/DropPermissionsHandler.java b/services/core/java/com/android/server/wm/DropPermissionsHandler.java
new file mode 100644
index 0000000..2ac1ef4
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DropPermissionsHandler.java
@@ -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;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 456c416..4ea0cf5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -153,7 +153,6 @@
 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 @@
     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 @@
                     UserHandle.getUserId(dropTargetWin.getOwningUid()));
         }
 
-        return mDragState.notifyDropLw(dropTargetWin, dropPermissionHolder, x, y);
+        return mDragState.notifyDropLw(dropTargetWin, dropPermissions, x, y);
     }
 
     /**