Move resetPasswordTest to pre-O DPC package

DPM.resetPassword is being deprecated in O and only DPC who targets SDK level
below O can still call it. As a result, move the CTS test to its own DPC package

Also try to clear device lockscreen password in tearDown() in case test fails.

Bug: 35417075
Test: cts-tradefed run cts-dev -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.MixedProfileOwnerTestApi25
Test: cts-tradefed run cts-dev -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.MixedDeviceOwnerTestApi25
Test: cts-tradefed run cts-dev -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.MixedManagedProfileOwnerTestApi25
Change-Id: I482f84587dc567410dd6df5e61fe94ec29dadaf5
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk
index af5293a..31e193d 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk
@@ -17,4 +17,4 @@
 include $(CLEAR_VARS)
 
 # Build the test APKs using their own makefiles
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk
new file mode 100644
index 0000000..cf8a05d
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/Android.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2017 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_PACKAGE_NAME := CtsDeviceAndProfileOwnerApp25
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, ../src)
+
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 compatibility-device-util ctstestrunner ub-uiautomator
+
+LOCAL_SDK_VERSION := test_current
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/../res
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/AndroidManifest.xml
new file mode 100644
index 0000000..a8d249c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/api25/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.deviceandprofileowner">
+
+    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="25"/>
+
+    <!-- Add a network security config that trusts user added CAs for tests -->
+    <application android:testOnly="true">
+
+        <uses-library android:name="android.test.runner" />
+        <receiver
+            android:name="com.android.cts.deviceandprofileowner.BaseDeviceAdminTest$BasicAdminReceiver"
+            android:permission="android.permission.BIND_DEVICE_ADMIN"
+            android:directBootAware="true">
+            <meta-data android:name="android.app.device_admin"
+                       android:resource="@xml/device_admin" />
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
+            </intent-filter>
+        </receiver>
+
+    </application>
+
+    <instrumentation
+            android:name="android.support.test.runner.AndroidJUnitRunner"
+            android:label="Profile and Device Owner CTS Tests"
+            android:targetPackage="com.android.cts.deviceandprofileowner">
+        <meta-data
+                android:name="listener"
+                android:value="com.android.cts.runner.CtsTestRunListener"/>
+    </instrumentation>
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java
index 17d934e..31d3bf9 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ResetPasswordTest.java
@@ -22,6 +22,9 @@
 /**
  * Test cases for {@link android.app.admin.DevicePolicyManager#resetPassword(String, int)}.
  *
+ * As of O, resetPassword is only accessible to DPCs targeting Sdk level before O, so this
+ * is exercised by CtsDeviceAndProfileOwnerApp25 only.
+ *
  * <p>These tests verify that the device password:
  * <ul>
  *     <li>can be created, changed and cleared when FBE is not locked, and
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 766b54a..b02dc8a 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -43,9 +43,6 @@
     protected static final String ADMIN_RECEIVER_TEST_CLASS
             = ".BaseDeviceAdminTest$BasicAdminReceiver";
 
-    protected static final String RESET_PASSWORD_TEST_CLASS = ".ResetPasswordTest";
-    protected static final String FBE_HELPER_CLASS = ".FbeHelper";
-
     private static final String INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
     private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
 
@@ -132,30 +129,6 @@
         executeDeviceTestClass(".CaCertManagementTest");
     }
 
-    /** Test for resetPassword for all devices. */
-    public void testResetPassword() throws Exception {
-        if (!mHasFeature) {
-            return;
-        }
-        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPassword");
-    }
-
-    /** Additional test for resetPassword for FBE-enabled devices. */
-    public void testResetPasswordFbe() throws Exception {
-        if (!mHasFeature || !mSupportsFbe) {
-            return;
-        }
-
-        // Lock FBE and verify resetPassword is disabled
-        executeDeviceTestMethod(FBE_HELPER_CLASS, "testSetPassword");
-        rebootAndWaitUntilReady();
-        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPasswordDisabled");
-
-        // Unlock FBE and verify resetPassword is enabled again
-        executeDeviceTestMethod(FBE_HELPER_CLASS, "testUnlockFbe");
-        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPassword");
-    }
-
     public void testApplicationRestrictions() throws Exception {
         if (!mHasFeature) {
             return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java
new file mode 100644
index 0000000..e4bf61c
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2017 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.devicepolicy;
+
+import android.platform.test.annotations.RequiresDevice;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Set of tests for use cases that apply to profile and device owner with DPC
+ * targeting API level 25.
+ */
+public abstract class DeviceAndProfileOwnerTestApi25 extends BaseDevicePolicyTest {
+
+    protected static final String DEVICE_ADMIN_PKG = "com.android.cts.deviceandprofileowner";
+    protected static final String DEVICE_ADMIN_APK = "CtsDeviceAndProfileOwnerApp25.apk";
+
+    private static final String TEST_APP_APK = "CtsSimpleApp.apk";
+    private static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
+
+    protected static final String ADMIN_RECEIVER_TEST_CLASS
+            = ".BaseDeviceAdminTest$BasicAdminReceiver";
+
+    protected static final String RESET_PASSWORD_TEST_CLASS = ".ResetPasswordTest";
+    protected static final String FBE_HELPER_CLASS = ".FbeHelper";
+
+    protected int mUserId;
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            getDevice().uninstallPackage(DEVICE_ADMIN_PKG);
+            getDevice().uninstallPackage(TEST_APP_PKG);
+
+            // Clear device lock in case test fails (testUnlockFbe in particular)
+            getDevice().executeShellCommand("cmd lock_settings clear --old 12345");
+            // Press the HOME key to close any alart dialog that may be shown.
+            getDevice().executeShellCommand("input keyevent 3");
+        }
+        super.tearDown();
+    }
+
+    /** Test for resetPassword for all devices. */
+    public void testResetPassword() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPassword");
+    }
+
+    /** Additional test for resetPassword for FBE-enabled devices. */
+    public void testResetPasswordFbe() throws Exception {
+        if (!mHasFeature || !mSupportsFbe) {
+            return;
+        }
+
+        // Lock FBE and verify resetPassword is disabled
+        executeDeviceTestMethod(FBE_HELPER_CLASS, "testSetPassword");
+        rebootAndWaitUntilReady();
+        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPasswordDisabled");
+
+        // Unlock FBE and verify resetPassword is enabled again
+        executeDeviceTestMethod(FBE_HELPER_CLASS, "testUnlockFbe");
+        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPassword");
+    }
+
+    protected void executeDeviceTestClass(String className) throws Exception {
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, mUserId);
+    }
+
+    protected void executeDeviceTestMethod(String className, String testName) throws Exception {
+        runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId);
+    }
+
+    /**
+     * Start SimpleActivity synchronously in a particular user.
+     */
+    protected void startSimpleActivityAsUser(int userId) throws Exception {
+        installAppAsUser(TEST_APP_APK, userId);
+        String command = "am start -W --user " + userId + " " + TEST_APP_PKG + "/"
+                + TEST_APP_PKG + ".SimpleActivity";
+        getDevice().executeShellCommand(command);
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTestApi25.java
new file mode 100644
index 0000000..32b48d6
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTestApi25.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 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.devicepolicy;
+
+import android.platform.test.annotations.RequiresDevice;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ * Set of tests for device owner use cases that also apply to profile owners.
+ * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTestApi25.
+ */
+public class MixedDeviceOwnerTestApi25 extends DeviceAndProfileOwnerTestApi25 {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        if (mHasFeature) {
+            mUserId = mPrimaryUserId;
+
+            installAppAsUser(DEVICE_ADMIN_APK, mUserId);
+            if (!setDeviceOwner(
+                    DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId,
+                    /*expectFailure*/ false)) {
+                removeAdmin(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
+                getDevice().uninstallPackage(DEVICE_ADMIN_PKG);
+                fail("Failed to set device owner");
+            }
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            assertTrue("Failed to remove device owner",
+                    removeAdmin(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId));
+        }
+        super.tearDown();
+    }
+
+    // All tests for this class are defined in DeviceAndProfileOwnerTestApi25
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
index ccc95be..a2d8057 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -78,49 +78,6 @@
         executeDeviceTestMethod(".ScreenCaptureDisabledTest", "testScreenCapturePossible");
     }
 
-    /**
-     * Verify the Profile Owner of a managed profile can create and change the password,
-     * but cannot remove it.
-     */
-    @Override
-    public void testResetPassword() throws Exception {
-        if (!mHasFeature) {
-            return;
-        }
-
-        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPasswordManagedProfile");
-    }
-
-    /**
-     *  Verify the Profile Owner of a managed profile can only change the password when FBE is
-     *  unlocked, and cannot remove the password even when FBE is unlocked.
-     */
-    @Override
-    public void testResetPasswordFbe() throws Exception {
-        if (!mHasFeature || !mSupportsFbe) {
-            return;
-        }
-
-        // Lock FBE and verify resetPassword is disabled
-        executeDeviceTestMethod(FBE_HELPER_CLASS, "testSetPassword");
-        rebootAndWaitUntilReady();
-        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPasswordDisabled");
-
-        // Start an activity in managed profile to trigger work challenge
-        startSimpleActivityAsUser(mUserId);
-
-        // Unlock FBE and verify resetPassword is enabled again
-        executeDeviceTestMethod(FBE_HELPER_CLASS, "testUnlockFbe");
-        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPasswordManagedProfile");
-    }
-
-    public void testCannotClearProfileOwner() throws Exception {
-        if (mHasFeature) {
-            runDeviceTestsAsUser(DEVICE_ADMIN_PKG, CLEAR_PROFILE_OWNER_NEGATIVE_TEST_CLASS,
-                    mUserId);
-        }
-    }
-
     @Override
     public void testDisallowSetWallpaper_allowed() throws Exception {
         // Managed profile doesn't have wallpaper.
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
new file mode 100644
index 0000000..23324a3
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 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.devicepolicy;
+
+/**
+ * Set of tests for managed profile owner use cases that also apply to device owners.
+ * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTestApi25.
+ */
+public class MixedManagedProfileOwnerTestApi25 extends DeviceAndProfileOwnerTestApi25 {
+
+    private int mParentUserId = -1;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // We need managed users to be supported in order to create a profile of the user owner.
+        mHasFeature &= hasDeviceFeature("android.software.managed_users");
+
+        if (mHasFeature) {
+            removeTestUsers();
+            mParentUserId = mPrimaryUserId;
+            createManagedProfile();
+        }
+    }
+
+    private void createManagedProfile() throws Exception {
+        mUserId = createManagedProfile(mParentUserId);
+        switchUser(mParentUserId);
+        startUser(mUserId);
+
+        installAppAsUser(DEVICE_ADMIN_APK, mUserId);
+        setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
+        startUser(mUserId);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            removeUser(mUserId);
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Verify the Profile Owner of a managed profile can create and change the password,
+     * but cannot remove it.
+     */
+    @Override
+    public void testResetPassword() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPasswordManagedProfile");
+    }
+
+    /**
+     *  Verify the Profile Owner of a managed profile can only change the password when FBE is
+     *  unlocked, and cannot remove the password even when FBE is unlocked.
+     */
+    @Override
+    public void testResetPasswordFbe() throws Exception {
+        if (!mHasFeature || !mSupportsFbe) {
+            return;
+        }
+
+        // Lock FBE and verify resetPassword is disabled
+        executeDeviceTestMethod(FBE_HELPER_CLASS, "testSetPassword");
+        rebootAndWaitUntilReady();
+        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPasswordDisabled");
+
+        // Start an activity in managed profile to trigger work challenge
+        startSimpleActivityAsUser(mUserId);
+
+        // Unlock FBE and verify resetPassword is enabled again
+        executeDeviceTestMethod(FBE_HELPER_CLASS, "testUnlockFbe");
+        executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPasswordManagedProfile");
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTestApi25.java
new file mode 100644
index 0000000..b044441
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTestApi25.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 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.devicepolicy;
+
+import android.platform.test.annotations.RequiresDevice;
+
+/**
+ * Set of tests for pure (non-managed) profile owner use cases that also apply to device owners.
+ * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTestApi25.
+ */
+public class MixedProfileOwnerTestApi25 extends DeviceAndProfileOwnerTestApi25 {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        if (mHasFeature) {
+            mUserId = mPrimaryUserId;
+
+            installAppAsUser(DEVICE_ADMIN_APK, mUserId);
+            if (!setProfileOwner(
+                    DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId,
+                    /*expectFailure*/ false)) {
+                removeAdmin(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
+                getDevice().uninstallPackage(DEVICE_ADMIN_PKG);
+                fail("Failed to set profile owner");
+            }
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            assertTrue("Failed to remove profile owner.",
+                    removeAdmin(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId));
+        }
+        super.tearDown();
+    }
+}