CTS: Add tests for UserManager.isDemoUser() api.

Bug: 31092477
Test: cts-tradefed run singleCommand cts --module CtsRetailDemoHostTestCases
Change-Id: I6a17515dac13e8a8cef629f87dfbc999d022e162
diff --git a/hostsidetests/retaildemo/Android.mk b/hostsidetests/retaildemo/Android.mk
new file mode 100644
index 0000000..0aa5ee1
--- /dev/null
+++ b/hostsidetests/retaildemo/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2016 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CtsRetailDemoHostTestCases
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := tools-common-prebuilt cts-tradefed tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.retaildemo
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/retaildemo/AndroidTest.xml b/hostsidetests/retaildemo/AndroidTest.xml
new file mode 100644
index 0000000..c174489
--- /dev/null
+++ b/hostsidetests/retaildemo/AndroidTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<configuration description="Config for the CTS retaildemo host tests">
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="test-file-name" value="CtsRetailDemoApp.apk" />
+        <option name="cleanup-apks" value="true" />
+    </target_preparer>
+
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsRetailDemoHostTestCases.jar" />
+    </test>
+
+</configuration>
\ No newline at end of file
diff --git a/hostsidetests/retaildemo/app/Android.mk b/hostsidetests/retaildemo/app/Android.mk
new file mode 100644
index 0000000..e91e1da
--- /dev/null
+++ b/hostsidetests/retaildemo/app/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2016 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsRetailDemoApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/retaildemo/app/AndroidManifest.xml b/hostsidetests/retaildemo/app/AndroidManifest.xml
new file mode 100644
index 0000000..b36ee1b
--- /dev/null
+++ b/hostsidetests/retaildemo/app/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2016 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.retaildemo">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:targetPackage="com.android.cts.retaildemo"
+            android:label="RetailDemo device side tests" />
+</manifest>
diff --git a/hostsidetests/retaildemo/app/src/com/android/cts/retaildemo/DemoUserTest.java b/hostsidetests/retaildemo/app/src/com/android/cts/retaildemo/DemoUserTest.java
new file mode 100644
index 0000000..bb20b1a
--- /dev/null
+++ b/hostsidetests/retaildemo/app/src/com/android/cts/retaildemo/DemoUserTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 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.retaildemo;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.content.Context;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@SmallTest
+@RunWith(JUnit4.class)
+public class DemoUserTest {
+    private UserManager mUm;
+
+    @Before
+    public void setUp() {
+        mUm = InstrumentationRegistry.getContext().getSystemService(UserManager.class);
+    }
+
+    @Test
+    public void testIsDemoUser_success() {
+        assertTrue(mUm.isDemoUser());
+    }
+
+    @Test
+    public void testIsDemoUser_failure() {
+        assertFalse(mUm.isDemoUser());
+    }
+}
diff --git a/hostsidetests/retaildemo/src/android/host/retaildemo/BaseTestCase.java b/hostsidetests/retaildemo/src/android/host/retaildemo/BaseTestCase.java
new file mode 100644
index 0000000..5033b6d
--- /dev/null
+++ b/hostsidetests/retaildemo/src/android/host/retaildemo/BaseTestCase.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2016 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 android.host.retaildemo;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestResult;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Map;
+
+public class BaseTestCase extends DeviceTestCase implements IBuildReceiver {
+    private static final String RETAIL_DEMO_TEST_PKG = "com.android.cts.retaildemo";
+    private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
+
+    private IBuildInfo mBuildInfo;
+    private CompatibilityBuildHelper mBuildHelper;
+
+    private ArrayList<Integer> mTestUsers;
+
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mBuildInfo = buildInfo;
+        mBuildHelper = new CompatibilityBuildHelper(mBuildInfo);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        assertNotNull(mBuildInfo); // ensure build has been set before test is run.
+        mTestUsers = new ArrayList<>();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        for (int userId : mTestUsers) {
+            getDevice().removeUser(userId);
+        }
+        super.tearDown();
+    }
+
+    protected int createDemoUser() throws DeviceNotAvailableException, IllegalStateException {
+        final String command = "pm create-user --ephemeral --demo "
+                + "TestUser_" + System.currentTimeMillis();
+        CLog.d("Starting command: " + command);
+        final String output = getDevice().executeShellCommand(command);
+        CLog.d("Output for command " + command + ": " + output);
+
+        if (output.startsWith("Success")) {
+            try {
+                int userId = Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
+                mTestUsers.add(userId);
+                return userId;
+            } catch (NumberFormatException e) {
+                CLog.e("Failed to parse result: %s", output);
+            }
+        } else {
+            CLog.e("Failed to create demo user: %s", output);
+        }
+        throw new IllegalStateException();
+    }
+
+    protected void installAppAsUser(String appFileName, int userId)
+            throws FileNotFoundException, DeviceNotAvailableException {
+        CLog.d("Installing app " + appFileName + " for user " + userId);
+        File apkFile = new File(mBuildHelper.getTestsDir(), appFileName);
+        final String result = getDevice().installPackageForUser(
+                apkFile, true, true, userId, "-t");
+        assertNull("Failed to install " + appFileName + " for user " + userId + ": " + result,
+                result);
+    }
+
+    protected boolean runDeviceTestsAsUser(String testClassName, String testMethodName, int userId)
+            throws Exception {
+        if (testClassName != null && testClassName.startsWith(".")) {
+            testClassName = RETAIL_DEMO_TEST_PKG + testClassName;
+        }
+
+        RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
+                RETAIL_DEMO_TEST_PKG, RUNNER, getDevice().getIDevice());
+        if (testClassName != null && testMethodName != null) {
+            testRunner.setMethodName(testClassName, testMethodName);
+        } else if (testClassName != null) {
+            testRunner.setClassName(testClassName);
+        }
+
+        CollectingTestListener listener = new CollectingTestListener();
+        assertTrue(getDevice().runInstrumentationTestsAsUser(testRunner, userId, listener));
+
+        TestRunResult runResult = listener.getCurrentRunResults();
+        printTestResult(runResult);
+        return !runResult.hasFailedTests() && runResult.getNumTestsInState(TestStatus.PASSED) > 0;
+    }
+
+    private void printTestResult(TestRunResult runResult) {
+        for (Map.Entry<TestIdentifier, TestResult> testEntry :
+                runResult.getTestResults().entrySet()) {
+            TestResult testResult = testEntry.getValue();
+            CLog.d("Test " + testEntry.getKey() + ": " + testResult.getStatus());
+            if (testResult.getStatus() != TestStatus.PASSED) {
+                CLog.d(testResult.getStackTrace());
+            }
+        }
+    }
+}
diff --git a/hostsidetests/retaildemo/src/android/host/retaildemo/DemoModeTest.java b/hostsidetests/retaildemo/src/android/host/retaildemo/DemoModeTest.java
new file mode 100644
index 0000000..8252022
--- /dev/null
+++ b/hostsidetests/retaildemo/src/android/host/retaildemo/DemoModeTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 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 android.host.retaildemo;
+
+import static junit.framework.Assert.assertTrue;
+
+public class DemoModeTest extends BaseTestCase {
+    private static final String RETAIL_DEMO_TEST_APK = "CtsRetailDemoApp.apk";
+
+    public void testIsDemoUser_inPrimaryUser() throws Exception {
+        assertTrue(runDeviceTestsAsUser(
+                ".DemoUserTest", "testIsDemoUser_failure", getDevice().getPrimaryUserId()));
+    }
+
+    public void testIsDemoUser_inDemoUser() throws Exception {
+        final int demoUserId = createDemoUser();
+        getDevice().startUser(demoUserId);
+        installAppAsUser(RETAIL_DEMO_TEST_APK, demoUserId);
+        assertTrue(runDeviceTestsAsUser(
+                ".DemoUserTest", "testIsDemoUser_success", demoUserId));
+    }
+}