[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 014efaddc6 -s ours

am skip reason: subject contains skip directive

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/CertInstaller/+/15546661

Change-Id: Ic82edec7928d74c38db7d9bc0a47eb1ad51c6afe
diff --git a/Android.bp b/Android.bp
index a6ded0b..9bc8795 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,5 +1,25 @@
+package {
+    default_applicable_licenses: ["packages_apps_CertInstaller_license"],
+}
+
+// Added automatically by a large-scale-change
+// http://go/android-license-faq
+license {
+    name: "packages_apps_CertInstaller_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 android_app {
     name: "CertInstaller",
+    static_libs: [
+        "bouncycastle-unbundled",
+    ],
     srcs: ["src/**/*.java"],
     platform_apis: true,
     certificate: "platform",
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4212254..886b7ca 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,61 +1,65 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.certinstaller">
+<?xml version="1.0" encoding="utf-8"?>
 
-    <original-package android:name="com.android.certinstaller" />
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+     package="com.android.certinstaller">
+
+    <original-package android:name="com.android.certinstaller"/>
 
     <permission android:name="com.android.certinstaller.INSTALL_AS_USER"
-                android:protectionLevel="signature" />
-    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
-    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.MANAGE_USERS" />
-    <uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS" />
-    <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" />
+         android:protectionLevel="signature"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.MANAGE_USERS"/>
+    <uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS"/>
+    <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"/>
 
     <application android:label="@string/app_name"
-                 android:allowBackup="false">
+         android:allowBackup="false">
         <activity android:name=".CertInstallerMain"
-                  android:theme="@style/Transparent"
-                  android:configChanges="orientation|keyboardHidden|screenSize">
+             android:theme="@style/Transparent"
+             android:configChanges="orientation|keyboardHidden|screenSize"
+             android:exported="true">
             <intent-filter>
-                <action android:name="android.credentials.INSTALL" />
-                <category android:name="android.intent.category.DEFAULT" />
+                <action android:name="android.credentials.INSTALL"/>
+                <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
             <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <data android:mimeType="application/x-x509-ca-cert" />
-                <data android:mimeType="application/x-x509-user-cert" />
-                <data android:mimeType="application/x-x509-server-cert" />
-                <data android:mimeType="application/x-pkcs12" />
-                <data android:mimeType="application/x-pem-file" />
-                <data android:mimeType="application/pkix-cert" />
-                <data android:mimeType="application/x-wifi-config" />
+                <action android:name="android.intent.action.VIEW"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <data android:mimeType="application/x-x509-ca-cert"/>
+                <data android:mimeType="application/x-x509-user-cert"/>
+                <data android:mimeType="application/x-x509-server-cert"/>
+                <data android:mimeType="application/x-pkcs12"/>
+                <data android:mimeType="application/x-pem-file"/>
+                <data android:mimeType="application/pkix-cert"/>
+                <data android:mimeType="application/x-wifi-config"/>
             </intent-filter>
         </activity>
 
         <activity-alias android:name=".InstallCertAsUser"
-                        android:targetActivity=".CertInstallerMain"
-                        android:permission="com.android.certinstaller.INSTALL_AS_USER">
+             android:targetActivity=".CertInstallerMain"
+             android:exported="true"
+             android:permission="com.android.certinstaller.INSTALL_AS_USER">
             <intent-filter>
-                <action android:name="android.credentials.INSTALL_AS_USER" />
-                <category android:name="android.intent.category.DEFAULT" />
+                <action android:name="android.credentials.INSTALL_AS_USER"/>
+                <category android:name="android.intent.category.DEFAULT"/>
             </intent-filter>
         </activity-alias>
 
         <activity android:name=".CertInstaller"
-                  android:theme="@style/Transparent"
-                  android:configChanges="orientation|keyboardHidden"
-                  android:exported="false">
+             android:theme="@style/Transparent"
+             android:configChanges="orientation|keyboardHidden"
+             android:exported="false">
         </activity>
         <activity android:name=".WiFiInstaller"
-                  android:theme="@style/Transparent"
-                  android:configChanges="orientation|keyboardHidden"
-                  android:exported="false">
+             android:theme="@style/Transparent"
+             android:configChanges="orientation|keyboardHidden"
+             android:exported="false">
         </activity>
         <activity android:name=".CredentialsInstallDialog"
-                  android:theme="@style/Transparent"
-                  android:configChanges="orientation|keyboardHidden"
-                  android:exported="false">
+             android:theme="@style/Transparent"
+             android:configChanges="orientation|keyboardHidden"
+             android:exported="false">
         </activity>
     </application>
 </manifest>
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/OWNERS b/OWNERS
index 13bb3b6..f67e72d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,6 @@
-eranm@google.com
 pgrafov@google.com
 rubinxu@google.com
 sandness@google.com
+
+# Emeritus
+eranm@google.com
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index f856629..32ce802 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -83,8 +83,8 @@
     <string name="install_done" msgid="1522718684172097080">"<xliff:g id="NAME">%1$s</xliff:g> நற்சான்றிதழ், சேமித்த வைஃபை நெட்வொர்க்குகளில் சேர்க்கப்பட்டது."</string>
     <string name="done_label" msgid="5597425930652904250">"முடிந்தது"</string>
     <string name="wifi_installer_detail" msgid="63879632832701669">"<xliff:g id="NAME">%1$s</xliff:g> வழியாகக் கிடைக்கும் நெட்வொர்க்குகளுடன் இணைக்க, வைஃபை நற்சான்றிதழை நிறுவவும்."</string>
-    <string name="wifi_installer_download_error" msgid="5429453090956277692">"இறக்கப்பட்ட ஃபைலில் சிக்கல்கள் உள்ளதால், அதை நிறுவ முடியாது. சரியான மூலத்திலிருந்து ஃபைலை இறக்கியதை உறுதிப்படுத்திக்கொள்ளவும்."</string>
-    <string name="wifi_installer_fail" msgid="894483173306576331">"வைஃபை நற்சான்றிதழை நிறுவ முடியவில்லை. ஃபைலை மீண்டும் இறக்க முயற்சிக்கவும்."</string>
+    <string name="wifi_installer_download_error" msgid="5429453090956277692">"இறக்கப்பட்ட ஃபைலில் சிக்கல்கள் உள்ளதால், அதை நிறுவ முடியாது. சரியான மூலத்திலிருந்து கோப்பை இறக்கியதை உறுதிப்படுத்திக்கொள்ளவும்."</string>
+    <string name="wifi_installer_fail" msgid="894483173306576331">"வைஃபை நற்சான்றிதழை நிறுவ முடியவில்லை. கோப்பை மீண்டும் இறக்க முயற்சிக்கவும்."</string>
     <string name="wifi_installer_fail_no_wifi_title" msgid="8358191074828840533">"நிறுவுதல் ரத்துசெய்யப்பட்டது"</string>
     <string name="wifi_installer_fail_title" msgid="5547079779067835479">"நிறுவ முடியவில்லை"</string>
     <string name="wifi_installer_fail_no_wifi" msgid="2044576439984209921">"வைஃபையை இயக்கி, மீண்டும் முயற்சிக்கவும்."</string>
diff --git a/robotests/Android.bp b/robotests/Android.bp
new file mode 100644
index 0000000..63de5d5
--- /dev/null
+++ b/robotests/Android.bp
@@ -0,0 +1,21 @@
+//############################################################
+// CertInstaller Robolectric test target.                    #
+//############################################################
+
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "packages_apps_CertInstaller_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["packages_apps_CertInstaller_license"],
+}
+
+android_robolectric_test {
+    name: "CertInstallerRoboTests",
+
+    srcs: ["src/**/*.java"],
+
+    java_resource_dirs: ["config"],
+
+    instrumentation_for: "CertInstaller",
+}
diff --git a/robotests/config/robolectric.properties b/robotests/config/robolectric.properties
new file mode 100644
index 0000000..c5e4c0b
--- /dev/null
+++ b/robotests/config/robolectric.properties
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2020 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.
+#
+
+sdk=NEWEST_SDK
diff --git a/robotests/src/com/android/certinstaller/CertInstallerRoboTest.java b/robotests/src/com/android/certinstaller/CertInstallerRoboTest.java
new file mode 100644
index 0000000..1c845a9
--- /dev/null
+++ b/robotests/src/com/android/certinstaller/CertInstallerRoboTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2020 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.certinstaller;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.Intent;
+import android.security.Credentials;
+import android.security.KeyChain;
+import android.security.KeyStore;
+import android.os.Process;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+
+@RunWith(RobolectricTestRunner.class)
+public final class CertInstallerRoboTest {
+
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application.getApplicationContext();
+    }
+
+    @Test
+    public void testNameNotNullPass() throws Exception {
+        Intent intent = new Intent(mContext, CertInstaller.class);
+        intent.putExtra(KeyChain.EXTRA_NAME, "name");
+        CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
+
+        assertThat(helper.getName()).isEqualTo("name");
+    }
+
+    @Test
+    public void testReferrerNotNullPass() throws Exception {
+        Intent intent = new Intent(mContext, CertInstaller.class);
+        intent.putExtra(Intent.EXTRA_REFERRER, "referrer");
+        CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
+
+        assertThat(helper.getReferrer()).isEqualTo("referrer");
+    }
+
+    /**
+     * mUid should be ignored if EXTRA_CERTIFICATE_USAGE is provided.
+     * if EXTRA_CERTIFICATE_USAGE equals CERTIFICATE_USAGE_WIFI,
+     * mUid should equal Process.WIFI_UID
+     */
+    @Test
+    public void testUidUsageEqualWifiPass() throws Exception {
+        Intent intent = new Intent(mContext, CertInstaller.class);
+        intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, Process.INVALID_UID);
+        intent.putExtra(Credentials.EXTRA_CERTIFICATE_USAGE, Credentials.CERTIFICATE_USAGE_WIFI);
+
+        CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
+
+        assertThat(helper.getCertUsageSelected()).isEqualTo(Credentials.CERTIFICATE_USAGE_WIFI);
+        assertThat(helper.getUid()).isEqualTo(Process.WIFI_UID);
+
+    }
+
+    /**
+     * mUid should be ignored if EXTRA_CERTIFICATE_USAGE is provided.
+     * if EXTRA_CERTIFICATE_USAGE does not equal CERTIFICATE_USAGE_WIFI,
+     * mUid should equal KeyStore.UID_SELF
+     */
+    @Test
+    public void testUidUsageNotNullPass() throws Exception {
+        Intent intent = new Intent(mContext, CertInstaller.class);
+        intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, Process.INVALID_UID);
+        intent.putExtra(Credentials.EXTRA_CERTIFICATE_USAGE, "usage");
+
+        CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
+
+        assertThat(helper.getUid()).isEqualTo(KeyStore.UID_SELF);
+        assertThat(helper.getCertUsageSelected()).isEqualTo("usage");
+    }
+
+    /**
+     * if EXTRA_CERTIFICATE_USAGE is not provided,
+     * mUid should equal the Credentials.EXTRA_INSTALL_AS_UID extra
+     */
+    @Test
+    public void testUidUsageNullPass() throws Exception {
+        Intent intent = new Intent(mContext, CertInstaller.class);
+        intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, 100);
+
+        CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
+
+        assertThat(helper.getUid()).isEqualTo(100);
+    }
+
+    @Test
+    public void testIntentGetsMultipleKeysPass() throws Exception {
+        Intent intent = new Intent(mContext, CertInstaller.class);
+        intent.putExtra("key1", CA_CERTIFICATE_1);
+        intent.putExtra("key2", CA_CERTIFICATE_2);
+
+        CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
+
+        assertThat(helper.getData("key1")).isEqualTo(CA_CERTIFICATE_1);
+        assertThat(helper.getData("key2")).isEqualTo(CA_CERTIFICATE_2);
+    }
+    @Test
+    public void testIntentNullPass() throws Exception {
+        Intent intent = new Intent(mContext, CertInstaller.class);
+
+        CredentialHelper helper = startActivityAndGetCredentialHelper(intent);
+
+        assertThat(!helper.containsAnyRawData()).isTrue();
+        assertThat(helper.getName()).isEqualTo("");
+        assertThat(helper.getUid()).isEqualTo(Process.INVALID_UID);
+        assertThat(helper.getReferrer()).isEqualTo("");
+        assertThat(helper.getCertUsageSelected()).isEqualTo("");
+    }
+
+    private CredentialHelper startActivityAndGetCredentialHelper(Intent intent) {
+        ActivityController<CertInstaller> controller =
+                Robolectric.buildActivity(CertInstaller.class, intent);
+
+        CertInstaller activity = controller
+                .create()
+                .start()
+                .resume()
+                .visible()
+                .get();
+        return activity.getCredentials();
+    }
+
+    public static final byte[] CA_CERTIFICATE_1 = new byte[]{
+            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8a, (byte) 0x30, (byte) 0x82
+    };
+
+    public static final byte[] CA_CERTIFICATE_2 = new byte[]{
+            (byte) 0x01, (byte) 0xf3, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01
+    };
+
+}
\ No newline at end of file
diff --git a/src/com/android/certinstaller/CertInstaller.java b/src/com/android/certinstaller/CertInstaller.java
index 3a6b7b3..570c400 100644
--- a/src/com/android/certinstaller/CertInstaller.java
+++ b/src/com/android/certinstaller/CertInstaller.java
@@ -29,6 +29,7 @@
 import android.content.pm.PackageManager;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Process;
 import android.security.Credentials;
 import android.security.KeyChain;
 import android.security.KeyChain.KeyChainConnection;
