Add CTSVerifier tests for checking permission grant states.

- Tests are added to check if permission is locked down in settings
depending on the state set by the device or profile owner.
- Moving CtsPermissionApp from cts/hostsidetests/devicepolicy/app
to cts/apps and using that for setting permission grant states.

Bug: 22192211

Change-Id: I0b9119f427f52a1122b738ce96a954bd74e880b2
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 48a8318..5ddfcb2 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -64,12 +64,14 @@
 
 
 notification-bot := $(call intermediates-dir-for,APPS,NotificationBot)/package.apk
+permission-app := $(call intermediates-dir-for,APPS,CtsPermissionApp)/package.apk
 
 # Builds and launches CTS Verifier on a device.
 .PHONY: cts-verifier
-cts-verifier: CtsVerifier adb NotificationBot
+cts-verifier: CtsVerifier adb NotificationBot CtsPermissionApp
 	adb install -r $(PRODUCT_OUT)/data/app/CtsVerifier/CtsVerifier.apk \
 		&& adb install -r $(notification-bot) \
+		&& adb install -r $(permission-app) \
 		&& adb shell "am start -n com.android.cts.verifier/.CtsVerifierActivity"
 
 #
@@ -106,10 +108,12 @@
 endif
 $(verifier-zip) : $(HOST_OUT)/CameraITS
 $(verifier-zip) : $(notification-bot)
+$(verifier-zip) : $(permission-app)
 $(verifier-zip) : $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk | $(ACP)
 		$(hide) mkdir -p $(verifier-dir)
 		$(hide) $(ACP) -fp $< $(verifier-dir)/CtsVerifier.apk
 		$(ACP) -fp $(notification-bot) $(verifier-dir)/NotificationBot.apk
+		$(ACP) -fp $(permission-app) $(verifier-dir)/CtsPermissionApp.apk
 ifeq ($(HOST_OS),linux)
 		$(hide) $(ACP) -fp $(HOST_OUT)/bin/cts-usb-accessory $(verifier-dir)/cts-usb-accessory
 endif
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 39302c1..47eb16f 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1375,6 +1375,23 @@
                 android:label="@string/device_owner_wifi_lockdown_test">
         </activity>
 
+        <activity android:name=".managedprovisioning.PermissionLockdownTestActivity"
+                android:label="@string/device_profile_owner_permission_lockdown_test">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_PERMISSION_LOCKDOWN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity-alias
+                android:name=".managedprovisioning.ManagedProfilePermissionLockdownTestActivity"
+                android:targetActivity=".managedprovisioning.PermissionLockdownTestActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity-alias>
+
         <activity android:name=".managedprovisioning.ByodFlowTestActivity"
                 android:launchMode="singleTask"
                 android:label="@string/provisioning_byod">
diff --git a/apps/CtsVerifier/res/layout/permission_lockdown.xml b/apps/CtsVerifier/res/layout/permission_lockdown.xml
new file mode 100644
index 0000000..ea295dd
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/permission_lockdown.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/permission_lockdown_activity"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:paddingTop="4dp">
+        <TextView
+                android:id="@+id/test_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/device_profile_owner_permission_lockdown_test_instructions"
+                android:textSize="18sp"
+                android:padding="10dp" />
+    </ScrollView>
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1">
+        <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center_vertical"
+                android:paddingStart="10dp"
+                android:paddingEnd="10dp">
+
+            <LinearLayout
+                    android:orientation="horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingTop="4dp">
+                <ImageView
+                        android:id="@+id/package_icon"
+                        android:layout_width="48dp"
+                        android:layout_height="48dp"
+                        android:scaleType="centerInside"
+                        android:gravity="center" />
+                <TextView
+                        android:id="@+id/package_name"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:gravity="center_vertical"
+                        android:paddingLeft="10dp"
+                        android:textSize="16sp"
+                        android:singleLine="true"
+                        android:ellipsize="end" />
+            </LinearLayout>
+
+            <TextView
+                    android:id="@+id/permission_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textSize="16sp"
+                    android:paddingTop="4dp" />
+
+            <RadioGroup
+                    android:id="@+id/permission_group"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    android:paddingTop="4dp">
+                <RadioButton
+                        android:id="@+id/permission_allow"
+                        android:text="@string/permission_allow"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content" />
+                <RadioButton
+                        android:id="@+id/permission_default"
+                        android:text="@string/permission_default"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content" />
+                <RadioButton
+                        android:id="@+id/permission_deny"
+                        android:text="@string/permission_deny"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content" />
+            </RadioGroup>
+
+            <Button
+                    android:id="@+id/open_settings"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:text="@string/open_settings_button_label"
+                    android:onClick="openSettings" />
+        </LinearLayout>
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 3a3f231..91a62ba 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1664,6 +1664,33 @@
     </string>
     <string name="device_owner_disable_keyguard_button">Disable keyguard</string>
     <string name="device_owner_reenable_keyguard_button">Reenable keyguard</string>
