Fix CTS: MixedManagedProfileOwnerTest#testDelegatedCertInstaller failure

Cause: isKeyguardSecure api change KeyguardManager.isSecure()
to observe work profile in ag/1026084 (b/28666104). Only when
managed profile has password and work challenge,
KeyguardManager.isSecure() returns true.

Convert the activity into receiver as activity can't bypass
work challenge even using showForAllUser flag, b/28935539

BUG: 28888625
Change-Id: I3d995be3452a1339116022477d6c8f2d32dc30a1
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml b/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml
index c50e5fd..6bf1451 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml
@@ -20,7 +20,7 @@
     <uses-sdk android:minSdkVersion="22"/>
 
     <application>
-        <activity android:name="CertInstallerActivity">
+        <receiver android:name=".CertInstallerReceiver">
             <intent-filter>
                 <action android:name="com.android.cts.certinstaller.install_cert" />
                 <action android:name="com.android.cts.certinstaller.remove_cert" />
@@ -28,7 +28,7 @@
                 <action android:name="com.android.cts.certinstaller.install_keypair" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
-        </activity>
+        </receiver>
     </application>
 
 </manifest>
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerActivity.java b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerReceiver.java
similarity index 85%
rename from hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerActivity.java
rename to hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerReceiver.java
index b14822b..599bd8e 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerActivity.java
+++ b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerReceiver.java
@@ -15,11 +15,10 @@
  */
 package com.android.cts.certinstaller;
 
-import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.os.Bundle;
 import android.util.Base64;
 import android.util.Base64InputStream;
 import android.util.Log;
@@ -42,7 +41,7 @@
  * {@link DevicePolicyManager#getInstalledCaCerts},
  * {@link DevicePolicyManager#installKeyPair}.
  */
-public class CertInstallerActivity extends Activity {
+public class CertInstallerReceiver extends BroadcastReceiver {
 
     private static final String TAG = "DelegatedCertInstaller";
     // exercises {@link DevicePolicyManager#installCaCert} and
@@ -66,16 +65,13 @@
     private static final String EXTRA_RESULT_EXCEPTION = "extra_result_exception";
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        Intent intent = getIntent();
+    public void onReceive(Context context, Intent intent) {
         if (intent == null) {
-            finish();
             return;
         }
 
         String action = intent.getAction();
-        DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
+        DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
 
         byte[] certBuffer;
@@ -93,10 +89,10 @@
                 if (!dpm.hasCaCertInstalled(null, certBuffer)) {
                     throw new RuntimeException("Cannot find cert after installation.");
                 }
-                sendResult(true, null);
+                sendResult(context, true, null);
             } catch (Exception e) {
                 Log.e(TAG, "Exception raised duing ACTION_INSTALL_CERT", e);
-                sendResult(false, e);
+                sendResult(context, false, e);
             }
         } else if (ACTION_REMOVE_CERT.equals(action)) {
             try {
@@ -105,18 +101,19 @@
                     throw new RuntimeException("Trying to uninstall a non-existent cert.");
                 }
                 dpm.uninstallCaCert(null, certBuffer);
-                sendResult(!dpm.hasCaCertInstalled(null, certBuffer), null);
+                sendResult(context, !dpm.hasCaCertInstalled(null, certBuffer), null);
             } catch (Exception e) {
                 Log.e(TAG, "Exception raised duing ACTION_REMOVE_CERT", e);
-                sendResult(false, e);
+                sendResult(context, false, e);
             }
         } else if (ACTION_VERIFY_CERT.equals(action)) {
             try {
                 certBuffer = intent.getByteArrayExtra(EXTRA_CERT_DATA);
-                sendResult(containsCertificate(dpm.getInstalledCaCerts(null), certBuffer), null);
+                sendResult(context, containsCertificate(dpm.getInstalledCaCerts(null), certBuffer),
+                        null);
             } catch (Exception e) {
                 Log.e(TAG, "Exception raised duing ACTION_VERIFY_CERT", e);
-                sendResult(false, e);
+                sendResult(context, false, e);
             }
         } else if (ACTION_INSTALL_KEYPAIR.equals(action)) {
             String alias = intent.getStringExtra(EXTRA_KEY_ALIAS);
@@ -138,26 +135,27 @@
                 // CTS keychain tests will make sure the API's behaviour is correct.
                 // Note: installKeyPair() will silently return false if there is no lockscreen
                 // password, however the test setup should have set one already.
-                sendResult(dpm.installKeyPair(null, privatekey, certificate,  alias), null);
+                sendResult(context, dpm.installKeyPair(null, privatekey, certificate,  alias),
+                        null);
             } catch (Exception e) {
                 Log.e(TAG, "Exception raised duing ACTION_INSTALL_KEYPAIR", e);
-                sendResult(false, e);
+                sendResult(context, false, e);
             }
         }
-        finish();
     }
 