@@ -41,7 +42,11 @@
 import android.widget.RadioGroup;
 import android.widget.Toast;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Installs certificates to the system keystore.
@@ -73,7 +78,32 @@
 
     private CredentialHelper createCredentialHelper(Intent intent) {
         try {
-            return new CredentialHelper(intent);
+            Bundle bundle = intent.getExtras();
+            if (bundle == null) {
+                return new CredentialHelper();
+            } else {
+                int size = bundle.size();
+                Log.d(TAG, "# extras: " + size);
+
+                String name = bundle.getString(KeyChain.EXTRA_NAME);
+                bundle.remove(KeyChain.EXTRA_NAME);
+
+                String referrer = bundle.getString(Intent.EXTRA_REFERRER);
+                bundle.remove(Intent.EXTRA_REFERRER);
+
+                String certUsageSelected = bundle.getString(Credentials.EXTRA_CERTIFICATE_USAGE);
+                bundle.remove(Credentials.EXTRA_CERTIFICATE_USAGE);
+
+                int uid = bundle.getInt(Credentials.EXTRA_INSTALL_AS_UID, Process.INVALID_UID);
+                bundle.remove(Credentials.EXTRA_INSTALL_AS_UID);
+
+                Map<String, byte[]> byteMap = new HashMap<>();
+                for (String key : bundle.keySet()) {
+                    byte[] bytes = bundle.getByteArray(key);
+                    byteMap.put(key, bytes);
+                }
+                return new CredentialHelper(byteMap, name,  referrer, certUsageSelected, uid);
+            }
         } catch (Throwable t) {
             Log.w(TAG, "createCredentialHelper", t);
             toastErrorAndFinish(R.string.invalid_cert);
@@ -247,7 +277,7 @@
     }
 
     private void installOthers() {
-        // Sanity check: Check that there's either:
+        // Check that there's either:
         // * A private key AND a user certificate, or
         // * A CA cert.
         boolean hasPrivateKeyAndUserCertificate =
@@ -564,4 +594,9 @@
             host.onExtractionDone(mSuccess);
         }
     }