+    <string name="device_profile_owner_permission_lockdown_test">Permissions lockdown</string>
+    <string name="device_profile_owner_permission_lockdown_test_instructions">
+            Select each of the three grant states for the permission shown below in turn.\n
+            Now open application settings, select Permissions, and verify if the following behaviour is observed.\n
+            <b>Allow:</b> Permission is granted to the app and cannot be changed through the settings UI.\n
+            <b>Let user decide:</b> Permission state can be changed through the settings UI.\n
+            <b>Deny:</b> Permission is denied to the app and cannot be changed through the settings UI.\n
+            Please mark the test accordingly.
+    </string>
+    <string name="device_owner_permission_lockdown_test_info">
+        This test checks if the permissions state in settings UI is locked down according to the state set by the device owner.
+    </string>
+    <string name="profile_owner_permission_lockdown_test_info">
+        <b>
+        Before proceeding, check if com.android.cts.permissionapp (aka CtsPermissionApp) is installed in work profile by going to Settings &gt; Apps. If not, please install the app before proceeding.\n\n
+        </b>
+        This test checks if the permissions state in settings UI is locked down correctly depending on the state set by the profile owner.
+    </string>
+    <string name="package_not_found">You must install %s (aka CtsPermissionApp).</string>
+    <string name="permission_allow">Grant</string>
+    <string name="permission_default">Let user decide</string>
+    <string name="permission_deny">Deny</string>
+    <string name="not_profile_owner">%s is not profile owner.</string>
+    <string name="not_device_owner">%s is not device owner.</string>
+    <string name="activity_not_found">No activity found to handle intent: %s</string>
+    <string name="open_settings_button_label">Open Application Settings</string>
+    <string name="finish_button_label">Finish</string>
 
     <!-- Strings for JobScheduler Tests -->
     <string name="js_test_description">This test is mostly automated, but requires some user interaction. You can pass this test once the list items below are checked.</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index 6206ea0..a463937 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -69,6 +69,7 @@
     private DialogTestListItem mCredSettingsVisibleTest;
     private DialogTestListItem mPrintSettingsVisibleTest;
     private DialogTestListItem mIntentFiltersTest;
+    private DialogTestListItem mPermissionLockdownTest;
     private DialogTestListItem mCrossProfileImageCaptureSupportTest;
     private DialogTestListItem mCrossProfileVideoCaptureSupportTest;
     private DialogTestListItem mCrossProfileAudioCaptureSupportTest;
@@ -264,6 +265,14 @@
                 checkIntentFilters();
             }
         };
