Cts tests for cross-profile copy paste.

BUG: 17998715

Change-Id: I7a752b44b4e15efa49de0912f58aa65f3cea1118
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml b/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
index e1f6886..5bbdf76 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
@@ -24,9 +24,10 @@
     <application>
         <activity android:name="com.android.cts.intent.receiver.IntentReceiverActivity">
             <intent-filter>
+                <action android:name="com.android.cts.action.COPY_TO_CLIPBOARD" />
                 <action android:name="com.android.cts.action.READ_FROM_URI" />
-                <action android:name="com.android.cts.action.WRITE_TO_URI" />
                 <action android:name="com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION" />
+                <action android:name="com.android.cts.action.WRITE_TO_URI" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
index 59f0752..294c678 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
@@ -16,6 +16,8 @@
 package com.android.cts.intent.receiver;
 
 import android.app.Activity;
+import android.content.ClipboardManager;
+import android.content.ClipData;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
@@ -35,21 +37,36 @@
 
     private static final String TAG = "IntentReceiverActivity";
 
-    private static final String ACTION_READ_FROM_URI = "com.android.cts.action.READ_FROM_URI";
+    private static final String ACTION_COPY_TO_CLIPBOARD =
+            "com.android.cts.action.COPY_TO_CLIPBOARD";
 
-    private static final String ACTION_WRITE_TO_URI = "com.android.cts.action.WRITE_TO_URI";
+    private static final String ACTION_READ_FROM_URI =
+            "com.android.cts.action.READ_FROM_URI";
 
     private static final String ACTION_TAKE_PERSISTABLE_URI_PERMISSION =
             "com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION";
 
