Add Keyguard disabled features CTS and CTSVerifier tests

CTS tests for Device Admin. CTSVerifier tests for BYOD (Profile owner) case.

Bug: 21512534
Change-Id: Ibe90318c099f061e8c9f15ae57ed1df2bac1170c
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 47eb16f..a859c2f 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1369,7 +1369,12 @@
                 android:theme="@android:style/Theme.NoDisplay"
                 android:noHistory="true"
                 android:autoRemoveFromRecents="true"
-                android:stateNotNeeded="true"/>
+                android:stateNotNeeded="true">
+        </activity>
+
+        <activity android:name=".managedprovisioning.KeyguardDisabledFeaturesActivity"
+                android:label="@string/provisioning_byod_keyguard_disabled_features">
+        </activity>
 
         <activity android:name=".managedprovisioning.WifiLockdownTestActivity"
                 android:label="@string/device_owner_wifi_lockdown_test">
@@ -1416,6 +1421,8 @@
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_IMAGE" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_VIDEO" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_AUDIO" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_KEYGUARD_DISABLED_FEATURES" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_LOCKNOW" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
         </activity>
@@ -1455,6 +1462,7 @@
         <activity android:name=".managedprovisioning.WorkNotificationTestActivity">
             <intent-filter>
                 <action android:name="com.android.cts.verifier.managedprovisioning.WORK_NOTIFICATION" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.LOCKSCREEN_NOTIFICATION" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.CLEAR_WORK_NOTIFICATION" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 91a62ba..55fdc44 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1449,6 +1449,42 @@
         \n
         Verify that you are prompted with the above choices and both options work as intended. Then mark this test accordingly.
     </string>
