Add UiAutomation test for runtime permissions

Bug: 22192363
Change-Id: Idf2a9ef766cb4ce811253ba8d4aedb7cd2748377
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk b/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
index 7b3fba3..b31e74b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
@@ -26,7 +26,8 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
 
-LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner compatibility-device-util_v2
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner compatibility-device-util_v2 \
+	ub-uiautomator
 
 LOCAL_SDK_VERSION := current
 
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
index 2a54d97..49754d0 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
@@ -19,7 +19,8 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
-import android.test.AndroidTestCase;
+import android.support.test.uiautomator.UiDevice;
+import android.test.InstrumentationTestCase;
 
 /**
  * Base class for profile-owner based tests.
@@ -27,7 +28,7 @@
  * This class handles making sure that the test is the profile owner and that it has an active admin
  * registered, so that all tests may assume these are done.
  */
-public class BaseManagedProfileTest extends AndroidTestCase {
+public class BaseManagedProfileTest extends InstrumentationTestCase {
 
     public static class BasicAdminReceiver extends DeviceAdminReceiver {
     }
@@ -36,21 +37,23 @@
             BasicAdminReceiver.class.getPackage().getName(), BasicAdminReceiver.class.getName());
 
     protected DevicePolicyManager mDevicePolicyManager;
+    protected Context mContext;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        mContext = getInstrumentation().getContext();
 
-       mDevicePolicyManager = (DevicePolicyManager)
-               mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-       assertNotNull(mDevicePolicyManager);
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        assertNotNull(mDevicePolicyManager);
 
-       // TODO: Only check the below if we are running as the profile user. If running under the
-       // user owner, can we check that there is a profile and that the below holds for it? If we
-       // don't want to do these checks every time we could get rid of this class altogether and
-       // just have a single test case running under the profile user that do them.
-       assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
-       assertTrue(mDevicePolicyManager.isProfileOwnerApp(
-               ADMIN_RECEIVER_COMPONENT.getPackageName()));
+        // TODO: Only check the below if we are running as the profile user. If running under the
+        // user owner, can we check that there is a profile and that the below holds for it? If we
+        // don't want to do these checks every time we could get rid of this class altogether and
+        // just have a single test case running under the profile user that do them.
+        assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
+        assertTrue(mDevicePolicyManager.isProfileOwnerApp(
+                ADMIN_RECEIVER_COMPONENT.getPackageName()));
     }
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PermissionsTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PermissionsTest.java
index 727b47f..369017c 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PermissionsTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PermissionsTest.java
@@ -23,6 +23,12 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.os.UserManager;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiWatcher;
+import android.support.test.uiautomator.Until;
 import android.util.Log;
 
 import java.util.concurrent.ArrayBlockingQueue;
@@ -54,9 +60,18 @@
     private static final String EXTRA_GRANT_STATE
             = "com.android.cts.permission.extra.GRANT_STATE";
     private static final int PERMISSION_ERROR = -2;
+    private static final BySelector CRASH_POPUP_BUTTON_SELECTOR = By
+            .clazz(android.widget.Button.class.getName())
+            .text("OK")
+            .pkg("android");
+    private static final BySelector CRASH_POPUP_TEXT_SELECTOR = By
+            .clazz(android.widget.TextView.class.getName())
+            .pkg("android");
+    private static final String CRASH_WATCHER_ID = "CRASH";
 
     private PermissionBroadcastReceiver mReceiver;
     private PackageManager mPackageManager;
+    private UiDevice mDevice;
 
     @Override
     protected void setUp() throws Exception {
@@ -69,11 +84,13 @@
         mReceiver = new PermissionBroadcastReceiver();
         mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PERMISSION_RESULT));
         mPackageManager = mContext.getPackageManager();
+        mDevice = UiDevice.getInstance(getInstrumentation());
     }
 
     @Override
     protected void tearDown() throws Exception {
         mContext.unregisterReceiver(mReceiver);
+        mDevice.removeWatcher(CRASH_WATCHER_ID);
         super.tearDown();
     }
 
@@ -144,6 +161,28 @@
         assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
     }
 
+    public void testPermissionPrompts() throws Exception {
+        // register a crash watcher
+        mDevice.registerWatcher(CRASH_WATCHER_ID, new UiWatcher() {
+            @Override
+            public boolean checkForCondition() {
+                UiObject2 button = mDevice.findObject(CRASH_POPUP_BUTTON_SELECTOR);
+                if (button != null) {
+                    UiObject2 text = mDevice.findObject(CRASH_POPUP_TEXT_SELECTOR);
+                    Log.d(TAG, "Removing an error dialog: " + text != null ? text.getText() : null);
+                    button.click();
+                    return true;
+                }
+                return false;
+            }
+        });
+        mDevice.runWatchers();
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED, "permission_deny_button");
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED, "permission_allow_button");
+    }
+
     public void testPermissionUpdate_setDeniedState() throws Exception {
         assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
                 PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
@@ -192,6 +231,10 @@
     }
 
     private void assertPermissionRequest(int expected) throws Exception {
+        assertPermissionRequest(expected, null);
+    }
+
+    private void assertPermissionRequest(int expected, String buttonResource) throws Exception {
         Intent launchIntent = new Intent();
         launchIntent.setComponent(new ComponentName(PERMISSION_APP_PACKAGE_NAME,
                 PERMISSIONS_ACTIVITY_NAME));
@@ -199,6 +242,7 @@
         launchIntent.setAction(ACTION_REQUEST_PERMISSION);
         launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContext.startActivity(launchIntent);
+        pressPermissionPromptButton(buttonResource);
         assertEquals(expected, mReceiver.waitForBroadcast());
         assertEquals(expected, mPackageManager.checkPermission(PERMISSION_NAME,
                 PERMISSION_APP_PACKAGE_NAME));
@@ -246,6 +290,20 @@
                 PackageManager.PERMISSION_GRANTED);
     }
 
+    private void pressPermissionPromptButton(String resName) throws Exception {
+        if (resName == null) {
+            return;
+        }
+
+        BySelector selector = By
+                .clazz(android.widget.Button.class.getName())
+                .res("com.android.packageinstaller", resName);
+        mDevice.wait(Until.hasObject(selector), 5000);
+        UiObject2 button = mDevice.findObject(selector);
+        assertNotNull("Couldn't find button with resource id: " + resName, button);
+        button.click();
+    }
+
     private class PermissionBroadcastReceiver extends BroadcastReceiver {
         private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer> (1);
 
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
index 76a9e44..9646e61 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
@@ -64,11 +64,4 @@
         // Verify the profile is deleted
         assertFalse(mUserManager.getUserProfiles().contains(currentUser));
     }
-
-    // Override this test inherited from base class, as it will trigger another round of setUp()
-    // which would fail because the managed profile has been removed by this test.
-    @Override
-    @Ignore
-    public void testAndroidTestCaseSetupProperly() {
-    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 50987ef..34d342d 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -532,6 +532,22 @@
                 "testPermissionMixedPolicies", mUserId));
     }
 
+    public void testPermissionPrompts() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        try {
+            // unlock device and ensure that the screen stays on
+            getDevice().executeShellCommand("input keyevent 82");
+            getDevice().executeShellCommand("settings put global stay_on_while_plugged_in 2");
+            installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".PermissionsTest",
+                    "testPermissionPrompts", mUserId));
+        } finally {
+            getDevice().executeShellCommand("settings put global stay_on_while_plugged_in 0");
+        }
+    }
+
     public void testPermissionAppUpdate() throws Exception {
         if (!mHasFeature) {
             return;