-    private void sendResult(boolean succeed, Exception e) {
+
+    private void sendResult(Context context, boolean succeed, Exception e) {
         Intent intent = new Intent();
         intent.setAction(ACTION_CERT_OPERATION_DONE);
         intent.putExtra(EXTRA_RESULT_VALUE, succeed);
         if (e != null) {
             intent.putExtra(EXTRA_RESULT_EXCEPTION, e);
         }
-        sendBroadcast(intent);
+        context.sendBroadcast(intent);
     }
 
-    private boolean containsCertificate(List<byte[]> certificates, byte[] toMatch)
+    private static boolean containsCertificate(List<byte[]> certificates, byte[] toMatch)
             throws CertificateException {
         Certificate certificateToMatch = readCertificate(toMatch);
         for (byte[] certBuffer : certificates) {
@@ -169,7 +167,7 @@
         return false;
     }
 
-    private Certificate readCertificate(byte[] certBuffer) throws CertificateException {
+    private static Certificate readCertificate(byte[] certBuffer) throws CertificateException {
         final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
         return certFactory.generateCertificate(new ByteArrayInputStream(certBuffer));
     }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
index e733189..fe027f7 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
@@ -19,6 +19,7 @@
 import android.app.KeyguardManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -52,6 +53,10 @@
     private static final String EXTRA_KEY_ALIAS = "extra_key_alias";
     private static final String EXTRA_RESULT_VALUE = "extra_result_value";
     private static final String EXTRA_RESULT_EXCEPTION = "extra_result_exception";
+    // package name of receiver has to be specified explicitly as the receiver is registered in
+    // manifest
+    private static final ComponentName CERT_INSTALLER_COMPONENT = new ComponentName(
+            CERT_INSTALLER_PACKAGE, "com.android.cts.certinstaller.CertInstallerReceiver");
 
     /*
      * The CA and keypair below are generated with:
@@ -254,30 +259,33 @@
     private void installCaCert(byte[] cert) {
         Intent intent = new Intent();
         intent.setAction(ACTION_INSTALL_CERT);
+        intent.setComponent(CERT_INSTALLER_COMPONENT);
         intent.putExtra(EXTRA_CERT_DATA, cert);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        mContext.sendBroadcast(intent);
     }
 
     private void removeCaCert(byte[] cert) {
         Intent intent = new Intent();
         intent.setAction(ACTION_REMOVE_CERT);
+        intent.setComponent(CERT_INSTALLER_COMPONENT);
         intent.putExtra(EXTRA_CERT_DATA, cert);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        mContext.sendBroadcast(intent);
     }
 
     private void verifyCaCert(byte[] cert) {
         Intent intent = new Intent();
         intent.setAction(ACTION_VERIFY_CERT);
+        intent.setComponent(CERT_INSTALLER_COMPONENT);
         intent.putExtra(EXTRA_CERT_DATA, cert);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        mContext.sendBroadcast(intent);
     }
 
     private void assertResult(String testName, Boolean expectSuccess) throws InterruptedException {
         assertTrue("Cert installer did not respond in time.",
-                mAvailableResultSemaphore.tryAcquire(5, TimeUnit.SECONDS));
+                mAvailableResultSemaphore.tryAcquire(10, TimeUnit.SECONDS));
         synchronized (this) {
             if (expectSuccess) {
                 assertTrue(testName + " failed unexpectedly.", mReceivedResult);
@@ -294,10 +302,11 @@
     private void installKeyPair(String key, String cert, String alias) {
         Intent intent = new Intent();
         intent.setAction(ACTION_INSTALL_KEYPAIR);
+        intent.setComponent(CERT_INSTALLER_COMPONENT);
         intent.putExtra(EXTRA_CERT_DATA, cert);
         intent.putExtra(EXTRA_KEY_DATA, key);
         intent.putExtra(EXTRA_KEY_ALIAS, alias);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(intent);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        mContext.sendBroadcast(intent);
     }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index 2c6e4ca..460d44d 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -362,30 +362,20 @@
 
         installAppAsUser(CERT_INSTALLER_APK, mUserId);
 
-        boolean installProfileOwnerForPassword = (mPrimaryUserId != mUserId);
-        if (installProfileOwnerForPassword) {
-            // This is a managed profile test. We need to set a profile owner on the primary user in
-            // order to be able to set and clear the lockscreen password.
-            installAppAsUser(DEVICE_ADMIN_APK, mPrimaryUserId);
-            setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
-                    mPrimaryUserId);
-        }
+        boolean isManagedProfile = (mPrimaryUserId != mUserId);
 
         try {
             // Set a non-empty device lockscreen password, which is a precondition for installing
             // private key pairs.
             assertTrue("Set lockscreen password failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
-                    ".ResetPasswordHelper", "testSetPassword", mPrimaryUserId));
+                    ".ResetPasswordHelper", "testSetPassword", mUserId));
             assertTrue("DelegatedCertInstaller failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
                     ".DelegatedCertInstallerTest", mUserId));
         } finally {
-            // Reset lockscreen password and remove profile owner if required
-            assertTrue("Clear lockscreen password failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
-                    ".ResetPasswordHelper", "testClearPassword", mPrimaryUserId));
-            if (installProfileOwnerForPassword) {
-                assertTrue("Failed to remove profile owner.",
-                        removeAdmin(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
-                                mPrimaryUserId));
+            if (!isManagedProfile) {
+                // Skip managed profile as dpm doesn't allow clear password
+                assertTrue("Clear lockscreen password failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
+                        ".ResetPasswordHelper", "testClearPassword", mUserId));
             }
         }
     }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
index 3d1b540..554f53b 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -37,16 +37,20 @@
         if (mHasFeature) {
             removeTestUsers();
             mParentUserId = mPrimaryUserId;
-            mUserId = createManagedProfile(mParentUserId);
-            switchUser(mParentUserId);
-            startUser(mUserId);
-
-            installAppAsUser(DEVICE_ADMIN_APK, mUserId);
-            setProfileOwnerOrFail(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
-            startUser(mUserId);
+            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) {
@@ -97,4 +101,20 @@
         // DISALLOW_UNMUTE_MICROPHONE and DISALLOW_ADJUST_VOLUME can only be set by device owners
         // and profile owners on the primary user.
     }
+
+    @Override
+    public void testDelegatedCertInstaller() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        try {
+            super.testDelegatedCertInstaller();
+        } finally {
+            // In managed profile, clearing password through dpm is not allowed. Recreate user to
+            // clear password instead.
+            removeUser(mUserId);
+            createManagedProfile();
+        }
+    }
 }