Tests for cross-profile intent filters

Bug: 15900074
Change-Id: Id67285cccc7c08173154144de7d37ad9a2ff1bb4
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml
index 1aaf99f..e78ef37 100644
--- a/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/AndroidManifest.xml
@@ -30,6 +30,32 @@
                 <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
             </intent-filter>
         </receiver>
+        <activity android:name=".PrimaryUserFilterSetterActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.cts.profileowner.ACTION_TEST_SET_FILTERS" />
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".ManagedProfileActivity">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <action android:name="com.android.cts.profileowner.ACTION_TEST_MANAGED_ACTIVITY" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".PrimaryUserActivity">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <action android:name="com.android.cts.profileowner.ACTION_TEST_PRIMARY_ACTIVITY" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".AllUsersActivity">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <action android:name="com.android.cts.profileowner.ACTION_TEST_ALL_ACTIVITY" />
+            </intent-filter>
+        </activity>
     </application>
 
     <instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java
index e7ccc74..daee77f 100644
--- a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/BaseProfileOwnerTest.java
@@ -32,7 +32,7 @@
     public static class BasicAdminReceiver extends DeviceAdminReceiver {
     }
 
-    static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName(
+    public static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName(
             BasicAdminReceiver.class.getPackage().getName(), BasicAdminReceiver.class.getName());
 
     protected DevicePolicyManager mDevicePolicyManager;
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/AllUsersActivity.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/AllUsersActivity.java
new file mode 100644
index 0000000..fbbfac5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/AllUsersActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.profileowner;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Activity that lives in both primary user and its profile.
+ */
+public class AllUsersActivity extends Activity {
+    private static final String TAG = AllUsersActivity.class.getName();
+
+    public static final String ACTION =
+            "com.android.cts.profileowner.ACTION_TEST_ALL_ACTIVITY";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "Roger that!");
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/ManagedProfileActivity.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/ManagedProfileActivity.java
new file mode 100644
index 0000000..2cd3ad9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/ManagedProfileActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.profileowner;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Activity that lives in the managed profile.
+ */
+public class ManagedProfileActivity extends Activity {
+    private static final String TAG = ManagedProfileActivity.class.getName();
+
+    public static final String ACTION =
+            "com.android.cts.profileowner.ACTION_TEST_MANAGED_ACTIVITY";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "Roger that!");
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/ManagedProfileTest.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/ManagedProfileTest.java
new file mode 100644
index 0000000..9ce08bb
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/ManagedProfileTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.profileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+
+/**
+ * Test for {@link DevicePolicyManager#addCrossProfileIntentFilter} API.
+ *
+ * Note that it expects that there is an activity responding to {@code PrimaryUserActivity.ACTION}
+ * in the primary profile, one to {@code ManagedProfileActivity.ACTION} in the secondary profile,
+ * and one to {@code AllUsersActivity.ACTION} in both profiles.
+ */
+public class ManagedProfileTest extends BaseProfileOwnerTest {
+
+    private PackageManager mPackageManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mPackageManager = getContext().getPackageManager();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
+        super.tearDown();
+    }
+
+    public void testClearCrossProfileIntentFilters() {
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(PrimaryUserActivity.ACTION);
+        mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+
+        mDevicePolicyManager.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
+
+        assertTrue(mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).isEmpty());
+    }
+
+    public void testAddCrossProfileIntentFilter_primary() {
+        assertEquals(0, mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(PrimaryUserActivity.ACTION);
+        mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+    }
+
+    public void testAddCrossProfileIntentFilter_all() {
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(AllUsersActivity.ACTION), /* flags = */ 0).size());
+
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(AllUsersActivity.ACTION);
+        mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+
+        assertEquals(2, mPackageManager.queryIntentActivities(
+                new Intent(AllUsersActivity.ACTION), /* flags = */ 0).size());
+    }
+
+    public void testAddCrossProfileIntentFilter_managed() {
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0).size());
+
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(ManagedProfileActivity.ACTION);
+        mDevicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
+
+        // We should still be resolving in the profile
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0).size());
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserActivity.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserActivity.java
new file mode 100644
index 0000000..0f18e96
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.profileowner;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Activity for that lives in the primary user.
+ */
+public class PrimaryUserActivity extends Activity {
+    private static final String TAG = PrimaryUserActivity.class.getName();
+
+    public static final String ACTION =
+            "com.android.cts.profileowner.ACTION_TEST_PRIMARY_ACTIVITY";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "Roger that!");
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserFilterSetterActivity.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserFilterSetterActivity.java
new file mode 100644
index 0000000..b44227d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserFilterSetterActivity.java
@@ -0,0 +1,43 @@
+package com.android.cts.profileowner;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Log;
+
+import static com.android.cts.profileowner.BaseProfileOwnerTest.ADMIN_RECEIVER_COMPONENT;
+
+/**
+ * Class that sets the cross-profile intent filters required to test intent filtering from
+ * the primary profile to the managed one.
+ */
+public class PrimaryUserFilterSetterActivity extends Activity {
+
+    public static final String TAG = PrimaryUserFilterSetterActivity.class.getName();
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        PackageManager packageManager = getPackageManager();
+        DevicePolicyManager devicePolicyManager = (DevicePolicyManager)
+                getSystemService(Context.DEVICE_POLICY_SERVICE);
+        IntentFilter testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(PrimaryUserActivity.ACTION);
+        devicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+
+        testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(ManagedProfileActivity.ACTION);
+        devicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+
+        testIntentFilter = new IntentFilter();
+        testIntentFilter.addAction(AllUsersActivity.ACTION);
+        devicePolicyManager.addCrossProfileIntentFilter(ADMIN_RECEIVER_COMPONENT,
+                testIntentFilter, DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
+        Log.i(TAG, "Roger that!");
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserTest.java b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserTest.java
new file mode 100644
index 0000000..cd665a9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ProfileOwner/src/com/android/cts/profileowner/crossprofileintentfilters/PrimaryUserTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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.profileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.test.AndroidTestCase;
+
+/**
+ * Test for {@link DevicePolicyManager#addCrossProfileIntentFilter} API, for
+ * {@code DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT}.
+ *
+ * Note that it expects that there is an activity responding to {@code PrimaryUserActivity.ACTION}
+ * in the primary profile, one to {@code ManagedProfileActivity.ACTION} in the secondary profile,
+ * and one to {@code AllUsersActivity.ACTION} in both profiles.
+ *
+ * Note that the {code DevicePolicyManager#clearCrossProfileIntentFilters} as well as more complex
+ * test scenarios can be found in {@link ManagedProfileTest}.
+ */
+public class PrimaryUserTest extends AndroidTestCase {
+
+    private PackageManager mPackageManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mPackageManager = getContext().getPackageManager();
+    }
+
+    public void testAddCrossProfileIntentFilter_primary() {
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(PrimaryUserActivity.ACTION), /* flags = */ 0).size());
+    }
+
+    public void testAddCrossProfileIntentFilter_all() {
+        assertEquals(2, mPackageManager.queryIntentActivities(
+                new Intent(AllUsersActivity.ACTION), /* flags = */ 0).size());
+    }
+
+    public void testAddCrossProfileIntentFilter_managed() {
+        assertEquals(1, mPackageManager.queryIntentActivities(
+                new Intent(ManagedProfileActivity.ACTION), /* flags = */ 0).size());
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
index 6d51f9e..a98f950 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ProfileOwnerTest.java
@@ -74,9 +74,21 @@
             mUserId = createUser();
             installApp(PROFILE_OWNER_APK);
             setProfileOwner(PROFILE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS);
+            startManagedProfile();
         }
     }
 