+    <string name="provisioning_byod_keyguard_disabled_features">Keyguard disabled features</string>
+    <string name="provisioning_byod_keyguard_disabled_features_info">
+        This test exercises Keyguard Disabled Features. Follow instructions above.
+    </string>
+    <string name="provisioning_byod_keyguard_disabled_features_instruction">
+        Please press the \"Prepare test\" button to disable trust agents.\n
+        Then please press through the following verification steps.\n
+        Note: Device password will be set to \"testpassword\". After leaving the screen device password be cleared.
+    </string>
+    <string name="provisioning_byod_keyguard_disabled_features_prepare_button">Prepare test</string>
+    <string name="provisioning_byod_disable_trust_agents">Disable trust agents</string>
+    <string name="provisioning_byod_disable_trust_agents_instruction">
+        Please press the Go button to go to Settings > Security. Then go to Trusted agents and\n
+        check if the agents are shown as disabled by the administrator.
+        Then please press Back and mark the test as \"Pass\" or \"Fail\".
+    </string>
+    <string name="provisioning_byod_fingerprint_disabled_in_settings">Fingerprint is disabled in Settings</string>
+    <string name="provisioning_byod_fingerprint_disabled_in_settings_instruction">
+        Please press the Go button to go to Settings > Security. Then go to Fingerprint and\n
+        check if the screen is shown as disabled by the administrator.
+        Then please press Back and mark the test as \"Pass\" or \"Fail\".
+    </string>
+    <string name="provisioning_byod_disable_fingerprint">Fingerprint disabled on keyguard</string>
+    <string name="provisioning_byod_disable_fingerprint_instruction">
+        Please press the Go button to lock the screen. Then try to log in using the fingerprint reader.\n
+        Expected result is you cannot log in using your fingerprint.\n
+        After you log back in, please navigate back to CtsVerifier and mark the test as \"Pass\" or \"Fail\".
+    </string>
+    <string name="provisioning_byod_disable_notifications">Notifications disabled on keyguard</string>
+    <string name="provisioning_byod_disable_notifications_instruction">
+        Please press the Go button to lock the screen. Wait a couple of seconds and look out for a
+        notification from CtsVerifier.\n
+        Expected result is the notification is shown as \"Contents hidden\", you can not see the contents
+        (Which would read \"This is a work notification\").\n
+        After you log back in, please navigate back to CtsVerifier and mark the test as \"Pass\" or \"Fail\".
+    </string>
     <string name="provisioning_byod_work_notification">Work notification is badged</string>
     <string name="provisioning_byod_work_notification_instruction">
         Please press the Go button to trigger a notification.\n
diff --git a/apps/CtsVerifier/res/xml/device_admin_byod.xml b/apps/CtsVerifier/res/xml/device_admin_byod.xml
index 61238aa..ce44794 100644
--- a/apps/CtsVerifier/res/xml/device_admin_byod.xml
+++ b/apps/CtsVerifier/res/xml/device_admin_byod.xml
@@ -20,6 +20,8 @@
         <encrypted-storage />
         <wipe-data />
         <reset-password />
+        <disable-keyguard-features />
+        <force-lock />
     </uses-policies>
 </device-admin>
 <!-- END_INCLUDE(meta_data) -->
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 a463937..bee1241 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -32,6 +32,7 @@
 import com.android.cts.verifier.DialogTestListActivity;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.TestListActivity;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
 import com.android.cts.verifier.TestResult;
 
 /**
@@ -73,6 +74,7 @@
     private DialogTestListItem mCrossProfileImageCaptureSupportTest;
     private DialogTestListItem mCrossProfileVideoCaptureSupportTest;
     private DialogTestListItem mCrossProfileAudioCaptureSupportTest;
+    private TestListItem mKeyguardDisabledFeaturesTest;
 
     public ByodFlowTestActivity() {
         super(R.layout.provisioning_byod,
@@ -256,6 +258,11 @@
                 R.string.provisioning_byod_cross_profile_instruction,
                 chooser);
 
+        mKeyguardDisabledFeaturesTest = TestListItem.newTest(this,
+                R.string.provisioning_byod_keyguard_disabled_features,
+                KeyguardDisabledFeaturesActivity.class.getName(),
+                new Intent(this, KeyguardDisabledFeaturesActivity.class), null);
+
         // Test for checking if the required intent filters are set during managed provisioning.
         mIntentFiltersTest = new DialogTestListItem(this,
                 R.string.provisioning_byod_cross_profile_intent_filters,
@@ -295,6 +302,7 @@
         adapter.add(mEnableNonMarketTest);
         adapter.add(mIntentFiltersTest);
         adapter.add(mPermissionLockdownTest);
+        adapter.add(mKeyguardDisabledFeaturesTest);
 
         if (canResolveIntent(ByodHelperActivity.getCaptureImageIntent())) {
             // Capture image intent can be resolved in primary profile, so test.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index 4d1a92a..09e6393 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -67,8 +67,13 @@
     public static final String ACTION_CAPTURE_AND_CHECK_VIDEO = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_VIDEO";
     // Primage -> managed intent: request to capture and check an audio recording
     public static final String ACTION_CAPTURE_AND_CHECK_AUDIO = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_AUDIO";
+    public static final String ACTION_KEYGUARD_DISABLED_FEATURES =
+            "com.android.cts.verifier.managedprovisioning.BYOD_KEYGUARD_DISABLED_FEATURES";
+    public static final String ACTION_LOCKNOW =
+            "com.android.cts.verifier.managedprovisioning.BYOD_LOCKNOW";
 
     public static final String EXTRA_PROVISIONED = "extra_provisioned";
+    public static final String EXTRA_PARAMETER_1 = "extra_parameter_1";
 
     // Primary -> managed intent: set unknown sources restriction and install package
     public static final String ACTION_INSTALL_APK = "com.android.cts.verifier.managedprovisioning.BYOD_INSTALL_APK";
@@ -187,6 +192,14 @@
                 finish();
             }
             return;
+        } else if (ACTION_KEYGUARD_DISABLED_FEATURES.equals(action)) {
+            final int value = intent.getIntExtra(EXTRA_PARAMETER_1,
+                    DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE);
+            ComponentName admin = DeviceAdminTestReceiver.getReceiverComponentName();
+            mDevicePolicyManager.setKeyguardDisabledFeatures(admin, value);
+        } else if (ACTION_LOCKNOW.equals(action)) {
+            mDevicePolicyManager.lockNow();
+            setResult(RESULT_OK);
         }
         // This activity has no UI and is only used to respond to CtsVerifier in the primary side.
         finish();
@@ -267,6 +280,10 @@
         return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
     }
 
+    public static Intent createLockIntent() {
+        return new Intent(ACTION_LOCKNOW);
+    }
+
     private Uri getTempUri(String fileName) {
         final File file = new File(getFilesDir() + File.separator + "images"
                 + File.separator + fileName);
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 4987f86..b18e816 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -61,8 +61,11 @@
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE);
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_VIDEO);
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_AUDIO);
+            filter.addAction(ByodHelperActivity.ACTION_KEYGUARD_DISABLED_FEATURES);
+            filter.addAction(ByodHelperActivity.ACTION_LOCKNOW);
             filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE);
             filter.addAction(WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION);
+            filter.addAction(WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION_ON_LOCKSCREEN);
             filter.addAction(WorkNotificationTestActivity.ACTION_CLEAR_WORK_NOTIFICATION);
             filter.addAction(WorkStatusTestActivity.ACTION_WORK_STATUS_TOAST);
             filter.addAction(WorkStatusTestActivity.ACTION_WORK_STATUS_ICON);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
new file mode 100644
index 0000000..0fdc498
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
@@ -0,0 +1,123 @@
+/*
+ * 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.Context;
+import android.content.Intent;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.DialogTestListActivity;
+import com.android.cts.verifier.R;
+
+public class KeyguardDisabledFeaturesActivity extends DialogTestListActivity {
+
+    public KeyguardDisabledFeaturesActivity() {
+        super(R.layout.provisioning_byod,
+                R.string.provisioning_byod_keyguard_disabled_features,
+                R.string.provisioning_byod_keyguard_disabled_features_info,
+                R.string.provisioning_byod_keyguard_disabled_features_instruction);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mPrepareTestButton.setText(
+                R.string.provisioning_byod_keyguard_disabled_features_prepare_button);
+        mPrepareTestButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    resetPassword("testpassword");
+                    setKeyguardDisabledFeatures(DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS |
+                            DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT |
+                            DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+                }
+            });
+    }
+
+    @Override
+    public void finish() {
+        // Pass and fail buttons are known to call finish() when clicked, and this is when we want to
+        // clear the password.
+        resetPassword(null);
+        super.finish();
+    }
+
+    private void setKeyguardDisabledFeatures(final int flags) {
+        Intent setKeyguardDisabledFeaturesIntent =
+                new Intent(ByodHelperActivity.ACTION_KEYGUARD_DISABLED_FEATURES)
+                .putExtra(ByodHelperActivity.EXTRA_PARAMETER_1, flags);
+        startActivity(setKeyguardDisabledFeaturesIntent);
+    }
+
+    /**
+     * Reset device password
+     * @param password password to reset to (may be null)
+     */
+    private void resetPassword(String password) {
+        DevicePolicyManager dpm = (DevicePolicyManager)
+                getSystemService(Context.DEVICE_POLICY_SERVICE);
+        dpm.resetPassword(password, 0);
+    }
+
+    @Override
+    protected void setupTests(ArrayTestListAdapter adapter) {
+        adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_disable_trust_agents,
+                "BYOD_DisableTrustAgentsTest",
+                R.string.provisioning_byod_disable_trust_agents_instruction,
+                new Intent(Settings.ACTION_SECURITY_SETTINGS)));
+        adapter.add(new DialogTestListItemWithIcon(this,
+                R.string.provisioning_byod_disable_notifications,
+                "BYOD_DisableUnredactedNotifications",
+                R.string.provisioning_byod_disable_notifications_instruction,
+                new Intent(WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION_ON_LOCKSCREEN),
+                R.drawable.ic_corp_icon));
+        FingerprintManager fpm = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);
+        if (fpm.isHardwareDetected()) {
+            adapter.add(new DialogTestListItem(this,
+                    R.string.provisioning_byod_fingerprint_disabled_in_settings,
+                    "BYOD_FingerprintDisabledInSettings",
+                    R.string.provisioning_byod_fingerprint_disabled_in_settings_instruction,
+                    new Intent(Settings.ACTION_SECURITY_SETTINGS)));
+            adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_disable_fingerprint,
+                    "BYOD_DisableFingerprint",
+                    R.string.provisioning_byod_disable_fingerprint_instruction,
+                    ByodHelperActivity.createLockIntent()));
+        }
+    }
+
+    @Override
+    protected void clearRemainingState(final DialogTestListItem test) {
+        super.clearRemainingState(test);
+        if (WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION_ON_LOCKSCREEN.equals(
+                test.getManualTestIntent().getAction())) {
+            try {
+                startActivity(new Intent(
+                        WorkNotificationTestActivity.ACTION_CLEAR_WORK_NOTIFICATION));
+            } catch (ActivityNotFoundException e) {
+                // User shouldn't run this test before work profile is set up.
+            }
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkNotificationTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkNotificationTestActivity.java
index c85ccf5..a912d2c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkNotificationTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkNotificationTestActivity.java
@@ -19,7 +19,9 @@
 import android.app.Activity;
 import android.app.Notification;
 import android.app.NotificationManager;
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.content.Intent;
 import android.os.Bundle;
 
 import com.android.cts.verifier.R;
@@ -30,26 +32,37 @@
 public class WorkNotificationTestActivity extends Activity {
     public static final String ACTION_WORK_NOTIFICATION =
             "com.android.cts.verifier.managedprovisioning.WORK_NOTIFICATION";
+    public static final String ACTION_WORK_NOTIFICATION_ON_LOCKSCREEN =
+            "com.android.cts.verifier.managedprovisioning.LOCKSCREEN_NOTIFICATION";
     public static final String ACTION_CLEAR_WORK_NOTIFICATION =
             "com.android.cts.verifier.managedprovisioning.CLEAR_WORK_NOTIFICATION";
     private static final int NOTIFICATION_ID = 7;
+    private NotificationManager mNotificationManager;
+
+    private void showWorkNotification(int visibility) {
+        final Notification notification = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.icon)
+                .setContentTitle(getString(R.string.provisioning_byod_work_notification_title))
+                .setVisibility(visibility)
+                .setAutoCancel(true)
+                .build();
+        mNotificationManager.notify(NOTIFICATION_ID, notification);
+    }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         final String action = getIntent().getAction();
-        final NotificationManager notificationManager = (NotificationManager)
-                getSystemService(Context.NOTIFICATION_SERVICE);
+        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
         if (ACTION_WORK_NOTIFICATION.equals(action)) {
-            final Notification notification = new Notification.Builder(this)
-                .setSmallIcon(R.drawable.icon)
-                .setContentTitle(getString(R.string.provisioning_byod_work_notification_title))
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setAutoCancel(true)
-                .build();
-            notificationManager.notify(NOTIFICATION_ID, notification);
+            showWorkNotification(Notification.VISIBILITY_PUBLIC);
+        } else if (ACTION_WORK_NOTIFICATION_ON_LOCKSCREEN.equals(action)) {
+            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            dpm.lockNow();
+            showWorkNotification(Notification.VISIBILITY_PRIVATE);
         } else if (ACTION_CLEAR_WORK_NOTIFICATION.equals(action)) {
-            notificationManager.cancel(NOTIFICATION_ID);
+            mNotificationManager.cancel(NOTIFICATION_ID);
         }
         finish();
     }
diff --git a/tests/deviceadmin/res/xml/device_admin.xml b/tests/deviceadmin/res/xml/device_admin.xml
index 263fda6..f7d394e 100644
--- a/tests/deviceadmin/res/xml/device_admin.xml
+++ b/tests/deviceadmin/res/xml/device_admin.xml
@@ -22,6 +22,7 @@
         <force-lock />
         <wipe-data />
         <expire-password />
+        <disable-keyguard-features />
     </uses-policies>
 </device-admin>
 
diff --git a/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index 04e2ba3..66e12c0 100644
--- a/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -526,6 +526,23 @@
         }
     }
 
+    public void testKeyguardDisabledFeatures() {
+        if (!mDeviceAdmin) {
+            Log.w(TAG, "Skipping testKeyguardDisabledFeatures");
+            return;
+        }
+        int originalValue = mDevicePolicyManager.getKeyguardDisabledFeatures(mComponent);
+        try {
+            for (int which = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
+                    which < 2 * DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT; ++which) {
+                mDevicePolicyManager.setKeyguardDisabledFeatures(mComponent, which);
+                assertEquals(which, mDevicePolicyManager.getKeyguardDisabledFeatures(mComponent));
+            }
+        } finally {
+            mDevicePolicyManager.setKeyguardDisabledFeatures(mComponent, originalValue);
+        }
+    }
+
     public void testCreateUser_failIfNotDeviceOwner() {
         if (!mDeviceAdmin) {
             Log.w(TAG, "Skipping testCreateUser_failIfNotDeviceOwner");