Added invalid certificate dialog

This is part of the changes to improve the UX and language for installing certificates.
With the addition of the Settings page to select the type of certificate to install,
additional logic is required to ensure an appropriate certificate is selected.
This CL does validation checks and will show a dialog if the wrong certificate type is selected.

Bug: 139173976
Test: manual testing by selecting different certificate types with the file picker
      Including testing certificate which needs to be extracted
      go/enterprise-wifi-lab-access

Screenshot of the screen: https://hsv.googleplex.com/4890125932691456

Change-Id: I45064f7b5a14d84232d7009fa7c2b1387f674ae4
diff --git a/res/values/strings.xml b/res/values/strings.xml
index def2b3f..44632fd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -58,10 +58,6 @@
     <string name="action_missing_private_key">Private key required to install a certificate</string>
     <string name="action_missing_user_cert">Certificate required to install a private key</string>
 
-    <!-- Title of User certificate -->
-    <string name="user_certificate">VPN &amp; app user certificate</string>
-    <!-- Title of Wi-Fi certificate -->
-    <string name="wifi_certificate">Wi\u2011Fi certificate</string>
     <!-- Title of dialog to select the certificate usage when installing a certificate outside Settings -->
     <string name="select_certificate_usage_title">Choose a certificate type</string>
     <!-- Title of dialog to redirect user when installing a CA certificate outside Settings -->
@@ -70,6 +66,21 @@
     <string name="redirect_ca_certificate_message">CA certificates can put your privacy at risk and must be installed in Settings</string>
     <!-- Button of dialog to redirect user when installing a CA certificate outside Settings -->
     <string name="redirect_ca_certificate_close_button">Close</string>
+    <!-- Title of dialog to inform user that certificate selected is invalid -->
+    <string name="invalid_certificate_title">Can\'t install certificates</string>
+    <!-- Button of dialog to inform user that certificate selected is invalid -->
+    <string name="invalid_certificate_close_button">Close</string>
+    <!-- Message of dialog to inform user that certificate selected is invalid -->
+    <string name="invalid_certificate_message">This file can\'t be used as a <xliff:g id="certificate_usage">%1$s</xliff:g></string>
+    <!-- Default certificate type used in dialog to inform user that certificate selected is invalid -->
+    <string name="certificate">Certificate</string>
+    <!-- CA certificate type used in dialog to inform user that certificate selected is invalid -->
+    <string name="ca_certificate">CA certificate</string>
+    <!-- User certificate type used in dialog to inform user that certificate selected is invalid -->
+    <string name="user_certificate">VPN &amp; app user certificate</string>
+    <!-- WiFi certificate type used in dialog to inform user that certificate selected is invalid -->
+    <string name="wifi_certificate">Wi\u2011Fi certificate</string>
+
 
     <!-- Confirmation toast. This toast lets the user know that they successfully installed a CA certificate on their device. -->
     <string name="ca_cert_is_added">CA certificate installed</string>
diff --git a/src/com/android/certinstaller/CertInstaller.java b/src/com/android/certinstaller/CertInstaller.java
index 2956c51..dfcd1e1 100644
--- a/src/com/android/certinstaller/CertInstaller.java
+++ b/src/com/android/certinstaller/CertInstaller.java
@@ -56,6 +56,7 @@
     private static final int PROGRESS_BAR_DIALOG = 3;
     private static final int REDIRECT_CA_CERTIFICATE_DIALOG = 4;
     private static final int SELECT_CERTIFICATE_USAGE_DIALOG = 5;
+    private static final int INVALID_CERTIFICATE_DIALOG = 6;
 
     private static final int REQUEST_SYSTEM_INSTALL_CODE = 1;
 
@@ -165,6 +166,9 @@
             case SELECT_CERTIFICATE_USAGE_DIALOG:
                 return createSelectCertificateUsageDialog();
 
+            case INVALID_CERTIFICATE_DIALOG:
+                return createInvalidCertificateDialog();
+
             default:
                 return null;
         }
@@ -255,7 +259,25 @@
             return;
         }
 
-        installCertificateOrShowNameDialog();
+        if (validCertificateSelected()) {
+            installCertificateOrShowNameDialog();
+        } else {
+            showDialog(INVALID_CERTIFICATE_DIALOG);
+        }
+    }
+
+    private boolean validCertificateSelected() {
+        switch (mCredentials.getCertUsageSelected()) {
+            case Credentials.CERTIFICATE_USAGE_CA:
+                return mCredentials.hasOnlyVpnAndAppsTrustAnchors();
+            case Credentials.CERTIFICATE_USAGE_USER:
+                return mCredentials.hasUserCertificate()
+                        && !mCredentials.hasOnlyVpnAndAppsTrustAnchors();
+            case Credentials.CERTIFICATE_USAGE_WIFI:
+                return !mCredentials.hasOnlyVpnAndAppsTrustAnchors();
+            default:
+                return false;
+        }
     }
 
     private void installCertificateOrShowNameDialog() {
@@ -301,7 +323,11 @@
         if (success) {
             removeDialog(PKCS12_PASSWORD_DIALOG);
             if (mCredentials.calledBySettings()) {
-                installCertificateOrShowNameDialog();
+                if (validCertificateSelected()) {
+                    installCertificateOrShowNameDialog();
+                } else {
+                    showDialog(INVALID_CERTIFICATE_DIALOG);
+                }
             } else {
                 createRedirectOrSelectUsageDialog();
             }
@@ -367,6 +393,31 @@
         return d;
     }
 
+    private Dialog createInvalidCertificateDialog() {
+        Dialog d = new AlertDialog.Builder(this)
+                .setTitle(R.string.invalid_certificate_title)
+                .setMessage(getString(R.string.invalid_certificate_message,
+                        getCertificateUsageName()))
+                .setPositiveButton(R.string.invalid_certificate_close_button,
+                        (dialog, id) -> toastErrorAndFinish(R.string.cert_not_saved))
+                .create();
+        d.setOnCancelListener(dialog -> finish());
+        return d;
+    }
+
+    String getCertificateUsageName() {
+        switch (mCredentials.getCertUsageSelected()) {
+            case Credentials.CERTIFICATE_USAGE_CA:
+                return getString(R.string.ca_certificate);
+            case Credentials.CERTIFICATE_USAGE_USER:
+                return getString(R.string.user_certificate);
+            case Credentials.CERTIFICATE_USAGE_WIFI:
+                return getString(R.string.wifi_certificate);
+            default:
+                return getString(R.string.certificate);
+        }
+    }
+
     private Dialog createPkcs12PasswordDialog() {
         View view = View.inflate(this, R.layout.password_dialog, null);
         mView.setView(view);