Test that creating ephemeral users fails on systems without
split system user.

BUG: 27143201

Change-Id: Ia77f7480e9cf444a4599449c9b22d052e5b22b4e
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
index 3246401..cf28e7d 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -50,4 +50,31 @@
                 makeEphemeralFlag);
     }
 
+    /**
+     * Test creating an ephemeral user using the {@link DevicePolicyManager#createAndManageUser}
+     * method fails on systems without the split system user.
+     *
+     * <p>To be used by host-side test on systems without the split system user.
+     */
+    public void testCreateAndManageEphemeralUserFails() throws Exception {
+        String testUserName = "TestUser_" + System.currentTimeMillis();
+
+        // Use reflection to get the value of the hidden flag to make the new user ephemeral.
+        Field field = DevicePolicyManager.class.getField("MAKE_USER_EPHEMERAL");
+        int makeEphemeralFlag = field.getInt(null);
+
+        try {
+            mDevicePolicyManager.createAndManageUser(
+                    getWho(),
+                    testUserName,
+                    getWho(),
+                    null,
+                    makeEphemeralFlag);
+        } catch (IllegalArgumentException e) {
+            // Success, the expected exception was thrown.
+            return;
+        }
+        fail("createAndManageUser should have thrown IllegalArgumentException");
+    }
+
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ForceEphemeralUsersTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ForceEphemeralUsersTest.java
index a5f59d4..c5fa4b2 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ForceEphemeralUsersTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ForceEphemeralUsersTest.java
@@ -19,6 +19,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 /**
@@ -43,4 +44,23 @@
         assertTrue((boolean) getForceEphemeralUsersMethod.invoke(mDevicePolicyManager, getWho()));
     }
 
+    /**
+     * Setting force-ephemeral-user policy should fail if not on system with split system user.
+     *
+     * <p>To be run on systems without split system user.
+     */
+    public void testSetForceEphemeralUsersFails() throws Exception {
+        Method setForceEphemeralUsersMethod = DevicePolicyManager.class.getDeclaredMethod(
+                "setForceEphemeralUsers", ComponentName.class, boolean.class);
+        try {
+            setForceEphemeralUsersMethod.invoke(mDevicePolicyManager, getWho(), true);
+        } catch (InvocationTargetException e) {
+            if (e.getCause() instanceof UnsupportedOperationException) {
+                // Test passed, the exception was thrown as expected.
+                return;
+            }
+        }
+        fail("UnsupportedOperationException should have been thrown by setForceEphemeralUsers");
+    }
+
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index c49dbb3..0b32a19 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -43,6 +43,15 @@
     private static final String CLEAR_DEVICE_OWNER_TEST_CLASS =
             DEVICE_OWNER_PKG + ".ClearDeviceOwnerTest";
 
+    /** The ephemeral users are implemented and supported on the device. */
+    private boolean mHasEphemeralUserFeature;
+
+    /**
+     * Ephemeral users are implemented, but unsupported on the device (because of missing split
+     * system user).
+     */
+    private boolean mHasDisabledEphemeralUserFeature;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -51,6 +60,9 @@
             assertTrue("Failed to set device owner",
                     setDeviceOwner(DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
         }
+        mHasEphemeralUserFeature = mHasFeature && canCreateAdditionalUsers(1) && hasUserSplit();
+        mHasDisabledEphemeralUserFeature =
+                mHasFeature && canCreateAdditionalUsers(1) && !hasUserSplit();
     }
 
     @Override