+        
+        Intent permissionCheckIntent = new Intent(
+                PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
+        mPermissionLockdownTest = new DialogTestListItem(this,
+                R.string.device_profile_owner_permission_lockdown_test,
+                "BYOD_PermissionLockdownTest",
+                R.string.profile_owner_permission_lockdown_test_info,
+                permissionCheckIntent);
 
         adapter.add(mProfileOwnerInstalled);
 
@@ -285,6 +294,7 @@
         adapter.add(mDisableNonMarketTest);
         adapter.add(mEnableNonMarketTest);
         adapter.add(mIntentFiltersTest);
+        adapter.add(mPermissionLockdownTest);
 
         if (canResolveIntent(ByodHelperActivity.getCaptureImageIntent())) {
             // Capture image intent can be resolved in primary profile, so test.
@@ -424,17 +434,16 @@
     private void disableComponent() {
         // Disable app components in the current profile, so only the counterpart in the other profile
         // can respond (via cross-profile intent filter)
-        getPackageManager().setComponentEnabledSetting(new ComponentName(
-                this, ByodHelperActivity.class),
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
-        getPackageManager().setComponentEnabledSetting(new ComponentName(
-                this, WorkNotificationTestActivity.class),
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
-        getPackageManager().setComponentEnabledSetting(new ComponentName(
-                this, WorkStatusTestActivity.class),
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
+        final String[] components = {
+            ByodHelperActivity.class.getName(),
+            WorkNotificationTestActivity.class.getName(),
+            WorkStatusTestActivity.class.getName(),
+            PermissionLockdownTestActivity.ACTIVITY_ALIAS
+        };
+        for (String component : components) {
+            getPackageManager().setComponentEnabledSetting(new ComponentName(this, component),
+                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                    PackageManager.DONT_KILL_APP);
+        }
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index ef5d62d..4987f86 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -66,6 +66,8 @@
             filter.addAction(WorkNotificationTestActivity.ACTION_CLEAR_WORK_NOTIFICATION);
             filter.addAction(WorkStatusTestActivity.ACTION_WORK_STATUS_TOAST);
             filter.addAction(WorkStatusTestActivity.ACTION_WORK_STATUS_ICON);
+            filter.addAction(
+                    PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
                     DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 1a5e73c..e6bbdee 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -62,12 +62,15 @@
     static final String COMMAND_SET_GLOBAL_SETTING = "set-global-setting";
     static final String COMMAND_SET_STATUSBAR_DISABLED = "set-statusbar-disabled";
     static final String COMMAND_SET_KEYGUARD_DISABLED = "set-keyguard-disabled";
+    static final String COMMAND_CHECK_PERMISSION_LOCKDOWN = "check-permission-lockdown";
     static final String EXTRA_SETTING = "extra-setting";
 
     private static final String CHECK_DEVICE_OWNER_TEST_ID = "CHECK_DEVICE_OWNER";
     private static final String WIFI_LOCKDOWN_TEST_ID = WifiLockdownTestActivity.class.getName();
     private static final String DISABLE_STATUS_BAR_TEST_ID = "DISABLE_STATUS_BAR";
     private static final String DISABLE_KEYGUARD_TEST_ID = "DISABLE_KEYGUARD";
+    private static final String CHECK_PERMISSION_LOCKDOWN_TEST_ID =
+            PermissionLockdownTestActivity.class.getName();
     private static final String REMOVE_DEVICE_OWNER_TEST_ID = "REMOVE_DEVICE_OWNER";
 
     @Override
@@ -164,6 +167,11 @@
                                 createDeviceOwnerIntentWithBooleanParameter(
                                         COMMAND_SET_KEYGUARD_DISABLED, false))}));
 
+        // setPermissionGrantState
+        adapter.add(createTestItem(this, CHECK_PERMISSION_LOCKDOWN_TEST_ID,
+                R.string.device_profile_owner_permission_lockdown_test,
+                new Intent(PermissionLockdownTestActivity.ACTION_CHECK_PERMISSION_LOCKDOWN)));
+
         // removeDeviceOwner
         adapter.add(createInteractiveTestItem(this, REMOVE_DEVICE_OWNER_TEST_ID,
                 R.string.device_owner_remove_device_owner_test,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java
new file mode 100644
index 0000000..ea7e801
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2015 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.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+public class PermissionLockdownTestActivity extends PassFailButtons.Activity
+        implements RadioGroup.OnCheckedChangeListener {
+    private static final String PERMISSION_APP_PACKAGE = "com.android.cts.permissionapp";
+
+    // Alias used for starting the activity from ByodFlowTestActivity (Managed profile tests).
+    static final String ACTIVITY_ALIAS
+            = "com.android.cts.verifier.managedprovisioning" +
+                    ".ManagedProfilePermissionLockdownTestActivity";
+
+    private static final String MANAGED_PROVISIONING_ACTION_PREFIX
+            = "com.android.cts.verifier.managedprovisioning.action.";
+    // Indicates that activity is started for device owner case.
+    static final String ACTION_CHECK_PERMISSION_LOCKDOWN
+            = MANAGED_PROVISIONING_ACTION_PREFIX + "CHECK_PERMISSION_LOCKDOWN";
+    // Indicates that activity is started for profile owner case.
+    static final String ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN
+            = MANAGED_PROVISIONING_ACTION_PREFIX + "MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN";
+
+    // Permission grant states will be set on this permission.
+    private static final String CONTACTS_PERMISSION = android.Manifest.permission.READ_CONTACTS;
+
+    private boolean mDeviceOwnerTest;
+    private DevicePolicyManager mDevicePolicyManager;
+    private ComponentName mAdmin;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.permission_lockdown);
+
+        mDevicePolicyManager =
+                (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mAdmin = DeviceAdminTestReceiver.getReceiverComponentName();
+
+        mDeviceOwnerTest =
+                ACTION_CHECK_PERMISSION_LOCKDOWN.equals(getIntent().getAction()) ? true : false;
+        // Return immediately if we are neither profile nor device owner.
+        if (!isProfileOrDeviceOwner()) {
+            setTestResultAndFinish(false);
+            return;
+        }
+
+        buildLayout();
+    }
+
+    private void buildLayout() {
+        PackageManager packageManager = getPackageManager();
+        ApplicationInfo applicationInfo = null;
+        try {
+            // We need to make sure that the CtsPermissionApp is installed on the device or
+            // work profile.
+            applicationInfo = packageManager.getApplicationInfo(
+                    PERMISSION_APP_PACKAGE, 0 /* flags */);
+        } catch (PackageManager.NameNotFoundException e) {
+            showToast(getString(R.string.package_not_found, PERMISSION_APP_PACKAGE));
+            setTestResultAndFinish(false);
+            return;
+        }
+
+        ImageView packageIconImageView = (ImageView) findViewById(R.id.package_icon);
+        packageIconImageView.setImageDrawable(packageManager.getApplicationIcon(applicationInfo));
+        TextView packageNameTextView = (TextView) findViewById(R.id.package_name);
+        packageNameTextView.setText(packageManager.getApplicationLabel(applicationInfo));
+
+        TextView permissionNameTextView = (TextView) findViewById(R.id.permission_name);
+        permissionNameTextView.setText(CONTACTS_PERMISSION);
+
+        // Get the current permission grant state for initializing the RadioGroup.
+        int currentPermissionState = mDevicePolicyManager.getPermissionGrantState(mAdmin,
+                    PERMISSION_APP_PACKAGE, CONTACTS_PERMISSION);
+        RadioGroup permissionRadioGroup = (RadioGroup) findViewById(R.id.permission_group);
+        switch (currentPermissionState) {
+            case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: {
+                permissionRadioGroup.check(R.id.permission_allow);
+            } break;
+            case DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT: {
+                permissionRadioGroup.check(R.id.permission_default);
+            } break;
+            case  DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED: {
+                permissionRadioGroup.check(R.id.permission_deny);
+            } break;
+        }
+        permissionRadioGroup.setOnCheckedChangeListener(this);
+
+        addFinishOrPassFailButtons();
+    }
+
+    private void addFinishOrPassFailButtons() {
+        // In case of device owner, we include the pass-fail buttons where as in case of profile
+        // owner, we add a finish button.
+        ViewGroup parentView = (ViewGroup) findViewById(R.id.permission_lockdown_activity);
+        if (mDeviceOwnerTest) {
+            parentView.addView(
+                    getLayoutInflater().inflate(R.layout.pass_fail_buttons, parentView, false));
+            setInfoResources(R.string.device_profile_owner_permission_lockdown_test,
+                    R.string.device_owner_permission_lockdown_test_info, 0);
+            setPassFailButtonClickListeners();
+        } else {
+            Button finishButton = new Button(this);
+            finishButton.setText(R.string.finish_button_label);
+            finishButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    PermissionLockdownTestActivity.this.setTestResultAndFinish(false);
+                }
+            });
+            parentView.addView(finishButton);
+        }
+    }
+
+    // Dispatches an intent to open the Settings screen for CtsPermissionApp.
+    public void openSettings(View v) {
+        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+                .setData(Uri.fromParts("package", PERMISSION_APP_PACKAGE, null))
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            showToast(getString(R.string.activity_not_found, intent));
+        }
+    }
+
+    @Override
+    public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
+        int permissionGrantState = -1;
+        switch (checkedId) {
+            case R.id.permission_allow: {
+                permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED;
+            } break;
+            case R.id.permission_default: {
+                permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
+            } break;
+            case R.id.permission_deny: {
+                permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
+            } break;
+        }
+        mDevicePolicyManager.setPermissionGrantState(mAdmin, PERMISSION_APP_PACKAGE,
+                CONTACTS_PERMISSION, permissionGrantState);
+    }
+
+    private boolean isProfileOrDeviceOwner() {
+        String adminPackage = mAdmin.getPackageName();
+        if (mDeviceOwnerTest && !mDevicePolicyManager.isDeviceOwnerApp(adminPackage)) {
+            showToast(getString(R.string.not_device_owner, adminPackage));
+            return false;
+        } else if (!mDeviceOwnerTest && !mDevicePolicyManager.isProfileOwnerApp(adminPackage)) {
+            showToast(getString(R.string.not_profile_owner, adminPackage));
+            return false;
+        }
+        return true;
+    }
+
+    private void showToast(String toast) {
+        Toast.makeText(this, toast, Toast.LENGTH_LONG).show();
+    }
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/PermissionApp/Android.mk b/apps/PermissionApp/Android.mk
similarity index 100%
rename from hostsidetests/devicepolicy/app/PermissionApp/Android.mk
rename to apps/PermissionApp/Android.mk
diff --git a/hostsidetests/devicepolicy/app/PermissionApp/AndroidManifest.xml b/apps/PermissionApp/AndroidManifest.xml
similarity index 89%
rename from hostsidetests/devicepolicy/app/PermissionApp/AndroidManifest.xml
rename to apps/PermissionApp/AndroidManifest.xml
index 0a0df60..ea98410 100644
--- a/hostsidetests/devicepolicy/app/PermissionApp/AndroidManifest.xml
+++ b/apps/PermissionApp/AndroidManifest.xml
@@ -16,13 +16,14 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.cts.permission.permissionapp">
+    package="com.android.cts.permissionapp">
 
     <uses-sdk android:minSdkVersion="MNC"/>
 
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
 
