Merge "Append a correct extension in case of copying virtual files."
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/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 17c803f..ae360fc 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5957,6 +5957,14 @@
@Override
public PointerIcon getPointerIcon(MotionEvent event, float x, float y) {
+ if (mText instanceof Spannable && mLinksClickable) {
+ final int offset = getOffsetForPosition(x, y);
+ final ClickableSpan[] clickables = ((Spannable) mText).getSpans(offset, offset,
+ ClickableSpan.class);
+ if (clickables.length > 0) {
+ return PointerIcon.getSystemIcon(mContext, PointerIcon.STYLE_HAND);
+ }
+ }
if (isTextSelectable() || isTextEditable()) {
return PointerIcon.getSystemIcon(mContext, PointerIcon.STYLE_TEXT);
}
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/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index d9f94d0..472e8f6 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -46,6 +46,7 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -348,9 +349,27 @@
private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
throws IOException, XmlPullParserException {
out.startTag(null, XML_TAG_EXTRAS);
- extras.saveToXml(out);
+ PersistableBundle extrasCopy = deepCopyBundle(extras, 10);
+ extrasCopy.saveToXml(out);
out.endTag(null, XML_TAG_EXTRAS);
}
+
+ private PersistableBundle deepCopyBundle(PersistableBundle bundle, int maxDepth) {
+ if (maxDepth <= 0) {
+ return null;
+ }
+ PersistableBundle copy = (PersistableBundle) bundle.clone();
+ Set<String> keySet = bundle.keySet();
+ for (String key: keySet) {
+ PersistableBundle b = copy.getPersistableBundle(key);
+ if (b != null) {
+ PersistableBundle bCopy = deepCopyBundle(b, maxDepth-1);
+ copy.putPersistableBundle(key, bCopy);
+ }
+ }
+ return copy;
+ }
+
/**
* Write out a tag with data identifying this job's constraints. If the constraint isn't here
* it doesn't apply.
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index da894818..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);
}
/**