@@ -109,12 +121,20 @@
 
     /** Tries to toggle the force-ephemeral-users on and checks it was really set. */
     public void testSetForceEphemeralUsers() throws Exception {
-        if (!mHasFeature || getDevice().getApiLevel() < 24 /* Build.VERSION_CODES.N */
-                || !canCreateAdditionalUsers(1)) {
+        if (!mHasEphemeralUserFeature) {
             return;
         }
         // Set force-ephemeral-users policy and verify it was set.
-        executeDeviceOwnerTest("ForceEphemeralUsersTest");
+        executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsers");
+    }
+
+    /**
+     * Setting force-ephemeral-users policy to true without a split system user should fail.
+     */
+    public void testSetForceEphemeralUsersFailsWithoutSplitSystemUser() throws Exception {
+        if (mHasDisabledEphemeralUserFeature) {
+            executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsersFails");
+        }
     }
 
     /**
@@ -124,8 +144,7 @@
      * <p>If the current user is the system user, the other users are removed straight away.
      */
     public void testRemoveUsersOnSetForceEphemeralUsers() throws Exception {
-        if (!mHasFeature || getDevice().getApiLevel() < 24 /* Build.VERSION_CODES.N */
-                || !canCreateAdditionalUsers(1)) {
+        if (!mHasEphemeralUserFeature) {
             return;
         }
 
@@ -134,7 +153,7 @@
         assertTrue("User must have been created", listUsers().contains(userId));
 
         // Set force-ephemeral-users policy and verify it was set.
-        executeDeviceOwnerTest("ForceEphemeralUsersTest");
+        executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsers");
 
         // Users have to be removed when force-ephemeral-users is toggled on.
         assertFalse("User must have been removed", listUsers().contains(userId));
@@ -148,8 +167,7 @@
      * before all other users are removed.
      */
     public void testRemoveUsersOnSetForceEphemeralUsersWithUserSwitch() throws Exception {
-        if (!mHasFeature || getDevice().getApiLevel() < 24 /* Build.VERSION_CODES.N */
-                || !canCreateAdditionalUsers(1)) {
+        if (!mHasEphemeralUserFeature) {
             return;
         }
 
@@ -161,7 +179,7 @@
         switchUser(userId);
 
         // Set force-ephemeral-users policy and verify it was set.
-        executeDeviceOwnerTestAsUser("ForceEphemeralUsersTest", 0);
+        executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsers");
 
         // Make sure the user has been removed. As it is not a synchronous operation - switching to
         // the system user must happen first - give the system a little bit of time for finishing
@@ -184,13 +202,12 @@
 
     /** The users created after setting force-ephemeral-users policy to true must be ephemeral. */
     public void testCreateUserAfterSetForceEphemeralUsers() throws Exception {
-        if (!mHasFeature || getDevice().getApiLevel() < 24 /* Build.VERSION_CODES.N */
-                || !canCreateAdditionalUsers(1)) {
+        if (!mHasEphemeralUserFeature) {
             return;
         }
 
         // Set force-ephemeral-users policy and verify it was set.
-        executeDeviceOwnerTest("ForceEphemeralUsersTest");
+        executeDeviceTestMethod(".ForceEphemeralUsersTest", "testSetForceEphemeralUsers");
 
         int userId = createUser();
         assertTrue("User must be ephemeral", 0 != (getUserFlags(userId) & FLAG_EPHEMERAL));
@@ -200,14 +217,12 @@
      * Test creating an epehemeral user using the DevicePolicyManager's createAndManageUser method.
      */
     public void testCreateAndManageEphemeralUser() throws Exception {
-        if (!mHasFeature || getDevice().getApiLevel() < 24 /* Build.VERSION_CODES.N */
-                || !canCreateAdditionalUsers(1)) {
+        if (!mHasEphemeralUserFeature) {
             return;
         }
 
         ArrayList<Integer> originalUsers = listUsers();
-        assertTrue(runDeviceTests(DEVICE_OWNER_PKG, ".CreateAndManageUserTest",
-                "testCreateAndManageEphemeralUser", 0));
+        executeDeviceTestMethod(".CreateAndManageUserTest", "testCreateAndManageEphemeralUser");
 
         ArrayList<Integer> newUsers = listUsers();
 
@@ -229,6 +244,17 @@
         assertEquals("Ephemeral flag must be set", FLAG_EPHEMERAL, flags & FLAG_EPHEMERAL);
     }
 
+    /**
+     * Test that creating an epehemeral user using the DevicePolicyManager's createAndManageUser
+     * method fails on systems without the split system user.
+     */
+    public void testCreateAndManageEphemeralUserFailsWithoutSplitSystemUser() throws Exception {
+        if (mHasDisabledEphemeralUserFeature) {
+            executeDeviceTestMethod(
+                    ".CreateAndManageUserTest", "testCreateAndManageEphemeralUserFails");
+        }
+    }
+
     public void testDeviceLoggingWithTwoUsers() throws Exception {
         if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
             return;
@@ -305,12 +331,4 @@
         assertTrue(runDeviceTestsAsUser(DEVICE_OWNER_PKG, className, testName,
                 /* deviceOwnerUserId */ 0));
     }
-
-    private void executeDeviceOwnerTestAsUser(String testClassName, int userId) throws Exception {
-        if (!mHasFeature) {
-            return;
-        }
-        String testClass = DEVICE_OWNER_PKG + "." + testClassName;
-        assertTrue(testClass + " failed.", runDeviceTestsAsUser(DEVICE_OWNER_PKG, testClass, userId));
-    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/EphemeralUserTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/EphemeralUserTest.java
index 2133431..df4a47c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/EphemeralUserTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/EphemeralUserTest.java
@@ -24,8 +24,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mHasFeature = getDevice().getApiLevel() >= 24 /* Build.VERSION_CODES.N */
-                && canCreateAdditionalUsers(1);
+        mHasFeature = canCreateAdditionalUsers(1);
     }
 
     @Override
@@ -36,7 +35,7 @@
 
     /** The user should have the ephemeral flag set if it was created as ephemeral. */
     public void testCreateEphemeralUser() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !hasUserSplit()) {
             return;
         }
         int userId = createUser(FLAG_EPHEMERAL);
@@ -73,7 +72,7 @@
      * Ephemeral user should be automatically removed after it is stopped.
      */
     public void testRemoveEphemeralOnStop() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !hasUserSplit()) {
             return;
         }
         int userId = createUser(FLAG_EPHEMERAL);
@@ -88,7 +87,7 @@
      * and not ephemeral when the feature is not set.
      */
     public void testEphemeralGuestFeature() throws Exception {
-        if (!mHasFeature) {
+        if (!mHasFeature || !hasUserSplit()) {
             return;
         }
         // Create a guest user.
@@ -104,6 +103,20 @@
         }
     }
 
+    /**
+     * Test that creating an ephemeral user fails on systems without the split system user.
+     */
+    public void testCreateEphemeralWithoutUserSplitFails() throws Exception {
+        if (!mHasFeature || hasUserSplit()) {
+            return;
+        }
+        String command ="pm create-user --ephemeral " + "TestUser_" + System.currentTimeMillis();
+        String commandOutput = getDevice().executeShellCommand(command);
+
+        assertEquals("Creating the epehemeral user should fail.",
+                "Error: couldn't create User.", commandOutput.trim());
+    }
+
     private boolean getGuestUsersEphemeral() throws Exception {
         String commandOutput = getDevice().executeShellCommand("dumpsys user");
         String[] outputLines = commandOutput.split("\n");