-    <application>
+    <application android:label="CtsPermissionApp"
+            android:icon="@drawable/ic_permissionapp">
         <activity android:name=".PermissionActivity" >
             <intent-filter>
                 <action android:name="com.android.cts.permission.action.CHECK_HAS_PERMISSION" />
diff --git a/apps/PermissionApp/res/drawable-hdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-hdpi/ic_permissionapp.png
new file mode 100644
index 0000000..6fe4112
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-hdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/res/drawable-mdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-mdpi/ic_permissionapp.png
new file mode 100644
index 0000000..a7a5666
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-mdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/res/drawable-xhdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-xhdpi/ic_permissionapp.png
new file mode 100644
index 0000000..1e47732
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-xhdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/res/drawable-xxhdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-xxhdpi/ic_permissionapp.png
new file mode 100644
index 0000000..0e849b3
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-xxhdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/res/drawable-xxxhdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-xxxhdpi/ic_permissionapp.png
new file mode 100644
index 0000000..242a6b1
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-xxxhdpi/ic_permissionapp.png
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.java b/apps/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.java
similarity index 98%
rename from hostsidetests/devicepolicy/app/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.java
rename to apps/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.java
index fc45635..01b60d3 100644
--- a/hostsidetests/devicepolicy/app/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.java
+++ b/apps/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.cts.permission.permissionapp;
+package com.android.cts.permissionapp;
 
 import android.app.Activity;
 import android.content.Intent;
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
index 8b3a975..d181ad5 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
@@ -42,7 +42,7 @@
     private static final String TAG = "PermissionsTest";
 
     private static final String PERMISSION_APP_PACKAGE_NAME
-            = "com.android.cts.permission.permissionapp";
+            = "com.android.cts.permissionapp";
     private static final String SIMPLE_PRE_M_APP_PACKAGE_NAME =
             "com.android.cts.launcherapps.simplepremapp";
     private static final String PERMISSION_NAME = "android.permission.READ_CONTACTS";
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 02f42ba..0cbe36c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -34,7 +34,7 @@
     protected static final String ADMIN_RECEIVER_TEST_CLASS
             = ".BaseDeviceAdminTest$BasicAdminReceiver";
 
-    private static final String PERMISSIONS_APP_PKG = "com.android.cts.permission.permissionapp";
+    private static final String PERMISSIONS_APP_PKG = "com.android.cts.permissionapp";
     private static final String PERMISSIONS_APP_APK = "CtsPermissionApp.apk";
 
     private static final String SIMPLE_PRE_M_APP_PKG = "com.android.cts.launcherapps.simplepremapp";