+    private static final String ACTION_WRITE_TO_URI =
+            "com.android.cts.action.WRITE_TO_URI";
+
+
     private static final String EXTRA_CAUGHT_SECURITY_EXCEPTION = "extra_caught_security_exception";
 
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        Intent received = getIntent();
-        String action = received.getAction();
-        Uri uri = getIntent().getClipData().getItemAt(0).getUri();
-        if (ACTION_READ_FROM_URI.equals(action)) {
+        final Intent received = getIntent();
+        final String action = received.getAction();
+        final ClipData clipData = getIntent().getClipData();
+        final Uri uri = clipData != null ? clipData.getItemAt(0).getUri() : null;
+        if (ACTION_COPY_TO_CLIPBOARD.equals(action)) {
+            String text = received.getStringExtra("extra_text");
+            Log.i(TAG, "Copying \"" + text + "\" to the clipboard");
+            ClipData clip = ClipData.newPlainText("", text);
+            ClipboardManager clipboard =
+                    (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+            clipboard.setPrimaryClip(clip);
+            setResult(Activity.RESULT_OK);
+        } else if (ACTION_READ_FROM_URI.equals(action)) {
             Intent result = new Intent();
             String message = null;
             try {
@@ -63,6 +80,11 @@
             Log.i(TAG, "Message received in reading test: " + message);
             result.putExtra("extra_response", message);
             setResult(Activity.RESULT_OK, result);
+        } else if (ACTION_TAKE_PERSISTABLE_URI_PERMISSION.equals(action)) {
+            Log.i(TAG, "Taking persistable uri permission to " + uri);
+            getContentResolver().takePersistableUriPermission(uri,
+                    Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            setResult(Activity.RESULT_OK);
         } else if (ACTION_WRITE_TO_URI.equals(action)) {
             Intent result = new Intent();
             String message = received.getStringExtra("extra_message");
@@ -76,11 +98,6 @@
                 Log.i(TAG, "Caught a IOException while trying to write to " + uri, e);
             }
             setResult(Activity.RESULT_OK, result);
-        } else if (ACTION_TAKE_PERSISTABLE_URI_PERMISSION.equals(action)) {
-            Log.i(TAG, "Taking persistable uri permission to " + uri);
-            getContentResolver().takePersistableUriPermission(uri,
-                    Intent.FLAG_GRANT_READ_URI_PERMISSION);
-            setResult(Activity.RESULT_OK);
         }
         finish();
     }
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/ContentTest.java
similarity index 94%
rename from hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java
rename to hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/ContentTest.java
index 47de0da..1aaa5ab 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderTest.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/ContentTest.java
@@ -32,7 +32,7 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 
-public class IntentSenderTest extends InstrumentationTestCase {
+public class ContentTest extends InstrumentationTestCase {
 
     private static final String MESSAGE = "Sample Message";
 
@@ -57,8 +57,8 @@
 
     @Override
     public void tearDown() throws Exception {
-        super.tearDown();
         mActivity.finish();
+        super.tearDown();
     }
 
     /**
@@ -73,7 +73,7 @@
         intent.setClipData(ClipData.newRawUri("", uri));
         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
-        final Intent result = mActivity.getResult(intent);
+        final Intent result = mActivity.getCrossProfileResult(intent);
         assertNotNull(result);
         assertEquals(MESSAGE, result.getStringExtra("extra_response"));
     }
@@ -95,7 +95,7 @@
         intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                 | Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
-        mActivity.getResult(intent);
+        mActivity.getCrossProfileResult(intent);
         assertEquals(MESSAGE, getFirstLineFromUri(uri));
     }
 
@@ -107,7 +107,7 @@
         Intent intent = new Intent(ACTION_READ_FROM_URI);
         intent.setClipData(ClipData.newRawUri("", uri));
 
-        final Intent result = mActivity.getResult(intent);
+        final Intent result = mActivity.getCrossProfileResult(intent);
         assertNotNull(result);
         assertEquals(MESSAGE, result.getStringExtra("extra_response"));
     }
@@ -136,7 +136,7 @@
         Intent notGrant = new Intent(ACTION_READ_FROM_URI);
         notGrant.setClipData(ClipData.newRawUri("", uriNotGranted));
 
-        final Intent result = mActivity.getResult(notGrant);
+        final Intent result = mActivity.getCrossProfileResult(notGrant);
         assertNotNull(result);
         // The receiver did not have permission to read the uri. So it should have caught a security
         // exception.
@@ -155,7 +155,7 @@
         intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
         // We're expecting to run into a security exception
-        final Intent result = mActivity.getResult(intent);
+        final Intent result = mActivity.getCrossProfileResult(intent);
         if (result == null) {
             // This is fine; probably of a SecurityException when off in the
             // system somewhere.
@@ -170,7 +170,7 @@
         grantPersistable.setClipData(ClipData.newRawUri("", uri));
         grantPersistable.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
-        mActivity.getResult(grantPersistable);
+        mActivity.getCrossProfileResult(grantPersistable);
     }
 
     private Uri getBasicContentProviderUri(String path) {
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java
new file mode 100644
index 0000000..a5d83db
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 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.cts.intent.sender;
+
+import android.content.ClipboardManager;
+import android.content.ClipData;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class CopyPasteTest extends InstrumentationTestCase
+        implements ClipboardManager.OnPrimaryClipChangedListener {
+
+    private IntentSenderActivity mActivity;
+    private ClipboardManager mClipboard;
+    private Semaphore mNotified;
+
+    private static String ACTION_COPY_TO_CLIPBOARD = "com.android.cts.action.COPY_TO_CLIPBOARD";
+
+    private static String INITIAL_TEXT = "initial text";
+    private static String NEW_TEXT = "sample text";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        Context context = getInstrumentation().getTargetContext();
+        mActivity = launchActivity(context.getPackageName(), IntentSenderActivity.class, null);
+        mClipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mActivity.finish();
+        super.tearDown();
+    }
+
+    public void testCanReadAcrossProfiles() throws Exception {
+        ClipData clip = ClipData.newPlainText(""/*label*/, INITIAL_TEXT);
+        mClipboard.setPrimaryClip(clip);
+        assertEquals(INITIAL_TEXT , getTextFromClipboard());
+
+        askCrossProfileReceiverToCopy(NEW_TEXT);
+
+        assertEquals(NEW_TEXT, getTextFromClipboard());
+    }
+
+    public void testCannotReadAcrossProfiles() throws Exception {
+        ClipData clip = ClipData.newPlainText(""/*label*/, INITIAL_TEXT);
+        mClipboard.setPrimaryClip(clip);
+        assertEquals(INITIAL_TEXT , getTextFromClipboard());
+
+        askCrossProfileReceiverToCopy(NEW_TEXT);
+
+        String clipboardText = getTextFromClipboard();
+        assertTrue("The clipboard text is " + clipboardText + " but should be <null> or "
+                + INITIAL_TEXT, clipboardText == null || clipboardText.equals(INITIAL_TEXT));
+    }
+
+    public void testIsNotified() throws Exception {
+        try {
+            mNotified = new Semaphore(0);
+            mActivity.addPrimaryClipChangedListener(this);
+
+            askCrossProfileReceiverToCopy(NEW_TEXT);
+
+            assertTrue(mNotified.tryAcquire(5, TimeUnit.SECONDS));
+        } finally {
+            mActivity.removePrimaryClipChangedListener(this);
+        }
+    }
+
+    private void askCrossProfileReceiverToCopy(String text) throws Exception {
+        Intent intent = new Intent(ACTION_COPY_TO_CLIPBOARD);
+        intent.putExtra("extra_text", text);
+        mActivity.getCrossProfileResult(intent);
+    }
+
+    private String getTextFromClipboard() {
+        ClipData clip = mClipboard.getPrimaryClip();
+        if (clip == null) {
+            return null;
+        }
+        ClipData.Item item = clip.getItemAt(0);
+        if (item == null) {
+            return null;
+        }
+        CharSequence text = item.getText();
+        if (text == null) {
+            return null;
+        }
+        return text.toString();
+    }
+
+
+    @Override
+    public void onPrimaryClipChanged() {
+        mNotified.release();
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
index 00fa6b7..fd421ac 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
@@ -17,15 +17,27 @@
 package com.android.cts.intent.sender;
 
 import android.app.Activity;
+import android.content.ClipboardManager;
+import android.content.ClipboardManager.OnPrimaryClipChangedListener;
+import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.util.Log;
 
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.List;
 
 public class IntentSenderActivity extends Activity {
 
+    private static String TAG = "IntentSenderActivity";
+
     private final SynchronousQueue<Result> mResult = new SynchronousQueue<>();
 
+    private ClipboardManager mClipboardManager;
+
     public static class Result {
         public final int resultCode;
         public final Intent data;
@@ -37,6 +49,12 @@
     }
 
     @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mClipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+    }
+
+    @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (resultCode == Activity.RESULT_OK) {
             try {
@@ -52,4 +70,38 @@
         final Result result = mResult.poll(30, TimeUnit.SECONDS);
         return (result != null) ? result.data : null;
     }
+
+    /**
+     * This method will send an intent accross profiles to IntentReceiverActivity, and return the
+     * result intent set by IntentReceiverActivity.
+     */
+    public Intent getCrossProfileResult(Intent intent)
+            throws Exception {
+        PackageManager pm = getPackageManager();
+        List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        //  There should be two matches:
+        //  - com.android.cts.intent.receiver (on the current profile).
+        //  - One that will send the intent to the other profile.
+        //  It's the second one we want to send the intent to.
+
+        for (ResolveInfo ri : ris) {
+            if (!ri.activityInfo.packageName.equals("com.android.cts.intent.receiver")) {
+                intent.setComponent(new ComponentName(ri.activityInfo.packageName,
+                        ri.activityInfo.name));
+                return getResult(intent);
+            }
+        }
+        Log.e(TAG, "The intent " + intent + " cannot be sent accross profiles");
+        return null;
+    }
+
+    public void addPrimaryClipChangedListener(OnPrimaryClipChangedListener listener) {
+        mClipboardManager.addPrimaryClipChangedListener(listener);
+    }
+
+    public void removePrimaryClipChangedListener(
+            OnPrimaryClipChangedListener listener) {
+        mClipboardManager.removePrimaryClipChangedListener(listener);
+    }
+
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
index 9615991..49001e9 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
@@ -21,8 +21,15 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.IntentFilter;
+import android.os.UserManager;
 import android.test.AndroidTestCase;
 
+/**
+ * The methods in this class are not really tests.
+ * They are just performing an action that is needed for a test.
+ * But we're still using an AndroidTestCase because it's an easy way to call
+ * device-side methods from the host.
+ */
 public class CrossProfileUtils extends AndroidTestCase {
     private static final String ACTION_READ_FROM_URI = "com.android.cts.action.READ_FROM_URI";
 
@@ -31,16 +38,14 @@
     private static final String ACTION_TAKE_PERSISTABLE_URI_PERMISSION =
             "com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION";
 
+    private static String ACTION_COPY_TO_CLIPBOARD = "com.android.cts.action.COPY_TO_CLIPBOARD";
+
     public void addParentCanAccessManagedFilters() {
         removeAllFilters();
 
         final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(ACTION_READ_FROM_URI);
-        intentFilter.addAction(ACTION_WRITE_TO_URI);
-        intentFilter.addAction(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
-        dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, intentFilter,
+        dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, getIntentFilter(),
                 DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
     }
 
@@ -49,12 +54,17 @@
 
         final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
+        dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, getIntentFilter(),
+                DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+    }
+
+    public IntentFilter getIntentFilter() {
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(ACTION_READ_FROM_URI);
         intentFilter.addAction(ACTION_WRITE_TO_URI);
         intentFilter.addAction(ACTION_TAKE_PERSISTABLE_URI_PERMISSION);
-        dpm.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT, intentFilter,
-                DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+        intentFilter.addAction(ACTION_COPY_TO_CLIPBOARD);
+        return intentFilter;
     }
 
     public void removeAllFilters() {
@@ -62,4 +72,18 @@
                 Context.DEVICE_POLICY_SERVICE);
         dpm.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
     }
+
+    public void disallowCrossProfileCopyPaste() {
+        DevicePolicyManager dpm = (DevicePolicyManager)
+               getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+        dpm.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
+    }
+
+    public void allowCrossProfileCopyPaste() {
+        DevicePolicyManager dpm = (DevicePolicyManager)
+               getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+        dpm.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
+                UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 6ece85c..51b7930 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -49,6 +49,8 @@
         if (mHasFeature) {
             mUserId = createManagedProfile();
             installApp(MANAGED_PROFILE_APK);
+            installApp(INTENT_RECEIVER_APK);
+            installApp(INTENT_SENDER_APK);
             setProfileOwner(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
             startUser(mUserId);
         }
@@ -59,8 +61,9 @@
         if (mHasFeature) {
             removeUser(mUserId);
             getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
+            getDevice().uninstallPackage(INTENT_SENDER_PKG);
+            getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
         }
-
         super.tearDown();
     }
 
@@ -114,30 +117,58 @@
             return;
         }
 
-        try {
-            getDevice().uninstallPackage(INTENT_SENDER_PKG);
-            getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
-            installAppAsUser(INTENT_SENDER_APK, 0);
-            installAppAsUser(INTENT_RECEIVER_APK, mUserId);
+        // Test from parent to managed
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+                "removeAllFilters", mUserId));
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+                "addManagedCanAccessParentFilters", mUserId));
+        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", 0));
 
-            // Test from parent to managed
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                    "addManagedCanAccessParentFilters", mUserId));
-            assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".IntentSenderTest", 0));
+        // Test from managed to parent
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+                "removeAllFilters", mUserId));
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+                "addParentCanAccessManagedFilters", mUserId));
+        assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", mUserId));
 