+
+    @VisibleForTesting
+    public CredentialHelper getCredentials() {
+        return mCredentials;
+    }
 }
diff --git a/src/com/android/certinstaller/CertInstallerMain.java b/src/com/android/certinstaller/CertInstallerMain.java
index 4cec5fc..17b5649 100644
--- a/src/com/android/certinstaller/CertInstallerMain.java
+++ b/src/com/android/certinstaller/CertInstallerMain.java
@@ -16,14 +16,11 @@
 
 package com.android.certinstaller;
 
-import android.app.ActivityTaskManager;
-import android.app.IActivityTaskManager;
 import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.RemoteException;
 import android.os.UserManager;
 import android.preference.PreferenceActivity;
 import android.provider.DocumentsContract;
@@ -192,20 +189,12 @@
         }
         installIntent.putExtras(intent);
 
-        try {
-            // The referrer is passed as an extra because the launched-from package needs to be
-            // obtained here and not in the CertInstaller.
-            // It is also safe to add the referrer as an extra because the CertInstaller activity
-            // is not exported, which means it cannot be called from other apps.
-            IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();
-            installIntent.putExtra(Intent.EXTRA_REFERRER,
-                    activityTaskManager.getLaunchedFromPackage(getActivityToken()));
-            startActivityForResult(installIntent, REQUEST_INSTALL);
-        } catch (RemoteException e) {
-            Log.v(TAG, "Could not talk to activity manager.", e);
-            Toast.makeText(this, R.string.cert_temp_error, Toast.LENGTH_LONG).show();
-            finish();
-        }
+        // The referrer is passed as an extra because the launched-from package needs to be
+        // obtained here and not in the CertInstaller.
+        // It is also safe to add the referrer as an extra because the CertInstaller activity
+        // is not exported, which means it cannot be called from other apps.
+        installIntent.putExtra(Intent.EXTRA_REFERRER, getLaunchedFromPackage());
+        startActivityForResult(installIntent, REQUEST_INSTALL);
     }
 
     private void startInstallActivity(String mimeType, Uri uri) {
diff --git a/src/com/android/certinstaller/CredentialHelper.java b/src/com/android/certinstaller/CredentialHelper.java
index a1e9314..eab58f5 100644
--- a/src/com/android/certinstaller/CredentialHelper.java
+++ b/src/com/android/certinstaller/CredentialHelper.java
@@ -17,7 +17,8 @@
 package com.android.certinstaller;
 
 import static android.security.KeyStore.UID_SELF;
-
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.KeyguardManager;
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
@@ -34,11 +35,12 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.org.bouncycastle.asn1.ASN1InputStream;
-import com.android.org.bouncycastle.asn1.ASN1Sequence;
-import com.android.org.bouncycastle.asn1.DEROctetString;
-import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.org.conscrypt.TrustedCertificateStore;
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.x509.BasicConstraints;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
@@ -59,6 +61,7 @@
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * A helper class for accessing the raw data in the intent extra and handling
@@ -78,7 +81,7 @@
     private String mName = "";
     private String mCertUsageSelected = "";
     private String mReferrer = "";
-    private int mUid = -1;
+    private int mUid = Process.INVALID_UID;
     private PrivateKey mUserKey;
     private X509Certificate mUserCert;
     private List<X509Certificate> mCaCerts = new ArrayList<X509Certificate>();
@@ -86,36 +89,31 @@
     CredentialHelper() {
     }
 
-    CredentialHelper(Intent intent) {
-        Bundle bundle = intent.getExtras();
-        if (bundle == null) {
-            return;
-        }
-
-        String name = bundle.getString(KeyChain.EXTRA_NAME);
-        bundle.remove(KeyChain.EXTRA_NAME);
+    /**
+     * @param byteMap keeps raw data from intent's extra
+     * @param name
+     * @param referrer
+     * @param certUsageSelected used to assign mUid according to certificate usage
+     * @param uid is ignored unless certUsageSelected is null
+     */
+    CredentialHelper(@NonNull Map<String, byte[]> byteMap, @Nullable String name,
+            @Nullable String referrer, @Nullable String certUsageSelected, int uid) {
         if (name != null) {
             mName = name;
         }
 
-        String certUsageSelected = bundle.getString(Credentials.EXTRA_CERTIFICATE_USAGE);
-        bundle.remove(Credentials.EXTRA_CERTIFICATE_USAGE);
-        if (certUsageSelected != null) {
-            setCertUsageSelectedAndUid(certUsageSelected);
-        } else {
-            mUid = bundle.getInt(Credentials.EXTRA_INSTALL_AS_UID, -1);
-        }
-        bundle.remove(Credentials.EXTRA_INSTALL_AS_UID);
-
-        String referrer = bundle.getString(Intent.EXTRA_REFERRER);
-        bundle.remove(Intent.EXTRA_REFERRER);
         if (referrer != null) {
             mReferrer = referrer;
         }
 
-        Log.d(TAG, "# extras: " + bundle.size());
-        for (String key : bundle.keySet()) {
-            byte[] bytes = bundle.getByteArray(key);
+        if (certUsageSelected != null) {
+            setCertUsageSelectedAndUid(certUsageSelected);
+        } else {
+            mUid = uid;
+        }
+
+        for (String key : byteMap.keySet()) {
+            byte[] bytes = byteMap.get(key);
             Log.d(TAG, "   " + key + ": " + ((bytes == null) ? -1 : bytes.length));
             mBundle.put(key, bytes);
         }
@@ -149,7 +147,7 @@
     void onRestoreStates(Bundle savedStates) {
         mBundle = (HashMap) savedStates.getSerializable(DATA_KEY);
         mName = savedStates.getString(KeyChain.EXTRA_NAME);
-        mUid = savedStates.getInt(Credentials.EXTRA_INSTALL_AS_UID, -1);
+        mUid = savedStates.getInt(Credentials.EXTRA_INSTALL_AS_UID, Process.INVALID_UID);
         String userKeyAlgorithm = savedStates.getString(USER_KEY_ALGORITHM);
         byte[] userKeyBytes = savedStates.getByteArray(Credentials.USER_PRIVATE_KEY);
         Log.d(TAG, "Loaded key algorithm: " + userKeyAlgorithm);
@@ -475,4 +473,9 @@
     public String getReferrer() {
         return mReferrer;
     }
+
+    @VisibleForTesting
+    public int getUid() {
+        return mUid;
+    }
 }
diff --git a/src/com/android/certinstaller/WiFiInstaller.java b/src/com/android/certinstaller/WiFiInstaller.java
index 41827f6..ad03eca 100644
--- a/src/com/android/certinstaller/WiFiInstaller.java
+++ b/src/com/android/certinstaller/WiFiInstaller.java
@@ -1,5 +1,7 @@
 package com.android.certinstaller;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.Context;
@@ -13,6 +15,8 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.DocumentsContract;
+import android.text.TextUtils;
+import android.util.EventLog;
 import android.util.Log;
 import android.view.View;
 import android.widget.TextView;
@@ -26,18 +30,24 @@
     private static final String TAG = "WifiInstaller";
     private static final String NETWORK_NAME = "network_name";
     private static final String INSTALL_STATE = "install_state";
+    private static final String TYPE_WIFI_CONFIG = "application/x-wifi-config";
     public static final int INSTALL_SUCCESS = 2;
     public static final int INSTALL_FAIL = 1;
     public static final int INSTALL_FAIL_NO_WIFI = 0;
-    PasspointConfiguration mPasspointConfig;
-    WifiManager mWifiManager;
-    boolean doNotInstall;
+    private PasspointConfiguration mPasspointConfig;
+    private boolean mIsPasspointConfigurationValid;
 
     @Override
     protected void onCreate(Bundle savedStates) {
         super.onCreate(savedStates);
+        getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
 
+        mIsPasspointConfigurationValid = false;
         Bundle bundle = getIntent().getExtras();
+        if (bundle == null) {
+            Log.e(TAG, "Invalid inputs");
+            return;
+        }
         String uriString = bundle.getString(CertInstallerMain.WIFI_CONFIG_FILE);
         String mimeType = bundle.getString(CertInstallerMain.WIFI_CONFIG);
         byte[] data = bundle.getByteArray(CertInstallerMain.WIFI_CONFIG_DATA);
@@ -45,17 +55,34 @@
         Log.d(TAG, "WiFi data for " + CertInstallerMain.WIFI_CONFIG + ": " +
                 mimeType + " is " + (data != null ? data.length : "-"));
 
-        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
-        mPasspointConfig = ConfigParser.parsePasspointConfig(mimeType, data);
-        dropFile(Uri.parse(uriString), getApplicationContext());
-
-        if (mPasspointConfig == null) {
-            Log.w(TAG, "failed to build passpoint configuration");
-            doNotInstall = true;
-        } else if (mPasspointConfig.getHomeSp() == null) {
-            Log.w(TAG, "Passpoint profile missing HomeSP information");
-            doNotInstall = true;
+        // Make sure that the input is valid
+        if (data == null || data.length == 0 || TextUtils.isEmpty(uriString)) {
+            Log.e(TAG, "Invalid inputs");
+            return;
         }
+
+        // Verify MIME type before parsing
+        if (!TextUtils.equals(mimeType, TYPE_WIFI_CONFIG)) {
+            Log.e(TAG, "Unexpected MIME type: " + mimeType);
+            EventLog.writeEvent(0x534e4554, "176756691", -1, "Invalid mime-type");
+            return;
+        }
+
+        mPasspointConfig = ConfigParser.parsePasspointConfig(mimeType, data);
+        if (mPasspointConfig == null) {
+            Log.e(TAG, "Failed to build Passpoint configuration");
+            EventLog.writeEvent(0x534e4554, "176756691", -1, "Invalid data in file "
+                    + uriString);
+            return;
+        }
+        if (mPasspointConfig.getHomeSp() == null) {
+            Log.e(TAG, "Passpoint profile missing HomeSP information");
+        } else {
+            // Passpoint configuration parsed successfully and valid. Mark to be installed.
+            mIsPasspointConfigurationValid = true;
+        }
+        // Delete the file only if the Passpoint configuration was parsed successfully
+        dropFile(Uri.parse(uriString), getApplicationContext());
     }
 
     @Override
@@ -75,7 +102,8 @@
         builder.setView(layout);
 
         TextView text = (TextView) layout.findViewById(R.id.wifi_info);
-        if (!doNotInstall) {
+        if (mIsPasspointConfigurationValid) {
+            WifiManager wifiManager = getSystemService(WifiManager.class);
             text.setText(String.format(getResources().getString(R.string.wifi_installer_detail),
                     mPasspointConfig.getHomeSp().getFriendlyName()));
 
@@ -93,14 +121,14 @@
                         public void run() {
                             boolean success = true;
                             try {
-                                mWifiManager.removePasspointConfiguration(
+                                wifiManager.removePasspointConfiguration(
                                         mPasspointConfig.getHomeSp().getFqdn());
                             } catch (IllegalArgumentException e) {
                                 // Do nothing. This is expected if a profile with this FQDN does not
                                 // exist.
                             }
                             try {
-                                mWifiManager.addOrUpdatePasspointConfiguration(mPasspointConfig);
+                                wifiManager.addOrUpdatePasspointConfiguration(mPasspointConfig);
                             } catch (RuntimeException rte) {
                                 Log.w(TAG, "Caught exception while installing wifi config: " +
                                            rte, rte);
@@ -144,7 +172,9 @@
                 }
             });
         }
-        builder.create().show();
+        final AlertDialog alertDialog = builder.create();
+        alertDialog.show();
+        alertDialog.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
     }
 
     /**
@@ -154,14 +184,14 @@
      * @param context The context of the current application
      */
     private static void dropFile(Uri uri, Context context) {
-      try {
-        if (DocumentsContract.isDocumentUri(context, uri)) {
-          DocumentsContract.deleteDocument(context.getContentResolver(), uri);
-        } else {
-          context.getContentResolver().delete(uri, null, null);
+        try {
+            if (DocumentsContract.isDocumentUri(context, uri)) {
+                DocumentsContract.deleteDocument(context.getContentResolver(), uri);
+            } else {
+                context.getContentResolver().delete(uri, null, null);
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "could not delete document " + uri);
         }
-      } catch (Exception e) {
-        Log.e(TAG, "could not delete document " + uri);
-      }
     }
 }