+    /**
+     * Initializes the user that underlies the managed profile.
+     * This is required so that apps can run on it.
+     */
+    private void startManagedProfile() throws Exception  {
+        String command = "am start-user " + mUserId;
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+        assertTrue(commandOutput.startsWith("Success:"));
+    }
+
     @Override
     protected void tearDown() throws Exception {
         if (mHasFeature) {
@@ -109,7 +121,7 @@
             return;
         }
         String[] testClassNames = {
-                "ProfileOwnerSetupTest"
+                "ProfileOwnerSetupTest",
         };
         for (String className : testClassNames) {
             String testClass = PROFILE_OWNER_PKG + "." + className;
@@ -117,6 +129,36 @@
         }
     }
 
+    public void testCrossProfileIntentFilters() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // Set up activities: ManagedProfileActivity will only be enabled in the managed profile and
+        // PrimaryUserActivity only in the primary one
+        disableActivityForUser("ManagedProfileActivity", 0);
+        disableActivityForUser("PrimaryUserActivity", mUserId);
+
+        assertTrue(runDeviceTestsAsUser(PROFILE_OWNER_PKG,
+                PROFILE_OWNER_PKG + ".ManagedProfileTest", mUserId));
+
+        // Set up filters from primary to managed profile
+        String command = "am start -W --user " + mUserId  + " " + PROFILE_OWNER_PKG
+                + "/.PrimaryUserFilterSetterActivity";
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+              + getDevice().executeShellCommand(command));
+        assertTrue(runDeviceTests(PROFILE_OWNER_PKG, PROFILE_OWNER_PKG + ".PrimaryUserTest"));
+        // TODO: Test with startActivity
+        // TODO: Test with CtsVerifier for disambiguation cases
+    }
+
+    private void disableActivityForUser(String activityName, int userId)
+            throws DeviceNotAvailableException {
+        String command = "pm disable --user " + userId + " " + PROFILE_OWNER_PKG + "/."
+                + activityName;
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+                + getDevice().executeShellCommand(command));
+    }
+
     private boolean hasDeviceFeatures(String[] requiredFeatures)
             throws DeviceNotAvailableException {
         // TODO: Move this logic to ITestDevice.
@@ -204,7 +246,7 @@
 
     private boolean runDeviceTests(String pkgName, @Nullable String testClassName,
             @Nullable String testMethodName, @Nullable Integer userId)
-            throws DeviceNotAvailableException {
+                    throws DeviceNotAvailableException {
         TestRunResult runResult = (userId == null)
                 ? doRunTests(pkgName, testClassName, testMethodName)
                 : doRunTestsAsUser(pkgName, testClassName, testMethodName, userId);