Merge "Generate client certificate in runtime" into main
diff --git a/android/TerminalApp/Android.bp b/android/TerminalApp/Android.bp
index 09287d8..bf93226 100644
--- a/android/TerminalApp/Android.bp
+++ b/android/TerminalApp/Android.bp
@@ -24,9 +24,7 @@
     platform_apis: true,
     privileged: true,
     optimize: {
-        optimize: true,
-        proguard_flags_files: ["proguard.flags"],
-        shrink_resources: true,
+        enabled: false,
     },
     apex_available: [
         "com.android.virt",
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
index 428fd91..c8f5bab 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
@@ -23,6 +23,7 @@
 import android.content.ServiceConnection;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.ConditionVariable;
 import android.os.FileUtils;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -39,6 +40,7 @@
     private static final String TAG = "LinuxInstaller";
 
     private static final long ESTIMATED_IMG_SIZE_BYTES = FileUtils.parseSize("350MB");
+    static final String EXTRA_AUTO_DOWNLOAD = "auto_download";
 
     private ExecutorService mExecutorService;
     private CheckBox mWaitForWifiCheckbox;
@@ -48,6 +50,7 @@
     private ServiceConnection mInstallerServiceConnection;
     private InstallProgressListener mInstallProgressListener;
     private boolean mInstallRequested;
+    private ConditionVariable mInstallCompleted = new ConditionVariable();
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -72,11 +75,17 @@
                     requestInstall();
                 });
 
+        if (getIntent().getBooleanExtra(EXTRA_AUTO_DOWNLOAD, false)) {
+            Log.i(TAG, "Auto downloading");
+            requestInstall();
+        }
+
         Intent intent = new Intent(this, InstallerService.class);
         mInstallerServiceConnection = new InstallerServiceConnection(this);
         if (!bindService(intent, mInstallerServiceConnection, Context.BIND_AUTO_CREATE)) {
             handleCriticalError(new Exception("Failed to connect to installer service"));
         }
+
     }
 
     @Override
@@ -89,6 +98,10 @@
         super.onDestroy();
     }
 
+    public boolean waitForInstallCompleted(long timeoutMillis) {
+        return mInstallCompleted.block(timeoutMillis);
+    }
+
     public void handleCriticalError(Exception e) {
         if (Build.isDebuggable()) {
             Toast.makeText(
@@ -102,6 +115,9 @@
     }
 
     private void finishWithResult(int resultCode) {
+        if (resultCode == RESULT_OK) {
+            mInstallCompleted.open();
+        }
         setResult(resultCode);
         finish();
     }
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
index 9aa089c..90b5a78 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
@@ -29,6 +29,7 @@
 import android.net.Uri;
 import android.net.http.SslError;
 import android.os.Bundle;
+import android.os.ConditionVariable;
 import android.os.Environment;
 import android.provider.Settings;
 import android.system.ErrnoException;
@@ -84,6 +85,7 @@
     private PrivateKey mPrivateKey;
     private WebView mWebView;
     private AccessibilityManager mAccessibilityManager;
+    private ConditionVariable mBootCompleted = new ConditionVariable();
     private static final int POST_NOTIFICATIONS_PERMISSION_REQUEST_CODE = 101;
     private ActivityResultLauncher<Intent> manageExternalStorageActivityResultLauncher;
 
@@ -233,6 +235,7 @@
                                             findViewById(R.id.boot_progress)
                                                     .setVisibility(View.GONE);
                                             view.setVisibility(View.VISIBLE);
+                                            mBootCompleted.open();
                                         }
                                     }
                                 });
@@ -495,13 +498,16 @@
                                                                         .service_notification_quit_action),
                                                 stopPendingIntent)
                                         .build())
-                        .setDeleteIntent(stopPendingIntent)
                         .build();
 
         android.os.Trace.beginAsyncSection("executeTerminal", 0);
         VmLauncherServices.startVmLauncherService(this, this, notification);
     }
 
+    public boolean waitForBootCompleted(long timeoutMillis) {
+        return mBootCompleted.block(timeoutMillis);
+    }
+
     private long roundUpDiskSize(long diskSize) {
         // Round up every disk_size_round_up_step_size_in_mb MB
         int disk_size_step = getResources().getInteger(
diff --git a/build/apex/Android.bp b/build/apex/Android.bp
index b0ecdde..0bff52e 100644
--- a/build/apex/Android.bp
+++ b/build/apex/Android.bp
@@ -45,12 +45,7 @@
 
     apps: [
         "android.system.virtualmachine.res",
-    ] + select(release_flag("RELEASE_AVF_SUPPORT_CUSTOM_VM_WITH_PARAVIRTUALIZED_DEVICES"), {
-        true: [
-            "VmTerminalApp",
-        ],
-        default: [],
-    }),
+    ],
 
     file_contexts: ":com.android.virt-file_contexts",
 
@@ -165,7 +160,12 @@
     ],
     apps: [
         "EmptyPayloadApp",
-    ],
+    ] + select(release_flag("RELEASE_AVF_SUPPORT_CUSTOM_VM_WITH_PARAVIRTUALIZED_DEVICES"), {
+        true: [
+            "VmTerminalApp",
+        ],
+        default: [],
+    }),
     androidManifest: select(release_flag("RELEASE_AVF_ENABLE_LLPVM_CHANGES"), {
         true: "AndroidManifest.xml",
         default: unset,