Loading core/java/android/content/ClipData.java +9 −1 Original line number Diff line number Diff line Loading @@ -17,11 +17,14 @@ package android.content; import static android.content.ContentProvider.maybeAddUserId; import android.content.pm.PackageManager; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; import android.os.StrictMode; import android.text.Html; import android.text.Spannable; Loading Loading @@ -462,7 +465,12 @@ public class ClipData implements Parcelable { // Check to see what data representations the content // provider supports. We would like HTML text, but if that // is not possible we'll live with plan text. String[] types = context.getContentResolver().getStreamTypes(mUri, "text/*"); String[] types = null; try { types = context.getContentResolver().getStreamTypes(mUri, "text/*"); } catch (SecurityException e) { // No read permission for mUri, assume empty stream types list. } boolean hasHtml = false; boolean hasText = false; if (types != null) { Loading core/java/android/view/DropPermissions.java +21 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view; import android.app.ActivityManagerNative; import android.os.IBinder; import android.os.RemoteException; import com.android.internal.view.IDropPermissions; Loading @@ -41,6 +42,8 @@ public final class DropPermissions { private final IDropPermissions mDropPermissions; private IBinder mPermissionOwnerToken; private final CloseGuard mCloseGuard = CloseGuard.get(); /** Loading Loading @@ -79,12 +82,30 @@ public final class DropPermissions { return true; } /** * Take the permissions. Must call {@link #release} explicitly. * @return True if permissions are successfully taken. * @hide */ public boolean takeTransient() { try { mPermissionOwnerToken = ActivityManagerNative.getDefault(). newUriPermissionOwner("drop"); mDropPermissions.takeTransient(mPermissionOwnerToken); } catch (RemoteException e) { return false; } mCloseGuard.open("release"); return true; } /** * Revoke permissions explicitly. */ public void release() { try { mDropPermissions.release(); mPermissionOwnerToken = null; } catch (RemoteException e) { } mCloseGuard.close(); Loading core/java/android/widget/Editor.java +19 −5 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import android.view.ActionMode.Callback; import android.view.ContextMenu; import android.view.DisplayListCanvas; import android.view.DragEvent; import android.view.DropPermissions; import android.view.Gravity; import android.view.InputDevice; import android.view.LayoutInflater; Loading Loading @@ -2298,12 +2299,25 @@ public class Editor { void onDrop(DragEvent event) { StringBuilder content = new StringBuilder(""); final DropPermissions dropPermissions = DropPermissions.obtain(event); if (dropPermissions != null) { dropPermissions.takeTransient(); } try { ClipData clipData = event.getClipData(); final int itemCount = clipData.getItemCount(); for (int i=0; i < itemCount; i++) { Item item = clipData.getItemAt(i); content.append(item.coerceToStyledText(mTextView.getContext())); } } finally { if (dropPermissions != null) { dropPermissions.release(); } } final int offset = mTextView.getOffsetForPosition(event.getX(), event.getY()); Loading core/java/com/android/internal/view/IDropPermissions.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -24,5 +24,6 @@ import android.os.IBinder; */ interface IDropPermissions { void take(IBinder activityToken); void takeTransient(IBinder permissionOwnerToken); void release(); } services/core/java/com/android/server/wm/DropPermissionsHandler.java +42 −11 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ import com.android.internal.view.IDropPermissions; import java.util.ArrayList; class DropPermissionsHandler extends IDropPermissions.Stub { class DropPermissionsHandler extends IDropPermissions.Stub implements IBinder.DeathRecipient { private final int mSourceUid; private final String mTargetPackage; Loading @@ -38,6 +38,7 @@ class DropPermissionsHandler extends IDropPermissions.Stub { private final ArrayList<Uri> mUris = new ArrayList<Uri>(); private IBinder mActivityToken = null; private IBinder mPermissionOwnerToken = null; DropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode, int sourceUserId, int targetUserId) { Loading @@ -52,7 +53,7 @@ class DropPermissionsHandler extends IDropPermissions.Stub { @Override public void take(IBinder activityToken) throws RemoteException { if (mActivityToken != null) { if (mActivityToken != null || mPermissionOwnerToken != null) { return; } mActivityToken = activityToken; Loading @@ -61,6 +62,10 @@ class DropPermissionsHandler extends IDropPermissions.Stub { IBinder permissionOwner = ActivityManagerNative.getDefault(). getUriPermissionOwnerForActivity(mActivityToken); doTake(permissionOwner); } private void doTake(IBinder permissionOwner) throws RemoteException { long origId = Binder.clearCallingIdentity(); try { for (int i = 0; i < mUris.size(); i++) { Loading @@ -73,13 +78,25 @@ class DropPermissionsHandler extends IDropPermissions.Stub { } } @Override public void takeTransient(IBinder permissionOwnerToken) throws RemoteException { if (mActivityToken != null || mPermissionOwnerToken != null) { return; } mPermissionOwnerToken = permissionOwnerToken; mPermissionOwnerToken.linkToDeath(this, 0); doTake(mPermissionOwnerToken); } @Override public void release() throws RemoteException { if (mActivityToken == null) { if (mActivityToken == null && mPermissionOwnerToken == null) { return; } IBinder permissionOwner = null; if (mActivityToken != null) { try { permissionOwner = ActivityManagerNative.getDefault(). getUriPermissionOwnerForActivity(mActivityToken); Loading @@ -89,10 +106,24 @@ class DropPermissionsHandler extends IDropPermissions.Stub { } finally { mActivityToken = null; } } else { permissionOwner = mPermissionOwnerToken; mPermissionOwnerToken.unlinkToDeath(this, 0); mPermissionOwnerToken = null; } for (int i = 0; i < mUris.size(); ++i) { ActivityManagerNative.getDefault().revokeUriPermissionFromOwner( permissionOwner, mUris.get(i), mMode, mSourceUserId); } } @Override public void binderDied() { try { release(); } catch (RemoteException e) { // Cannot happen, local call. } } } Loading
core/java/android/content/ClipData.java +9 −1 Original line number Diff line number Diff line Loading @@ -17,11 +17,14 @@ package android.content; import static android.content.ContentProvider.maybeAddUserId; import android.content.pm.PackageManager; import android.content.res.AssetFileDescriptor; import android.graphics.Bitmap; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; import android.os.StrictMode; import android.text.Html; import android.text.Spannable; Loading Loading @@ -462,7 +465,12 @@ public class ClipData implements Parcelable { // Check to see what data representations the content // provider supports. We would like HTML text, but if that // is not possible we'll live with plan text. String[] types = context.getContentResolver().getStreamTypes(mUri, "text/*"); String[] types = null; try { types = context.getContentResolver().getStreamTypes(mUri, "text/*"); } catch (SecurityException e) { // No read permission for mUri, assume empty stream types list. } boolean hasHtml = false; boolean hasText = false; if (types != null) { Loading
core/java/android/view/DropPermissions.java +21 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.view; import android.app.ActivityManagerNative; import android.os.IBinder; import android.os.RemoteException; import com.android.internal.view.IDropPermissions; Loading @@ -41,6 +42,8 @@ public final class DropPermissions { private final IDropPermissions mDropPermissions; private IBinder mPermissionOwnerToken; private final CloseGuard mCloseGuard = CloseGuard.get(); /** Loading Loading @@ -79,12 +82,30 @@ public final class DropPermissions { return true; } /** * Take the permissions. Must call {@link #release} explicitly. * @return True if permissions are successfully taken. * @hide */ public boolean takeTransient() { try { mPermissionOwnerToken = ActivityManagerNative.getDefault(). newUriPermissionOwner("drop"); mDropPermissions.takeTransient(mPermissionOwnerToken); } catch (RemoteException e) { return false; } mCloseGuard.open("release"); return true; } /** * Revoke permissions explicitly. */ public void release() { try { mDropPermissions.release(); mPermissionOwnerToken = null; } catch (RemoteException e) { } mCloseGuard.close(); Loading
core/java/android/widget/Editor.java +19 −5 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ import android.view.ActionMode.Callback; import android.view.ContextMenu; import android.view.DisplayListCanvas; import android.view.DragEvent; import android.view.DropPermissions; import android.view.Gravity; import android.view.InputDevice; import android.view.LayoutInflater; Loading Loading @@ -2298,12 +2299,25 @@ public class Editor { void onDrop(DragEvent event) { StringBuilder content = new StringBuilder(""); final DropPermissions dropPermissions = DropPermissions.obtain(event); if (dropPermissions != null) { dropPermissions.takeTransient(); } try { ClipData clipData = event.getClipData(); final int itemCount = clipData.getItemCount(); for (int i=0; i < itemCount; i++) { Item item = clipData.getItemAt(i); content.append(item.coerceToStyledText(mTextView.getContext())); } } finally { if (dropPermissions != null) { dropPermissions.release(); } } final int offset = mTextView.getOffsetForPosition(event.getX(), event.getY()); Loading
core/java/com/android/internal/view/IDropPermissions.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -24,5 +24,6 @@ import android.os.IBinder; */ interface IDropPermissions { void take(IBinder activityToken); void takeTransient(IBinder permissionOwnerToken); void release(); }
services/core/java/com/android/server/wm/DropPermissionsHandler.java +42 −11 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ import com.android.internal.view.IDropPermissions; import java.util.ArrayList; class DropPermissionsHandler extends IDropPermissions.Stub { class DropPermissionsHandler extends IDropPermissions.Stub implements IBinder.DeathRecipient { private final int mSourceUid; private final String mTargetPackage; Loading @@ -38,6 +38,7 @@ class DropPermissionsHandler extends IDropPermissions.Stub { private final ArrayList<Uri> mUris = new ArrayList<Uri>(); private IBinder mActivityToken = null; private IBinder mPermissionOwnerToken = null; DropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode, int sourceUserId, int targetUserId) { Loading @@ -52,7 +53,7 @@ class DropPermissionsHandler extends IDropPermissions.Stub { @Override public void take(IBinder activityToken) throws RemoteException { if (mActivityToken != null) { if (mActivityToken != null || mPermissionOwnerToken != null) { return; } mActivityToken = activityToken; Loading @@ -61,6 +62,10 @@ class DropPermissionsHandler extends IDropPermissions.Stub { IBinder permissionOwner = ActivityManagerNative.getDefault(). getUriPermissionOwnerForActivity(mActivityToken); doTake(permissionOwner); } private void doTake(IBinder permissionOwner) throws RemoteException { long origId = Binder.clearCallingIdentity(); try { for (int i = 0; i < mUris.size(); i++) { Loading @@ -73,13 +78,25 @@ class DropPermissionsHandler extends IDropPermissions.Stub { } } @Override public void takeTransient(IBinder permissionOwnerToken) throws RemoteException { if (mActivityToken != null || mPermissionOwnerToken != null) { return; } mPermissionOwnerToken = permissionOwnerToken; mPermissionOwnerToken.linkToDeath(this, 0); doTake(mPermissionOwnerToken); } @Override public void release() throws RemoteException { if (mActivityToken == null) { if (mActivityToken == null && mPermissionOwnerToken == null) { return; } IBinder permissionOwner = null; if (mActivityToken != null) { try { permissionOwner = ActivityManagerNative.getDefault(). getUriPermissionOwnerForActivity(mActivityToken); Loading @@ -89,10 +106,24 @@ class DropPermissionsHandler extends IDropPermissions.Stub { } finally { mActivityToken = null; } } else { permissionOwner = mPermissionOwnerToken; mPermissionOwnerToken.unlinkToDeath(this, 0); mPermissionOwnerToken = null; } for (int i = 0; i < mUris.size(); ++i) { ActivityManagerNative.getDefault().revokeUriPermissionFromOwner( permissionOwner, mUris.get(i), mMode, mSourceUserId); } } @Override public void binderDied() { try { release(); } catch (RemoteException e) { // Cannot happen, local call. } } }