Making the clipboard work across users.

When copying from the parent: the ClipData can be pasted in the managed profile.
When copying from a managed profile: it can be pasted in the parent,
unless the policies says it's disabled. In which case, the clipboard of the parent becomes empty.
Supporting content uris.

BUG: 15186236

Change-Id: I522564a7c07ff21df137adcda980bb52e5739964
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 342155d..318a520 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1661,8 +1661,10 @@
             String targetPkg = data.readString();
             Uri uri = Uri.CREATOR.createFromParcel(data);
             int mode = data.readInt();
-            int userId = data.readInt();
-            grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode, userId);
+            int sourceUserId = data.readInt();
+            int targetUserId = data.readInt();
+            grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode, sourceUserId,
+                    targetUserId);
             reply.writeNoException();
             return true;
         }
@@ -4343,7 +4345,7 @@
     }
 
     public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
-            Uri uri, int mode, int userId) throws RemoteException {
+            Uri uri, int mode, int sourceUserId, int targetUserId) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
         data.writeInterfaceToken(IActivityManager.descriptor);
@@ -4352,7 +4354,8 @@
         data.writeString(targetPkg);
         uri.writeToParcel(data, 0);
         data.writeInt(mode);
-        data.writeInt(userId);
+        data.writeInt(sourceUserId);
+        data.writeInt(targetUserId);
         mRemote.transact(GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
         reply.readException();
         data.recycle();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index cc13a3b..53c1408 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -332,7 +332,7 @@
 
     public IBinder newUriPermissionOwner(String name) throws RemoteException;
     public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
-            Uri uri, int mode, int userId) throws RemoteException;
+            Uri uri, int mode, int sourceUserId, int targetUserId) throws RemoteException;
     public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
             int mode, int userId) throws RemoteException;
 
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index b44abf9..7a16ef8 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -828,6 +828,26 @@
         }
     }
 
+    /**
+     * Only fixing the data field of the intents
+     * @hide
+     */
+    public void fixUrisLight(int contentUserHint) {
+        final int size = mItems.size();
+        for (int i = 0; i < size; i++) {
+            final Item item = mItems.get(i);
+            if (item.mIntent != null) {
+                Uri data = item.mIntent.getData();
+                if (data != null) {
+                    item.mIntent.setData(maybeAddUserId(data, contentUserHint));
+                }
+            }
+            if (item.mUri != null) {
+                item.mUri = maybeAddUserId(item.mUri, contentUserHint);
+            }
+        }
+    }
+
     @Override
     public String toString() {
         StringBuilder b = new StringBuilder(128);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index d3aee50..45edf28 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -310,6 +310,18 @@
      */
     public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows";
 
+    /**
+     * Key for user restrictions. Specifies if what is copied in the clipboard of this profile can
+     * be pasted in related profiles. Does not restrict if the clipboard of related profiles can be
+     * pasted in this profile.
+     * The default value is <code>false</code>.
+     * <p/>
+     * Type: Boolean
+     * @see #setUserRestrictions(Bundle)
+     * @see #getUserRestrictions()
+     */
+    public static final String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste";
+
     /** @hide */
     public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3;
     /** @hide */