-            getDevice().uninstallPackage(INTENT_SENDER_PKG);
-            getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
-            installAppAsUser(INTENT_SENDER_APK, mUserId);
-            installAppAsUser(INTENT_RECEIVER_APK, 0);
+    }
 
-            // Test from managed to parent
-            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                    "addParentCanAccessManagedFilters", mUserId));
-            assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".IntentSenderTest", mUserId));
+    public void testCrossProfileCopyPaste() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
 
-        } finally {
-            getDevice().uninstallPackage(INTENT_SENDER_PKG);
-            getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+                "allowCrossProfileCopyPaste", mUserId));
+        // Test that managed can see what is copied in the parent.
+        testCrossProfileCopyPasteInternal(mUserId, true);
+        // Test that the parent can see what is copied in managed.
+        testCrossProfileCopyPasteInternal(0, true);
+
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+                "disallowCrossProfileCopyPaste", mUserId));
+        // Test that managed can still see what is copied in the parent.
+        testCrossProfileCopyPasteInternal(mUserId, true);
+        // Test that the parent cannot see what is copied in managed.
+        testCrossProfileCopyPasteInternal(0, false);
+    }
+
+    private void testCrossProfileCopyPasteInternal(int userId, boolean shouldSucceed)
+            throws DeviceNotAvailableException {
+        final String direction = (userId == 0) ? "addManagedCanAccessParentFilters"
+                : "addParentCanAccessManagedFilters";
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+                "removeAllFilters", mUserId));
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
+                direction, mUserId));
+        if (shouldSucceed) {
+            assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".CopyPasteTest",
+                    "testCanReadAcrossProfiles", userId));
+            assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".CopyPasteTest",
+                    "testIsNotified", userId));
+        } else {
+            assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".CopyPasteTest",
+                    "testCannotReadAcrossProfiles", userId));
         }
     }
 
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index ff3f921..df8fe13 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -129,6 +129,7 @@
     "com.android.cts.devicepolicy.ManagedProfileTest#testCrossProfileIntentFilters",
     "com.android.cts.devicepolicy.ManagedProfileTest#testCrossProfileContent",
     "com.android.cts.devicepolicy.ManagedProfileTest#testNoDebuggingFeaturesRestriction"
+    "com.android.cts.devicepolicy.ManagedProfileTest#testCrossProfileCopyPaste",
   ]
 },
 {