diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java b/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java
deleted file mode 100644
index e3d1a67..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2024 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.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.content.Context;
-import android.security.keystore.KeyGenParameterSpec;
-import android.security.keystore.KeyProperties;
-import android.util.Base64;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.X509Certificate;
-
-public class CertificateUtils {
-    private static final String ALIAS = "ttyd";
-
-    public static KeyStore.PrivateKeyEntry createOrGetKey() {
-        try {
-            KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
-            ks.load(null);
-
-            if (!ks.containsAlias(ALIAS)) {
-                Log.d(TAG, "there is no keypair, will generate it");
-                createKey();
-            } else if (!(ks.getCertificate(ALIAS) instanceof X509Certificate)) {
-                Log.d(TAG, "certificate isn't X509Certificate or it is invalid");
-                createKey();
-            } else {
-                try {
-                    ((X509Certificate) ks.getCertificate(ALIAS)).checkValidity();
-                } catch (CertificateExpiredException | CertificateNotYetValidException e) {
-                    Log.d(TAG, "certificate is invalid", e);
-                    createKey();
-                }
-            }
-            return ((KeyStore.PrivateKeyEntry) ks.getEntry(ALIAS, null));
-        } catch (Exception e) {
-            throw new RuntimeException("cannot generate or get key", e);
-        }
-    }
-
-    private static void createKey()
-            throws NoSuchAlgorithmException,
-                    NoSuchProviderException,
-                    InvalidAlgorithmParameterException {
-        KeyPairGenerator kpg =
-                KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
-        kpg.initialize(
-                new KeyGenParameterSpec.Builder(
-                                ALIAS, KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
-                        .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
-                        .build());
-
-        kpg.generateKeyPair();
-    }
-
-    public static void writeCertificateToFile(Context context, Certificate cert) {
-        String certFileName = "ca.crt";
-        File certFile = new File(context.getFilesDir(), certFileName);
-        try (FileOutputStream writer = new FileOutputStream(certFile)) {
-            String cert_begin = "-----BEGIN CERTIFICATE-----\n";
-            String end_cert = "-----END CERTIFICATE-----\n";
-            String output =
-                    cert_begin
-                            + Base64.encodeToString(cert.getEncoded(), Base64.DEFAULT)
-                                    .replaceAll("(.{64})", "$1\n")
-                            + end_cert;
-            writer.write(output.getBytes());
-        } catch (IOException | CertificateEncodingException e) {
-            throw new RuntimeException("cannot write certs", e);
-        }
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.kt b/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.kt
new file mode 100644
index 0000000..53809e5
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2024 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.virtualization.terminal
+
+import android.content.Context
+import android.security.keystore.KeyGenParameterSpec
+import android.security.keystore.KeyProperties
+import android.util.Base64
+import android.util.Log
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.lang.Exception
+import java.lang.RuntimeException
+import java.security.InvalidAlgorithmParameterException
+import java.security.KeyPairGenerator
+import java.security.KeyStore
+import java.security.NoSuchAlgorithmException
+import java.security.NoSuchProviderException
+import java.security.cert.Certificate
+import java.security.cert.CertificateEncodingException
+import java.security.cert.CertificateExpiredException
+import java.security.cert.CertificateNotYetValidException
+import java.security.cert.X509Certificate
+
+object CertificateUtils {
+    private const val ALIAS = "ttyd"
+
+    @JvmStatic
+    fun createOrGetKey(): KeyStore.PrivateKeyEntry {
+        try {
+            val ks = KeyStore.getInstance("AndroidKeyStore")
+            ks.load(null)
+
+            if (!ks.containsAlias(ALIAS)) {
+                Log.d(MainActivity.TAG, "there is no keypair, will generate it")
+                createKey()
+            } else if (ks.getCertificate(ALIAS) !is X509Certificate) {
+                Log.d(MainActivity.TAG, "certificate isn't X509Certificate or it is invalid")
+                createKey()
+            } else {
+                try {
+                    (ks.getCertificate(ALIAS) as X509Certificate).checkValidity()
+                } catch (e: CertificateExpiredException) {
+                    Log.d(MainActivity.TAG, "certificate is invalid", e)
+                    createKey()
+                } catch (e: CertificateNotYetValidException) {
+                    Log.d(MainActivity.TAG, "certificate is invalid", e)
+                    createKey()
+                }
+            }
+            return ks.getEntry(ALIAS, null) as KeyStore.PrivateKeyEntry
+        } catch (e: Exception) {
+            throw RuntimeException("cannot generate or get key", e)
+        }
+    }
+
+    @Throws(
+        NoSuchAlgorithmException::class,
+        NoSuchProviderException::class,
+        InvalidAlgorithmParameterException::class,
+    )
+    private fun createKey() {
+        val kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore")
+        kpg.initialize(
+            KeyGenParameterSpec.Builder(
+                    ALIAS,
+                    KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY,
+                )
+                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+                .build()
+        )
+
+        kpg.generateKeyPair()
+    }
+
+    @JvmStatic
+    fun writeCertificateToFile(context: Context, cert: Certificate) {
+        val certFile = File(context.getFilesDir(), "ca.crt")
+        try {
+            FileOutputStream(certFile).use { writer ->
+                val certBegin = "-----BEGIN CERTIFICATE-----\n"
+                val certEnd = "-----END CERTIFICATE-----\n"
+                val output =
+                    (certBegin +
+                        Base64.encodeToString(cert.encoded, Base64.DEFAULT)
+                            .replace("(.{64})".toRegex(), "$1\n") +
+                        certEnd)
+                writer.write(output.toByteArray())
+            }
+        } catch (e: IOException) {
+            throw RuntimeException("cannot write certs", e)
+        } catch (e: CertificateEncodingException) {
+            throw RuntimeException("cannot write certs", e)
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ErrorActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/ErrorActivity.java
deleted file mode 100644
index 7099f22..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/ErrorActivity.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright 2024 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.virtualization.terminal;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-public class ErrorActivity extends BaseActivity {
-    private static final String EXTRA_CAUSE = "cause";
-
-    public static void start(Context context, Exception e) {
-        Intent intent = new Intent(context, ErrorActivity.class);
-        intent.putExtra(EXTRA_CAUSE, e);
-        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
-        context.startActivity(intent);
-    }
-
-    @Override
-    protected void onCreate(@Nullable Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.activity_error);
-
-        View button = findViewById(R.id.recovery);
-        button.setOnClickListener((event) -> launchRecoveryActivity());
-    }
-
-    @Override
-    protected void onNewIntent(@NonNull Intent intent) {
-        super.onNewIntent(intent);
-        setIntent(intent);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        Intent intent = getIntent();
-        Exception e = intent.getParcelableExtra(EXTRA_CAUSE, Exception.class);
-        TextView cause = findViewById(R.id.cause);
-        if (e != null) {
-            String stackTrace = getStackTrace(e);
-            cause.setText(getString(R.string.error_code, stackTrace));
-        } else {
-            cause.setText(null);
-        }
-    }
-
-    private void launchRecoveryActivity() {
-        Intent intent = new Intent(this, SettingsRecoveryActivity.class);
-        startActivity(intent);
-    }
-
-    private static String getStackTrace(Exception e) {
-        try (StringWriter sWriter = new StringWriter();
-                PrintWriter pWriter = new PrintWriter(sWriter)) {
-            e.printStackTrace(pWriter);
-            return sWriter.toString();
-        } catch (IOException ex) {
-            // This shall never happen
-            throw new RuntimeException(ex);
-        }
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ErrorActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/ErrorActivity.kt
new file mode 100644
index 0000000..f253f86
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ErrorActivity.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2024 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.virtualization.terminal
+
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import android.view.View
+import android.widget.TextView
+import java.io.IOException
+import java.io.PrintWriter
+import java.io.StringWriter
+import java.lang.Exception
+import java.lang.RuntimeException
+
+class ErrorActivity : BaseActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+
+        setContentView(R.layout.activity_error)
+
+        val button = findViewById<View>(R.id.recovery)
+        button.setOnClickListener(View.OnClickListener { _ -> launchRecoveryActivity() })
+    }
+
+    override fun onNewIntent(intent: Intent) {
+        super.onNewIntent(intent)
+        setIntent(intent)
+    }
+
+    override fun onResume() {
+        super.onResume()
+
+        val intent = getIntent()
+        val e = intent.getParcelableExtra<Exception?>(EXTRA_CAUSE, Exception::class.java)
+        val cause = findViewById<TextView>(R.id.cause)
+        cause.text = e?.let { getString(R.string.error_code, getStackTrace(it)) }
+    }
+
+    private fun launchRecoveryActivity() {
+        val intent = Intent(this, SettingsRecoveryActivity::class.java)
+        startActivity(intent)
+    }
+
+    companion object {
+        private const val EXTRA_CAUSE = "cause"
+
+        @JvmStatic
+        fun start(context: Context, e: Exception) {
+            val intent = Intent(context, ErrorActivity::class.java)
+            intent.putExtra(EXTRA_CAUSE, e)
+            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
+            context.startActivity(intent)
+        }
+
+        private fun getStackTrace(e: Exception): String? {
+            try {
+                StringWriter().use { sWriter ->
+                    PrintWriter(sWriter).use { pWriter ->
+                        e.printStackTrace(pWriter)
+                        return sWriter.toString()
+                    }
+                }
+            } catch (ex: IOException) {
+                // This shall never happen
+                throw RuntimeException(ex)
+            }
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java
deleted file mode 100644
index 7f14179..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2024 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.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.os.Build;
-import android.os.Environment;
-import android.util.Log;
-
-import org.apache.commons.compress.archivers.ArchiveEntry;
-import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
-import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-import java.util.Arrays;
-import java.util.function.Function;
-
-/**
- * ImageArchive models the archive file (images.tar.gz) where VM payload files are in. This class
- * provides methods for handling the archive file, most importantly installing it.
- */
-class ImageArchive {
-    private static final String DIR_IN_SDCARD = "linux";
-    private static final String ARCHIVE_NAME = "images.tar.gz";
-    private static final String BUILD_TAG = "latest"; // TODO: use actual tag name
-    private static final String HOST_URL = "https://dl.google.com/android/ferrochrome/" + BUILD_TAG;
-
-    // Only one can be non-null
-    private final URL mUrl;
-    private final Path mPath;
-
-    private ImageArchive(URL url) {
-        mUrl = url;
-        mPath = null;
-    }
-
-    private ImageArchive(Path path) {
-        mUrl = null;
-        mPath = path;
-    }
-
-    public static Path getSdcardPathForTesting() {
-        return Environment.getExternalStoragePublicDirectory(DIR_IN_SDCARD).toPath();
-    }
-
-    /** Creates ImageArchive which is located in the sdcard. This archive is for testing only. */
-    public static ImageArchive fromSdCard() {
-        Path file = getSdcardPathForTesting().resolve(ARCHIVE_NAME);
-        return new ImageArchive(file);
-    }
-
-    /** Creates ImageArchive which is hosted in the Google server. This is the official archive. */
-    public static ImageArchive fromInternet() {
-        String arch = Arrays.asList(Build.SUPPORTED_ABIS).contains("x86_64") ? "x86_64" : "aarch64";
-        try {
-            URL url = new URL(HOST_URL + "/" + arch + "/" + ARCHIVE_NAME);
-            return new ImageArchive(url);
-        } catch (MalformedURLException e) {
-            // cannot happen
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Creates ImageArchive from either SdCard or Internet. SdCard is used only when the build is
-     * debuggable and the file actually exists.
-     */
-    public static ImageArchive getDefault() {
-        ImageArchive archive = fromSdCard();
-        if (Build.isDebuggable() && archive.exists()) {
-            return archive;
-        } else {
-            return fromInternet();
-        }
-    }
-
-    /** Tests if ImageArchive exists on the medium. */
-    public boolean exists() {
-        if (mPath != null) {
-            return Files.exists(mPath);
-        } else {
-            // TODO
-            return true;
-        }
-    }
-
-    /** Returns size of the archive in bytes */
-    public long getSize() throws IOException {
-        if (!exists()) {
-            throw new IllegalStateException("Cannot get size of non existing archive");
-        }
-        if (mPath != null) {
-            return Files.size(mPath);
-        } else {
-            HttpURLConnection conn = null;
-            try {
-                conn = (HttpURLConnection) mUrl.openConnection();
-                conn.setRequestMethod("HEAD");
-                conn.getInputStream();
-                return conn.getContentLength();
-            } finally {
-                if (conn != null) {
-                    conn.disconnect();
-                }
-            }
-        }
-    }
-
-    private InputStream getInputStream(Function<InputStream, InputStream> filter)
-            throws IOException {
-        InputStream is = mPath != null ? new FileInputStream(mPath.toFile()) : mUrl.openStream();
-        BufferedInputStream bufStream = new BufferedInputStream(is);
-        return filter == null ? bufStream : filter.apply(bufStream);
-    }
-
-    /**
-     * Installs this ImageArchive to a directory pointed by path. filter can be supplied to provide
-     * an additional input stream which will be used during the installation.
-     */
-    public void installTo(Path dir, Function<InputStream, InputStream> filter) throws IOException {
-        String source = mPath != null ? mPath.toString() : mUrl.toString();
-        Log.d(TAG, "Installing. source: " + source + ", destination: " + dir.toString());
-        try (InputStream stream = getInputStream(filter);
-                GzipCompressorInputStream gzStream = new GzipCompressorInputStream(stream);
-                TarArchiveInputStream tarStream = new TarArchiveInputStream(gzStream)) {
-
-            Files.createDirectories(dir);
-            ArchiveEntry entry;
-            while ((entry = tarStream.getNextEntry()) != null) {
-                Path to = dir.resolve(entry.getName());
-                if (Files.isDirectory(to)) {
-                    Files.createDirectories(to);
-                    continue;
-                }
-                Files.copy(tarStream, to, StandardCopyOption.REPLACE_EXISTING);
-            }
-        }
-        commitInstallationAt(dir);
-    }
-
-    private void commitInstallationAt(Path dir) throws IOException {
-        // To save storage, delete the source archive on the disk.
-        if (mPath != null) {
-            Files.deleteIfExists(mPath);
-        }
-
-        // Mark the completion
-        Path marker = dir.resolve(InstalledImage.MARKER_FILENAME);
-        Files.createFile(marker);
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
new file mode 100644
index 0000000..31c9a91
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2024 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.virtualization.terminal
+
+import android.os.Build
+import android.os.Environment
+import android.util.Log
+import com.android.virtualization.terminal.MainActivity.TAG
+import java.io.BufferedInputStream
+import java.io.FileInputStream
+import java.io.IOException
+import java.io.InputStream
+import java.lang.RuntimeException
+import java.net.HttpURLConnection
+import java.net.MalformedURLException
+import java.net.URL
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.StandardCopyOption
+import java.util.function.Function
+import org.apache.commons.compress.archivers.ArchiveEntry
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
+
+/**
+ * ImageArchive models the archive file (images.tar.gz) where VM payload files are in. This class
+ * provides methods for handling the archive file, most importantly installing it.
+ */
+internal class ImageArchive {
+    // Only one can be non-null
+    private sealed class Source<out A, out B>
+
+    private data class UrlSource<out Url>(val value: Url) : Source<Url, Nothing>()
+
+    private data class PathSource<out Path>(val value: Path) : Source<Nothing, Path>()
+
+    private val source: Source<URL, Path>
+
+    private constructor(url: URL) {
+        source = UrlSource(url)
+    }
+
+    private constructor(path: Path) {
+        source = PathSource(path)
+    }
+
+    /** Tests if ImageArchive exists on the medium. */
+    fun exists(): Boolean {
+        return when (source) {
+            is UrlSource -> true
+            is PathSource -> Files.exists(source.value)
+        }
+    }
+
+    /** Returns size of the archive in bytes */
+    @Throws(IOException::class)
+    fun getSize(): Long {
+        check(exists()) { "Cannot get size of non existing archive" }
+        return when (source) {
+            is UrlSource -> {
+                val conn = source.value.openConnection() as HttpURLConnection
+                try {
+                    conn.requestMethod = "HEAD"
+                    conn.getInputStream()
+                    return conn.contentLength.toLong()
+                } finally {
+                    conn.disconnect()
+                }
+            }
+            is PathSource -> Files.size(source.value)
+        }
+    }
+
+    @Throws(IOException::class)
+    private fun getInputStream(filter: Function<InputStream, InputStream>?): InputStream? {
+        val bufStream =
+            BufferedInputStream(
+                when (source) {
+                    is UrlSource -> source.value.openStream()
+                    is PathSource -> FileInputStream(source.value.toFile())
+                }
+            )
+        return filter?.apply(bufStream) ?: bufStream
+    }
+
+    /**
+     * Installs this ImageArchive to a directory pointed by path. filter can be supplied to provide
+     * an additional input stream which will be used during the installation.
+     */
+    @Throws(IOException::class)
+    fun installTo(dir: Path, filter: Function<InputStream, InputStream>?) {
+        val source =
+            when (source) {
+                is PathSource -> source.value.toString()
+                is UrlSource -> source.value.toString()
+            }
+        Log.d(TAG, "Installing. source: $source, destination: $dir")
+        TarArchiveInputStream(GzipCompressorInputStream(getInputStream(filter))).use { tarStream ->
+            Files.createDirectories(dir)
+            var entry: ArchiveEntry?
+            while ((tarStream.nextEntry.also { entry = it }) != null) {
+                val to = dir.resolve(entry!!.getName())
+                if (Files.isDirectory(to)) {
+                    Files.createDirectories(to)
+                    continue
+                }
+                Files.copy(tarStream, to, StandardCopyOption.REPLACE_EXISTING)
+            }
+        }
+        commitInstallationAt(dir)
+    }
+
+    @Throws(IOException::class)
+    private fun commitInstallationAt(dir: Path) {
+        // To save storage, delete the source archive on the disk.
+        if (source is PathSource) {
+            Files.deleteIfExists(source.value)
+        }
+
+        // Mark the completion
+        val marker = dir.resolve(InstalledImage.MARKER_FILENAME)
+        Files.createFile(marker)
+    }
+
+    companion object {
+        private const val DIR_IN_SDCARD = "linux"
+        private const val ARCHIVE_NAME = "images.tar.gz"
+        private const val BUILD_TAG = "latest" // TODO: use actual tag name
+        private const val HOST_URL = "https://dl.google.com/android/ferrochrome/$BUILD_TAG"
+
+        @JvmStatic
+        fun getSdcardPathForTesting(): Path {
+            return Environment.getExternalStoragePublicDirectory(DIR_IN_SDCARD).toPath()
+        }
+
+        /**
+         * Creates ImageArchive which is located in the sdcard. This archive is for testing only.
+         */
+        @JvmStatic
+        fun fromSdCard(): ImageArchive {
+            return ImageArchive(getSdcardPathForTesting().resolve(ARCHIVE_NAME))
+        }
+
+        /**
+         * Creates ImageArchive which is hosted in the Google server. This is the official archive.
+         */
+        @JvmStatic
+        fun fromInternet(): ImageArchive {
+            val arch =
+                if (listOf<String?>(*Build.SUPPORTED_ABIS).contains("x86_64")) "x86_64"
+                else "aarch64"
+            try {
+                return ImageArchive(URL("$HOST_URL/$arch/$ARCHIVE_NAME"))
+            } catch (e: MalformedURLException) {
+                // cannot happen
+                throw RuntimeException(e)
+            }
+        }
+
+        /**
+         * Creates ImageArchive from either SdCard or Internet. SdCard is used only when the build
+         * is debuggable and the file actually exists.
+         */
+        @JvmStatic
+        fun getDefault(): ImageArchive {
+            val archive = fromSdCard()
+            return if (Build.isDebuggable() && archive.exists()) {
+                archive
+            } else {
+                fromInternet()
+            }
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.java
deleted file mode 100644
index 318f49a..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2024 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.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.content.Context;
-import android.os.FileUtils;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.util.Log;
-
-import java.io.BufferedReader;
-import java.io.FileDescriptor;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardCopyOption;
-
-/** Collection of files that consist of a VM image. */
-class InstalledImage {
-    private static final String INSTALL_DIRNAME = "linux";
-    private static final String ROOTFS_FILENAME = "root_part";
-    private static final String BACKUP_FILENAME = "root_part_backup";
-    private static final String CONFIG_FILENAME = "vm_config.json";
-    private static final String BUILD_ID_FILENAME = "build_id";
-    static final String MARKER_FILENAME = "completed";
-
-    public static final long RESIZE_STEP_BYTES = 4 << 20; // 4 MiB
-
-    private final Path mDir;
-    private final Path mRootPartition;
-    private final Path mBackup;
-    private final Path mConfig;
-    private final Path mMarker;
-    private String mBuildId;
-
-    /** Returns InstalledImage for a given app context */
-    public static InstalledImage getDefault(Context context) {
-        Path installDir = context.getFilesDir().toPath().resolve(INSTALL_DIRNAME);
-        return new InstalledImage(installDir);
-    }
-
-    private InstalledImage(Path dir) {
-        mDir = dir;
-        mRootPartition = dir.resolve(ROOTFS_FILENAME);
-        mBackup = dir.resolve(BACKUP_FILENAME);
-        mConfig = dir.resolve(CONFIG_FILENAME);
-        mMarker = dir.resolve(MARKER_FILENAME);
-    }
-
-    public Path getInstallDir() {
-        return mDir;
-    }
-
-    /** Tests if this InstalledImage is actually installed. */
-    public boolean isInstalled() {
-        return Files.exists(mMarker);
-    }
-
-    /** Fully understalls this InstalledImage by deleting everything. */
-    public void uninstallFully() throws IOException {
-        FileUtils.deleteContentsAndDir(mDir.toFile());
-    }
-
-    /** Returns the path to the VM config file. */
-    public Path getConfigPath() {
-        return mConfig;
-    }
-
-    /** Returns the build ID of the installed image */
-    public String getBuildId() {
-        if (mBuildId == null) {
-            mBuildId = readBuildId();
-        }
-        return mBuildId;
-    }
-
-    private String readBuildId() {
-        Path file = mDir.resolve(BUILD_ID_FILENAME);
-        if (!Files.exists(file)) {
-            return "<no build id>";
-        }
-        try (BufferedReader r = new BufferedReader(new FileReader(file.toFile()))) {
-            return r.readLine();
-        } catch (IOException e) {
-            throw new RuntimeException("Failed to read build ID", e);
-        }
-    }
-
-    public Path uninstallAndBackup() throws IOException {
-        Files.delete(mMarker);
-        Files.move(mRootPartition, mBackup, StandardCopyOption.REPLACE_EXISTING);
-        return mBackup;
-    }
-
-    public Path getBackupFile() {
-        return mBackup;
-    }
-
-    public boolean hasBackup() {
-        return Files.exists(mBackup);
-    }
-
-    public void deleteBackup() throws IOException {
-        Files.deleteIfExists(mBackup);
-    }
-
-    public long getSize() throws IOException {
-        return Files.size(mRootPartition);
-    }
-
-    public long getSmallestSizePossible() throws IOException {
-        runE2fsck(mRootPartition);
-        String p = mRootPartition.toAbsolutePath().toString();
-        String result = runCommand("/system/bin/resize2fs", "-P", p);
-        // The return value is the number of 4k block
-        try {
-            long minSize =
-                    Long.parseLong(result.lines().toArray(String[]::new)[1].substring(42))
-                            * 4
-                            * 1024;
-            return roundUp(minSize);
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "Failed to parse min size, p=" + p + ", result=" + result);
-            throw new IOException(e);
-        }
-    }
-
-    public long resize(long desiredSize) throws IOException {
-        desiredSize = roundUp(desiredSize);
-        final long curSize = getSize();
-
-        if (desiredSize == curSize) {
-            return desiredSize;
-        }
-
-        runE2fsck(mRootPartition);
-        if (desiredSize > curSize) {
-            allocateSpace(mRootPartition, desiredSize);
-        }
-        resizeFilesystem(mRootPartition, desiredSize);
-        return getSize();
-    }
-
-    private static void allocateSpace(Path path, long sizeInBytes) throws IOException {
-        try {
-            RandomAccessFile raf = new RandomAccessFile(path.toFile(), "rw");
-            FileDescriptor fd = raf.getFD();
-            Os.posix_fallocate(fd, 0, sizeInBytes);
-            raf.close();
-            Log.d(TAG, "Allocated space to: " + sizeInBytes + " bytes");
-        } catch (ErrnoException e) {
-            Log.e(TAG, "Failed to allocate space", e);
-            throw new IOException("Failed to allocate space", e);
-        }
-    }
-
-    private static void runE2fsck(Path path) throws IOException {
-        String p = path.toAbsolutePath().toString();
-        runCommand("/system/bin/e2fsck", "-y", "-f", p);
-        Log.d(TAG, "e2fsck completed: " + path);
-    }
-
-    private static void resizeFilesystem(Path path, long sizeInBytes) throws IOException {
-        long sizeInMB = sizeInBytes / (1024 * 1024);
-        if (sizeInMB == 0) {
-            Log.e(TAG, "Invalid size: " + sizeInBytes + " bytes");
-            throw new IllegalArgumentException("Size cannot be zero MB");
-        }
-        String sizeArg = sizeInMB + "M";
-        String p = path.toAbsolutePath().toString();
-        runCommand("/system/bin/resize2fs", p, sizeArg);
-        Log.d(TAG, "resize2fs completed: " + path + ", size: " + sizeArg);
-    }
-
-    private static String runCommand(String... command) throws IOException {
-        try {
-            Process process = new ProcessBuilder(command).redirectErrorStream(true).start();
-            process.waitFor();
-            String result = new String(process.getInputStream().readAllBytes());
-            if (process.exitValue() != 0) {
-                Log.w(TAG, "Process returned with error, command=" + String.join(" ", command)
-                    + ", exitValue=" + process.exitValue() + ", result=" + result);
-            }
-            return result;
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw new IOException("Command interrupted", e);
-        }
-    }
-
-    private static long roundUp(long bytes) {
-        // Round up every diskSizeStep MB
-        return (long) Math.ceil(((double) bytes) / RESIZE_STEP_BYTES) * RESIZE_STEP_BYTES;
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.kt b/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.kt
new file mode 100644
index 0000000..e52f996
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstalledImage.kt
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2024 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.virtualization.terminal
+
+import android.content.Context
+import android.os.FileUtils
+import android.system.ErrnoException
+import android.system.Os
+import android.util.Log
+import com.android.virtualization.terminal.MainActivity.TAG
+import java.io.BufferedReader
+import java.io.FileReader
+import java.io.IOException
+import java.io.RandomAccessFile
+import java.lang.IllegalArgumentException
+import java.lang.NumberFormatException
+import java.lang.RuntimeException
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.StandardCopyOption
+import kotlin.math.ceil
+
+/** Collection of files that consist of a VM image. */
+internal class InstalledImage private constructor(val installDir: Path) {
+    private val rootPartition: Path = installDir.resolve(ROOTFS_FILENAME)
+    val backupFile: Path = installDir.resolve(BACKUP_FILENAME)
+
+    /** The path to the VM config file. */
+    val configPath: Path = installDir.resolve(CONFIG_FILENAME)
+    private val marker: Path = installDir.resolve(MARKER_FILENAME)
+    /** The build ID of the installed image */
+    val buildId: String by lazy { readBuildId() }
+
+    /** Tests if this InstalledImage is actually installed. */
+    fun isInstalled(): Boolean {
+        return Files.exists(marker)
+    }
+
+    /** Fully uninstall this InstalledImage by deleting everything. */
+    @Throws(IOException::class)
+    fun uninstallFully() {
+        FileUtils.deleteContentsAndDir(installDir.toFile())
+    }
+
+    private fun readBuildId(): String {
+        val file = installDir.resolve(BUILD_ID_FILENAME)
+        if (!Files.exists(file)) {
+            return "<no build id>"
+        }
+        try {
+            BufferedReader(FileReader(file.toFile())).use { r ->
+                return r.readLine()
+            }
+        } catch (e: IOException) {
+            throw RuntimeException("Failed to read build ID", e)
+        }
+    }
+
+    @Throws(IOException::class)
+    fun uninstallAndBackup(): Path {
+        Files.delete(marker)
+        Files.move(rootPartition, backupFile, StandardCopyOption.REPLACE_EXISTING)
+        return backupFile
+    }
+
+    fun hasBackup(): Boolean {
+        return Files.exists(backupFile)
+    }
+
+    @Throws(IOException::class)
+    fun deleteBackup() {
+        Files.deleteIfExists(backupFile)
+    }
+
+    @Throws(IOException::class)
+    fun getSize(): Long {
+        return Files.size(rootPartition)
+    }
+
+    @Throws(IOException::class)
+    fun getSmallestSizePossible(): Long {
+        runE2fsck(rootPartition)
+        val p: String = rootPartition.toAbsolutePath().toString()
+        val result = runCommand("/system/bin/resize2fs", "-P", p)
+        // The return value is the number of 4k block
+        return try {
+            roundUp(result.lines().first().substring(42).toLong() * 4 * 1024)
+        } catch (e: NumberFormatException) {
+            Log.e(TAG, "Failed to parse min size, p=$p, result=$result")
+            throw IOException(e)
+        }
+    }
+
+    @Throws(IOException::class)
+    fun resize(desiredSize: Long): Long {
+        val roundedUpDesiredSize = roundUp(desiredSize)
+        val curSize = getSize()
+
+        if (roundedUpDesiredSize == curSize) {
+            return roundedUpDesiredSize
+        }
+
+        runE2fsck(rootPartition)
+        if (roundedUpDesiredSize > curSize) {
+            allocateSpace(rootPartition, roundedUpDesiredSize)
+        }
+        resizeFilesystem(rootPartition, roundedUpDesiredSize)
+        return getSize()
+    }
+
+    companion object {
+        private const val INSTALL_DIRNAME = "linux"
+        private const val ROOTFS_FILENAME = "root_part"
+        private const val BACKUP_FILENAME = "root_part_backup"
+        private const val CONFIG_FILENAME = "vm_config.json"
+        private const val BUILD_ID_FILENAME = "build_id"
+        const val MARKER_FILENAME: String = "completed"
+
+        const val RESIZE_STEP_BYTES: Long = 4 shl 20 // 4 MiB
+
+        /** Returns InstalledImage for a given app context */
+        @JvmStatic
+        fun getDefault(context: Context): InstalledImage {
+            val installDir = context.getFilesDir().toPath().resolve(INSTALL_DIRNAME)
+            return InstalledImage(installDir)
+        }
+
+        @Throws(IOException::class)
+        private fun allocateSpace(path: Path, sizeInBytes: Long) {
+            try {
+                val raf = RandomAccessFile(path.toFile(), "rw")
+                val fd = raf.fd
+                Os.posix_fallocate(fd, 0, sizeInBytes)
+                raf.close()
+                Log.d(TAG, "Allocated space to: $sizeInBytes bytes")
+            } catch (e: ErrnoException) {
+                Log.e(TAG, "Failed to allocate space", e)
+                throw IOException("Failed to allocate space", e)
+            }
+        }
+
+        @Throws(IOException::class)
+        private fun runE2fsck(path: Path) {
+            val p: String = path.toAbsolutePath().toString()
+            runCommand("/system/bin/e2fsck", "-y", "-f", p)
+            Log.d(TAG, "e2fsck completed: $path")
+        }
+
+        @Throws(IOException::class)
+        private fun resizeFilesystem(path: Path, sizeInBytes: Long) {
+            val sizeInMB = sizeInBytes / (1024 * 1024)
+            if (sizeInMB == 0L) {
+                Log.e(TAG, "Invalid size: $sizeInBytes bytes")
+                throw IllegalArgumentException("Size cannot be zero MB")
+            }
+            val sizeArg = sizeInMB.toString() + "M"
+            val p: String = path.toAbsolutePath().toString()
+            runCommand("/system/bin/resize2fs", p, sizeArg)
+            Log.d(TAG, "resize2fs completed: $path, size: $sizeArg")
+        }
+
+        @Throws(IOException::class)
+        private fun runCommand(vararg command: String): String {
+            try {
+                val process = ProcessBuilder(*command).redirectErrorStream(true).start()
+                process.waitFor()
+                val result = String(process.inputStream.readAllBytes())
+                if (process.exitValue() != 0) {
+                    Log.w(
+                        TAG,
+                        "Process returned with error, command=${listOf(*command).joinToString(" ")}," +
+                            "exitValue=${process.exitValue()}, result=$result",
+                    )
+                }
+                return result
+            } catch (e: InterruptedException) {
+                Thread.currentThread().interrupt()
+                throw IOException("Command interrupted", e)
+            }
+        }
+
+        private fun roundUp(bytes: Long): Long {
+            // Round up every diskSizeStep MB
+            return ceil((bytes.toDouble()) / RESIZE_STEP_BYTES).toLong() * RESIZE_STEP_BYTES
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Logger.java b/android/TerminalApp/java/com/android/virtualization/terminal/Logger.java
deleted file mode 100644
index 2c0149e..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/Logger.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2024 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.virtualization.terminal;
-
-import android.system.virtualmachine.VirtualMachine;
-import android.system.virtualmachine.VirtualMachineConfig;
-import android.system.virtualmachine.VirtualMachineException;
-import android.util.Log;
-
-import libcore.io.Streams;
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.util.concurrent.ExecutorService;
-
-/**
- * Forwards VM's console output to a file on the Android side, and VM's log output to Android logd.
- */
-class Logger {
-    private Logger() {}
-
-    static void setup(VirtualMachine vm, Path path, ExecutorService executor) {
-        if (vm.getConfig().getDebugLevel() != VirtualMachineConfig.DEBUG_LEVEL_FULL) {
-            return;
-        }
-
-        try {
-            InputStream console = vm.getConsoleOutput();
-            OutputStream file = Files.newOutputStream(path, StandardOpenOption.CREATE);
-            executor.submit(() -> Streams.copy(console, new LineBufferedOutputStream(file)));
-
-            InputStream log = vm.getLogOutput();
-            executor.submit(() -> writeToLogd(log, vm.getName()));
-        } catch (VirtualMachineException | IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static boolean writeToLogd(InputStream input, String vmName) throws IOException {
-        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
-        String line;
-        while ((line = reader.readLine()) != null && !Thread.interrupted()) {
-            Log.d(vmName, line);
-        }
-        // TODO: find out why javac complains when the return type of this method is void. It
-        // (incorrectly?) thinks that IOException should be caught inside the lambda.
-        return true;
-    }
-
-    private static class LineBufferedOutputStream extends BufferedOutputStream {
-        LineBufferedOutputStream(OutputStream out) {
-            super(out);
-        }
-
-        @Override
-        public void write(byte[] buf, int off, int len) throws IOException {
-            super.write(buf, off, len);
-            for (int i = 0; i < len; ++i) {
-                if (buf[off + i] == '\n') {
-                    flush();
-                    break;
-                }
-            }
-        }
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Logger.kt b/android/TerminalApp/java/com/android/virtualization/terminal/Logger.kt
new file mode 100644
index 0000000..3a273ec
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/Logger.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 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.virtualization.terminal
+
+import android.system.virtualmachine.VirtualMachine
+import android.system.virtualmachine.VirtualMachineConfig
+import android.system.virtualmachine.VirtualMachineException
+import android.util.Log
+import com.android.virtualization.terminal.Logger.LineBufferedOutputStream
+import java.io.BufferedOutputStream
+import java.io.BufferedReader
+import java.io.IOException
+import java.io.InputStream
+import java.io.InputStreamReader
+import java.io.OutputStream
+import java.lang.RuntimeException
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.StandardOpenOption
+import java.util.concurrent.ExecutorService
+import libcore.io.Streams
+
+/**
+ * Forwards VM's console output to a file on the Android side, and VM's log output to Android logd.
+ */
+internal object Logger {
+    @JvmStatic
+    fun setup(vm: VirtualMachine, path: Path, executor: ExecutorService) {
+        if (vm.config.debugLevel != VirtualMachineConfig.DEBUG_LEVEL_FULL) {
+            return
+        }
+
+        try {
+            val console = vm.getConsoleOutput()
+            val file = Files.newOutputStream(path, StandardOpenOption.CREATE)
+            executor.submit<Int?> {
+                console.use { console ->
+                    LineBufferedOutputStream(file).use { fileOutput ->
+                        Streams.copy(console, fileOutput)
+                    }
+                }
+            }
+
+            val log = vm.getLogOutput()
+            executor.submit<Unit> { log.use { writeToLogd(it, vm.name) } }
+        } catch (e: VirtualMachineException) {
+            throw RuntimeException(e)
+        } catch (e: IOException) {
+            throw RuntimeException(e)
+        }
+    }
+
+    @Throws(IOException::class)
+    private fun writeToLogd(input: InputStream?, vmName: String?) {
+        val reader = BufferedReader(InputStreamReader(input))
+        reader
+            .useLines { lines -> lines.takeWhile { !Thread.interrupted() } }
+            .forEach { Log.d(vmName, it) }
+    }
+
+    private class LineBufferedOutputStream(out: OutputStream?) : BufferedOutputStream(out) {
+        @Throws(IOException::class)
+        override fun write(buf: ByteArray, off: Int, len: Int) {
+            super.write(buf, off, len)
+            (0 until len).firstOrNull { buf[off + it] == '\n'.code.toByte() }?.let { flush() }
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java
deleted file mode 100644
index 0d70ab9..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2024 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.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.app.Notification;
-import android.app.Notification.Action;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
-
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
-
-/**
- * PortNotifier is responsible for posting a notification when a new open port is detected. User can
- * enable or disable forwarding of the port in notification panel.
- */
-class PortNotifier {
-    private static final String ACTION_PORT_FORWARDING = "android.virtualization.PORT_FORWARDING";
-    private static final String KEY_PORT = "port";
-    private static final String KEY_ENABLED = "enabled";
-
-    private final Context mContext;
-    private final NotificationManager mNotificationManager;
-    private final BroadcastReceiver mReceiver;
-    private final PortsStateManager mPortsStateManager;
-    private final PortsStateManager.Listener mPortsStateListener;
-
-    public PortNotifier(Context context) {
-        mContext = context;
-        mNotificationManager = mContext.getSystemService(NotificationManager.class);
-        mReceiver = new PortForwardingRequestReceiver();
-
-        mPortsStateManager = PortsStateManager.getInstance(mContext);
-        mPortsStateListener =
-                new PortsStateManager.Listener() {
-                    @Override
-                    public void onPortsStateUpdated(
-                            Set<Integer> oldActivePorts, Set<Integer> newActivePorts) {
-                        Set<Integer> union = new HashSet<>(oldActivePorts);
-                        union.addAll(newActivePorts);
-                        for (int port : union) {
-                            if (!oldActivePorts.contains(port)) {
-                                showNotificationFor(port);
-                            } else if (!newActivePorts.contains(port)) {
-                                discardNotificationFor(port);
-                            }
-                        }
-                    }
-                };
-        mPortsStateManager.registerListener(mPortsStateListener);
-
-        IntentFilter intentFilter = new IntentFilter(ACTION_PORT_FORWARDING);
-        mContext.registerReceiver(mReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
-    }
-
-    public void stop() {
-        mPortsStateManager.unregisterListener(mPortsStateListener);
-        mContext.unregisterReceiver(mReceiver);
-    }
-
-    private String getString(int resId) {
-        return mContext.getString(resId);
-    }
-
-    private PendingIntent getPendingIntentFor(int port, boolean enabled) {
-        Intent intent = new Intent(ACTION_PORT_FORWARDING);
-        intent.setPackage(mContext.getPackageName());
-        intent.setIdentifier(String.format(Locale.ROOT, "%d_%b", port, enabled));
-        intent.putExtra(KEY_PORT, port);
-        intent.putExtra(KEY_ENABLED, enabled);
-        return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE);
-    }
-
-    private void showNotificationFor(int port) {
-        Intent tapIntent = new Intent(mContext, SettingsPortForwardingActivity.class);
-        tapIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        PendingIntent tapPendingIntent =
-                PendingIntent.getActivity(mContext, 0, tapIntent, PendingIntent.FLAG_IMMUTABLE);
-
-        String title = getString(R.string.settings_port_forwarding_notification_title);
-        String content =
-                mContext.getString(R.string.settings_port_forwarding_notification_content, port);
-        String acceptText = getString(R.string.settings_port_forwarding_notification_accept);
-        String denyText = getString(R.string.settings_port_forwarding_notification_deny);
-        Icon icon = Icon.createWithResource(mContext, R.drawable.ic_launcher_foreground);
-
-        Action acceptAction =
-                new Action.Builder(icon, acceptText, getPendingIntentFor(port, true /* enabled */))
-                        .build();
-        Action denyAction =
-                new Action.Builder(icon, denyText, getPendingIntentFor(port, false /* enabled */))
-                        .build();
-        Notification notification =
-                new Notification.Builder(mContext, mContext.getPackageName())
-                        .setSmallIcon(R.drawable.ic_launcher_foreground)
-                        .setContentTitle(title)
-                        .setContentText(content)
-                        .setContentIntent(tapPendingIntent)
-                        .addAction(acceptAction)
-                        .addAction(denyAction)
-                        .build();
-        mNotificationManager.notify(TAG, port, notification);
-    }
-
-    private void discardNotificationFor(int port) {
-        mNotificationManager.cancel(TAG, port);
-    }
-
-    private final class PortForwardingRequestReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (ACTION_PORT_FORWARDING.equals(intent.getAction())) {
-                performActionPortForwarding(context, intent);
-            }
-        }
-
-        private void performActionPortForwarding(Context context, Intent intent) {
-            int port = intent.getIntExtra(KEY_PORT, 0);
-            boolean enabled = intent.getBooleanExtra(KEY_ENABLED, false);
-            mPortsStateManager.updateEnabledPort(port, enabled);
-            discardNotificationFor(port);
-        }
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt
new file mode 100644
index 0000000..ed6e02e
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2024 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.virtualization.terminal
+
+import android.app.Notification
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.graphics.drawable.Icon
+import java.util.HashSet
+import java.util.Locale
+
+/**
+ * PortNotifier is responsible for posting a notification when a new open port is detected. User can
+ * enable or disable forwarding of the port in notification panel.
+ */
+internal class PortNotifier(val context: Context) {
+    private val notificationManager: NotificationManager =
+        context.getSystemService<NotificationManager?>(NotificationManager::class.java)
+    private val receiver: BroadcastReceiver =
+        PortForwardingRequestReceiver().also {
+            val intentFilter = IntentFilter(ACTION_PORT_FORWARDING)
+            context.registerReceiver(it, intentFilter, Context.RECEIVER_NOT_EXPORTED)
+        }
+    private val portsStateListener: PortsStateManager.Listener =
+        object : PortsStateManager.Listener {
+            override fun onPortsStateUpdated(oldActivePorts: Set<Int>, newActivePorts: Set<Int>) {
+                val union: MutableSet<Int> = HashSet<Int>(oldActivePorts)
+                union.addAll(newActivePorts)
+                for (port in union) {
+                    if (!oldActivePorts.contains(port)) {
+                        showNotificationFor(port)
+                    } else if (!newActivePorts.contains(port)) {
+                        discardNotificationFor(port)
+                    }
+                }
+            }
+        }
+    private val portsStateManager: PortsStateManager =
+        PortsStateManager.getInstance(context).also { it.registerListener(portsStateListener) }
+
+    fun stop() {
+        portsStateManager.unregisterListener(portsStateListener)
+        context.unregisterReceiver(receiver)
+    }
+
+    private fun getString(resId: Int): String {
+        return context.getString(resId)
+    }
+
+    private fun getPendingIntentFor(port: Int, enabled: Boolean): PendingIntent? {
+        val intent = Intent(ACTION_PORT_FORWARDING)
+        intent.setPackage(context.getPackageName())
+        intent.setIdentifier(String.format(Locale.ROOT, "%d_%b", port, enabled))
+        intent.putExtra(KEY_PORT, port)
+        intent.putExtra(KEY_ENABLED, enabled)
+        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+    }
+
+    private fun showNotificationFor(port: Int) {
+        val tapIntent = Intent(context, SettingsPortForwardingActivity::class.java)
+        tapIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP)
+        val tapPendingIntent =
+            PendingIntent.getActivity(context, 0, tapIntent, PendingIntent.FLAG_IMMUTABLE)
+
+        val title = getString(R.string.settings_port_forwarding_notification_title)
+        val content =
+            context.getString(R.string.settings_port_forwarding_notification_content, port)
+        val acceptText = getString(R.string.settings_port_forwarding_notification_accept)
+        val denyText = getString(R.string.settings_port_forwarding_notification_deny)
+        val icon = Icon.createWithResource(context, R.drawable.ic_launcher_foreground)
+
+        val acceptAction: Notification.Action =
+            Notification.Action.Builder(
+                    icon,
+                    acceptText,
+                    getPendingIntentFor(port, true /* enabled */),
+                )
+                .build()
+        val denyAction: Notification.Action =
+            Notification.Action.Builder(
+                    icon,
+                    denyText,
+                    getPendingIntentFor(port, false /* enabled */),
+                )
+                .build()
+        val notification: Notification =
+            Notification.Builder(context, context.getPackageName())
+                .setSmallIcon(R.drawable.ic_launcher_foreground)
+                .setContentTitle(title)
+                .setContentText(content)
+                .setContentIntent(tapPendingIntent)
+                .addAction(acceptAction)
+                .addAction(denyAction)
+                .build()
+        notificationManager.notify(MainActivity.TAG, port, notification)
+    }
+
+    private fun discardNotificationFor(port: Int) {
+        notificationManager.cancel(MainActivity.TAG, port)
+    }
+
+    private inner class PortForwardingRequestReceiver : BroadcastReceiver() {
+        override fun onReceive(context: Context?, intent: Intent) {
+            if (ACTION_PORT_FORWARDING == intent.action) {
+                performActionPortForwarding(intent)
+            }
+        }
+
+        fun performActionPortForwarding(intent: Intent) {
+            val port = intent.getIntExtra(KEY_PORT, 0)
+            val enabled = intent.getBooleanExtra(KEY_ENABLED, false)
+            portsStateManager.updateEnabledPort(port, enabled)
+            discardNotificationFor(port)
+        }
+    }
+
+    companion object {
+        private const val ACTION_PORT_FORWARDING = "android.virtualization.PORT_FORWARDING"
+        private const val KEY_PORT = "port"
+        private const val KEY_ENABLED = "enabled"
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.java b/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.java
deleted file mode 100644
index 5321d89..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2024 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.virtualization.terminal;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * PortsStateManager is responsible for communicating with shared preferences and managing state of
- * ports.
- */
-public class PortsStateManager {
-    private static final String PREFS_NAME = ".PORTS";
-    private static final int FLAG_ENABLED = 1;
-
-    private static PortsStateManager mInstance;
-    private final Object mLock = new Object();
-
-    private final SharedPreferences mSharedPref;
-
-    @GuardedBy("mLock")
-    private Set<Integer> mActivePorts;
-
-    @GuardedBy("mLock")
-    private final Set<Integer> mEnabledPorts;
-
-    @GuardedBy("mLock")
-    private final Set<Listener> mListeners;
-
-    private PortsStateManager(SharedPreferences sharedPref) {
-        mSharedPref = sharedPref;
-        mEnabledPorts =
-                mSharedPref.getAll().entrySet().stream()
-                        .filter(entry -> entry.getValue() instanceof Integer)
-                        .filter(entry -> ((int) entry.getValue() & FLAG_ENABLED) == FLAG_ENABLED)
-                        .map(entry -> entry.getKey())
-                        .filter(
-                                key -> {
-                                    try {
-                                        Integer.parseInt(key);
-                                        return true;
-                                    } catch (NumberFormatException e) {
-                                        return false;
-                                    }
-                                })
-                        .map(Integer::parseInt)
-                        .collect(Collectors.toSet());
-        mActivePorts = new HashSet<>();
-        mListeners = new HashSet<>();
-    }
-
-    static synchronized PortsStateManager getInstance(Context context) {
-        if (mInstance == null) {
-            SharedPreferences sharedPref =
-                    context.getSharedPreferences(
-                            context.getPackageName() + PREFS_NAME, Context.MODE_PRIVATE);
-            mInstance = new PortsStateManager(sharedPref);
-        }
-        return mInstance;
-    }
-
-    Set<Integer> getActivePorts() {
-        synchronized (mLock) {
-            return new HashSet<>(mActivePorts);
-        }
-    }
-
-    Set<Integer> getEnabledPorts() {
-        synchronized (mLock) {
-            return new HashSet<>(mEnabledPorts);
-        }
-    }
-
-    void updateActivePorts(Set<Integer> ports) {
-        Set<Integer> oldPorts;
-        synchronized (mLock) {
-            oldPorts = mActivePorts;
-            mActivePorts = ports;
-        }
-        notifyPortsStateUpdated(oldPorts, ports);
-    }
-
-    void updateEnabledPort(int port, boolean enabled) {
-        Set<Integer> activePorts;
-        synchronized (mLock) {
-            SharedPreferences.Editor editor = mSharedPref.edit();
-            editor.putInt(String.valueOf(port), enabled ? FLAG_ENABLED : 0);
-            editor.apply();
-            if (enabled) {
-                mEnabledPorts.add(port);
-            } else {
-                mEnabledPorts.remove(port);
-            }
-            activePorts = mActivePorts;
-        }
-        notifyPortsStateUpdated(activePorts, activePorts);
-    }
-
-    void clearEnabledPorts() {
-        Set<Integer> activePorts;
-        synchronized (mLock) {
-            SharedPreferences.Editor editor = mSharedPref.edit();
-            editor.clear();
-            editor.apply();
-            mEnabledPorts.clear();
-            activePorts = mActivePorts;
-        }
-        notifyPortsStateUpdated(activePorts, activePorts);
-    }
-
-    void registerListener(Listener listener) {
-        synchronized (mLock) {
-            mListeners.add(listener);
-        }
-    }
-
-    void unregisterListener(Listener listener) {
-        synchronized (mLock) {
-            mListeners.remove(listener);
-        }
-    }
-
-    private void notifyPortsStateUpdated(Set<Integer> oldActivePorts, Set<Integer> newActivePorts) {
-        Set<Listener> listeners;
-        synchronized (mLock) {
-            listeners = new HashSet<>(mListeners);
-        }
-        for (Listener listener : listeners) {
-            listener.onPortsStateUpdated(
-                    new HashSet<>(oldActivePorts), new HashSet<>(newActivePorts));
-        }
-    }
-
-    interface Listener {
-        default void onPortsStateUpdated(
-                Set<Integer> oldActivePorts, Set<Integer> newActivePorts) {}
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.kt b/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.kt
new file mode 100644
index 0000000..736176a
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/PortsStateManager.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2024 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.virtualization.terminal
+
+import android.content.Context
+import android.content.SharedPreferences
+import com.android.internal.annotations.GuardedBy
+import java.util.HashSet
+
+/**
+ * PortsStateManager is responsible for communicating with shared preferences and managing state of
+ * ports.
+ */
+class PortsStateManager private constructor(private val sharedPref: SharedPreferences) {
+    private val lock = Any()
+
+    @GuardedBy("lock") private var activePorts: MutableSet<Int> = hashSetOf()
+
+    @GuardedBy("lock")
+    private val enabledPorts: MutableSet<Int> =
+        sharedPref
+            .getAll()
+            .entries
+            .filterIsInstance<MutableMap.MutableEntry<String, Int>>()
+            .filter { it.value and FLAG_ENABLED == FLAG_ENABLED }
+            .map { it.key.toIntOrNull() }
+            .filterNotNull()
+            .toMutableSet()
+
+    @GuardedBy("lock") private val listeners: MutableSet<Listener> = hashSetOf()
+
+    fun getActivePorts(): MutableSet<Int> {
+        synchronized(lock) {
+            return HashSet<Int>(activePorts)
+        }
+    }
+
+    fun getEnabledPorts(): MutableSet<Int> {
+        synchronized(lock) {
+            return HashSet<Int>(enabledPorts)
+        }
+    }
+
+    fun updateActivePorts(ports: MutableSet<Int>) {
+        var oldPorts: MutableSet<Int>
+        synchronized(lock) {
+            oldPorts = activePorts
+            activePorts = ports
+        }
+        notifyPortsStateUpdated(oldPorts, ports)
+    }
+
+    fun updateEnabledPort(port: Int, enabled: Boolean) {
+        var activePorts: MutableSet<Int>
+        synchronized(lock) {
+            val editor = sharedPref.edit()
+            editor.putInt(port.toString(), if (enabled) FLAG_ENABLED else 0)
+            editor.apply()
+            if (enabled) {
+                enabledPorts.add(port)
+            } else {
+                enabledPorts.remove(port)
+            }
+            activePorts = this@PortsStateManager.activePorts
+        }
+        notifyPortsStateUpdated(activePorts, activePorts)
+    }
+
+    fun clearEnabledPorts() {
+        var activePorts: MutableSet<Int>
+        synchronized(lock) {
+            val editor = sharedPref.edit()
+            editor.clear()
+            editor.apply()
+            enabledPorts.clear()
+            activePorts = this@PortsStateManager.activePorts
+        }
+        notifyPortsStateUpdated(activePorts, activePorts)
+    }
+
+    fun registerListener(listener: Listener) {
+        synchronized(lock) { listeners.add(listener) }
+    }
+
+    fun unregisterListener(listener: Listener) {
+        synchronized(lock) { listeners.remove(listener) }
+    }
+
+    private fun notifyPortsStateUpdated(
+        oldActivePorts: MutableSet<Int>,
+        newActivePorts: MutableSet<Int>,
+    ) {
+        var listeners: MutableSet<Listener>
+        synchronized(lock) { listeners = HashSet<Listener>(this@PortsStateManager.listeners) }
+        for (listener in listeners) {
+            listener.onPortsStateUpdated(HashSet<Int>(oldActivePorts), HashSet<Int>(newActivePorts))
+        }
+    }
+
+    interface Listener {
+        fun onPortsStateUpdated(oldActivePorts: Set<Int>, newActivePorts: Set<Int>) {}
+    }
+
+    companion object {
+        private const val PREFS_NAME = ".PORTS"
+        private const val FLAG_ENABLED = 1
+
+        private var instance: PortsStateManager? = null
+
+        @JvmStatic
+        @Synchronized
+        fun getInstance(context: Context): PortsStateManager {
+            if (instance == null) {
+                val sharedPref =
+                    context.getSharedPreferences(
+                        context.getPackageName() + PREFS_NAME,
+                        Context.MODE_PRIVATE,
+                    )
+                instance = PortsStateManager(sharedPref)
+            }
+            return instance!!
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java
deleted file mode 100644
index 4094025..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2024 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.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.content.Context;
-import android.system.virtualmachine.VirtualMachine;
-import android.system.virtualmachine.VirtualMachineCallback;
-import android.system.virtualmachine.VirtualMachineConfig;
-import android.system.virtualmachine.VirtualMachineCustomImageConfig;
-import android.system.virtualmachine.VirtualMachineException;
-import android.system.virtualmachine.VirtualMachineManager;
-import android.util.Log;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ForkJoinPool;
-
-/** Utility class for creating a VM and waiting for it to finish. */
-class Runner {
-    private final VirtualMachine mVirtualMachine;
-    private final Callback mCallback;
-
-    private Runner(VirtualMachine vm, Callback cb) {
-        mVirtualMachine = vm;
-        mCallback = cb;
-    }
-
-    /** Create a virtual machine of the given config, under the given context. */
-    static Runner create(Context context, VirtualMachineConfig config)
-            throws VirtualMachineException {
-        // context may already be the app context, but calling this again is not harmful.
-        // See b/359439878 on why vmm should be obtained from the app context.
-        Context appContext = context.getApplicationContext();
-        VirtualMachineManager vmm = appContext.getSystemService(VirtualMachineManager.class);
-        VirtualMachineCustomImageConfig customConfig = config.getCustomImageConfig();
-        if (customConfig == null) {
-            throw new RuntimeException("CustomImageConfig is missing");
-        }
-
-        String name = customConfig.getName();
-        if (name == null || name.isEmpty()) {
-            throw new RuntimeException("Virtual machine's name is missing in the config");
-        }
-
-        VirtualMachine vm = vmm.getOrCreate(name, config);
-        try {
-            vm.setConfig(config);
-        } catch (VirtualMachineException e) {
-            vmm.delete(name);
-            vm = vmm.create(name, config);
-            Log.w(TAG, "Re-creating virtual machine (" + name + ")", e);
-        }
-
-        Callback cb = new Callback();
-        vm.setCallback(ForkJoinPool.commonPool(), cb);
-        vm.run();
-        return new Runner(vm, cb);
-    }
-
-    /** Give access to the underlying VirtualMachine object. */
-    VirtualMachine getVm() {
-        return mVirtualMachine;
-    }
-
-    /** Get future about VM's exit status. */
-    CompletableFuture<Boolean> getExitStatus() {
-        return mCallback.mFinishedSuccessfully;
-    }
-
-    private static class Callback implements VirtualMachineCallback {
-        final CompletableFuture<Boolean> mFinishedSuccessfully = new CompletableFuture<>();
-
-        @Override
-        public void onPayloadStarted(VirtualMachine vm) {
-            // This event is only from Microdroid-based VM. Custom VM shouldn't emit this.
-        }
-
-        @Override
-        public void onPayloadReady(VirtualMachine vm) {
-            // This event is only from Microdroid-based VM. Custom VM shouldn't emit this.
-        }
-
-        @Override
-        public void onPayloadFinished(VirtualMachine vm, int exitCode) {
-            // This event is only from Microdroid-based VM. Custom VM shouldn't emit this.
-        }
-
-        @Override
-        public void onError(VirtualMachine vm, int errorCode, String message) {
-            Log.e(TAG, "Error from VM. code: " + errorCode + " (" + message + ")");
-            mFinishedSuccessfully.complete(false);
-        }
-
-        @Override
-        public void onStopped(VirtualMachine vm, int reason) {
-            Log.d(TAG, "VM stopped. Reason: " + reason);
-            mFinishedSuccessfully.complete(true);
-        }
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.kt b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.kt
new file mode 100644
index 0000000..897e182
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2024 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.virtualization.terminal
+
+import android.content.Context
+import android.system.virtualmachine.VirtualMachine
+import android.system.virtualmachine.VirtualMachineCallback
+import android.system.virtualmachine.VirtualMachineConfig
+import android.system.virtualmachine.VirtualMachineException
+import android.system.virtualmachine.VirtualMachineManager
+import android.util.Log
+import com.android.virtualization.terminal.MainActivity.TAG
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.ForkJoinPool
+
+/** Utility class for creating a VM and waiting for it to finish. */
+internal class Runner private constructor(val vm: VirtualMachine?, callback: Callback) {
+    /** Get future about VM's exit status. */
+    val exitStatus = callback.finishedSuccessfully
+
+    private class Callback : VirtualMachineCallback {
+        val finishedSuccessfully: CompletableFuture<Boolean> = CompletableFuture<Boolean>()
+
+        override fun onPayloadStarted(vm: VirtualMachine) {
+            // This event is only from Microdroid-based VM. Custom VM shouldn't emit this.
+        }
+
+        override fun onPayloadReady(vm: VirtualMachine) {
+            // This event is only from Microdroid-based VM. Custom VM shouldn't emit this.
+        }
+
+        override fun onPayloadFinished(vm: VirtualMachine, exitCode: Int) {
+            // This event is only from Microdroid-based VM. Custom VM shouldn't emit this.
+        }
+
+        override fun onError(vm: VirtualMachine, errorCode: Int, message: String) {
+            Log.e(TAG, "Error from VM. code: $errorCode ($message)")
+            finishedSuccessfully.complete(false)
+        }
+
+        override fun onStopped(vm: VirtualMachine, reason: Int) {
+            Log.d(TAG, "VM stopped. Reason: $reason")
+            finishedSuccessfully.complete(true)
+        }
+    }
+
+    companion object {
+        /** Create a virtual machine of the given config, under the given context. */
+        @JvmStatic
+        @Throws(VirtualMachineException::class)
+        fun create(context: Context, config: VirtualMachineConfig): Runner {
+            // context may already be the app context, but calling this again is not harmful.
+            // See b/359439878 on why vmm should be obtained from the app context.
+            val appContext = context.getApplicationContext()
+            val vmm =
+                appContext.getSystemService<VirtualMachineManager>(
+                    VirtualMachineManager::class.java
+                )
+            val customConfig = config.customImageConfig
+            requireNotNull(customConfig) { "CustomImageConfig is missing" }
+
+            val name = customConfig.name
+            require(!name.isNullOrEmpty()) { "Virtual machine's name is missing in the config" }
+
+            var vm = vmm.getOrCreate(name, config)
+            try {
+                vm.config = config
+            } catch (e: VirtualMachineException) {
+                vmm.delete(name)
+                vm = vmm.create(name, config)
+                Log.w(TAG, "Re-creating virtual machine ($name)", e)
+            }
+
+            val cb = Callback()
+            vm.setCallback(ForkJoinPool.commonPool(), cb)
+            vm.run()
+            return Runner(vm, cb)
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalExceptionHandler.java b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalExceptionHandler.java
deleted file mode 100644
index 4ab2b77..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalExceptionHandler.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2024 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.virtualization.terminal;
-
-import android.content.Context;
-import android.util.Log;
-
-public class TerminalExceptionHandler implements Thread.UncaughtExceptionHandler {
-    private static final String TAG = "TerminalExceptionHandler";
-
-    private final Context mContext;
-
-    public TerminalExceptionHandler(Context context) {
-        mContext = context;
-    }
-
-    @Override
-    public void uncaughtException(Thread thread, Throwable throwable) {
-        Exception exception;
-        if (throwable instanceof Exception) {
-            exception = (Exception) throwable;
-        } else {
-            exception = new Exception(throwable);
-        }
-        try {
-            ErrorActivity.start(mContext, exception);
-        } catch (Exception ex) {
-            Log.wtf(TAG, "Failed to launch error activity for an exception", exception);
-        }
-
-        thread.getDefaultUncaughtExceptionHandler().uncaughtException(thread, throwable);
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalExceptionHandler.kt b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalExceptionHandler.kt
new file mode 100644
index 0000000..3a8c444
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalExceptionHandler.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2024 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.virtualization.terminal
+
+import android.content.Context
+import android.util.Log
+import java.lang.Exception
+
+class TerminalExceptionHandler(private val context: Context) : Thread.UncaughtExceptionHandler {
+
+    override fun uncaughtException(thread: Thread, throwable: Throwable) {
+        val exception = (throwable as? Exception) ?: Exception(throwable)
+        try {
+            ErrorActivity.start(context, exception)
+        } catch (_: Exception) {
+            Log.wtf(TAG, "Failed to launch error activity for an exception", exception)
+        }
+        Thread.getDefaultUncaughtExceptionHandler()?.uncaughtException(thread, throwable)
+    }
+
+    companion object {
+        private const val TAG = "TerminalExceptionHandler"
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalThreadFactory.java b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalThreadFactory.java
deleted file mode 100644
index 5ee535d..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalThreadFactory.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2024 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.virtualization.terminal;
-
-import android.content.Context;
-
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-
-public class TerminalThreadFactory implements ThreadFactory {
-    private final Context mContext;
-
-    public TerminalThreadFactory(Context context) {
-        mContext = context;
-    }
-
-    @Override
-    public Thread newThread(Runnable r) {
-        Thread thread = Executors.defaultThreadFactory().newThread(r);
-        thread.setUncaughtExceptionHandler(new TerminalExceptionHandler(mContext));
-        return thread;
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalThreadFactory.kt b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalThreadFactory.kt
new file mode 100644
index 0000000..f8e909d
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalThreadFactory.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 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.virtualization.terminal
+
+import android.content.Context
+import java.util.concurrent.Executors
+import java.util.concurrent.ThreadFactory
+
+class TerminalThreadFactory(private val context: Context) : ThreadFactory {
+    override fun newThread(r: Runnable): Thread {
+        return Executors.defaultThreadFactory().newThread(r).also {
+            it.uncaughtExceptionHandler = TerminalExceptionHandler(context)
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java
deleted file mode 100644
index 0ffc093..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (C) 2024 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.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.view.View.AccessibilityDelegate;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import android.view.accessibility.AccessibilityNodeProvider;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.webkit.WebView;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-
-public class TerminalView extends WebView
-        implements AccessibilityStateChangeListener, TouchExplorationStateChangeListener {
-    // Maximum length of texts the talk back announcements can be. This value is somewhat
-    // arbitrarily set. We may want to adjust this in the future.
-    private static final int TEXT_TOO_LONG_TO_ANNOUNCE = 200;
-
-    private final String CTRL_KEY_HANDLER;
-    private final String ENABLE_CTRL_KEY;
-    private final String TOUCH_TO_MOUSE_HANDLER;
-
-    private final AccessibilityManager mA11yManager;
-
-    public TerminalView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mA11yManager = context.getSystemService(AccessibilityManager.class);
-        mA11yManager.addTouchExplorationStateChangeListener(this);
-        mA11yManager.addAccessibilityStateChangeListener(this);
-        adjustToA11yStateChange();
-        try {
-            CTRL_KEY_HANDLER = readAssetAsString(context, "js/ctrl_key_handler.js");
-            ENABLE_CTRL_KEY = readAssetAsString(context, "js/enable_ctrl_key.js");
-            TOUCH_TO_MOUSE_HANDLER = readAssetAsString(context, "js/touch_to_mouse_handler.js");
-        } catch (IOException e) {
-            // It cannot happen
-            throw new IllegalArgumentException("cannot read code from asset", e);
-        }
-    }
-
-    private String readAssetAsString(Context context, String filePath) throws IOException {
-        try (InputStream is = context.getAssets().open(filePath)) {
-            return new String(is.readAllBytes());
-        }
-    }
-
-    public void mapTouchToMouseEvent() {
-        this.evaluateJavascript(TOUCH_TO_MOUSE_HANDLER, null);
-    }
-
-    public void mapCtrlKey() {
-        this.evaluateJavascript(CTRL_KEY_HANDLER, null);
-    }
-
-    public void enableCtrlKey() {
-        this.evaluateJavascript(ENABLE_CTRL_KEY, null);
-    }
-
-    @Override
-    public void onAccessibilityStateChanged(boolean enabled) {
-        Log.d(TAG, "accessibility " + enabled);
-        adjustToA11yStateChange();
-    }
-
-    @Override
-    public void onTouchExplorationStateChanged(boolean enabled) {
-        Log.d(TAG, "touch exploration " + enabled);
-        adjustToA11yStateChange();
-    }
-
-    private void adjustToA11yStateChange() {
-        if (!mA11yManager.isEnabled()) {
-            setFocusable(true);
-            return;
-        }
-
-        // When accessibility is on, the webview itself doesn't have to be focusable. The (virtual)
-        // edittext will be focusable to accept inputs. However, the webview has to be focusable for
-        // an accessibility purpose so that users can read the contents in it or scroll the view.
-        setFocusable(false);
-        setFocusableInTouchMode(true);
-    }
-
-    // AccessibilityEvents for WebView are sent directly from WebContentsAccessibilityImpl to the
-    // parent of WebView, without going through WebView. So, there's no WebView methods we can
-    // override to intercept the event handling process. To work around this, we attach an
-    // AccessibilityDelegate to the parent view where the events are sent to. And to guarantee that
-    // the parent view exists, wait until the WebView is attached to the window by when the parent
-    // must exist.
-    private final AccessibilityDelegate mA11yEventFilter =
-            new AccessibilityDelegate() {
-                @Override
-                public boolean onRequestSendAccessibilityEvent(
-                        ViewGroup host, View child, AccessibilityEvent e) {
-                    // We filter only the a11y events from the WebView
-                    if (child != TerminalView.this) {
-                        return super.onRequestSendAccessibilityEvent(host, child, e);
-                    }
-                    final int eventType = e.getEventType();
-                    switch (e.getEventType()) {
-                            // Skip reading texts that are too long. Right now, ttyd emits entire
-                            // text on the terminal to the live region, which is very annoying to
-                            // screen reader users.
-                        case AccessibilityEvent.TYPE_ANNOUNCEMENT:
-                            CharSequence text = e.getText().get(0); // there always is a text
-                            if (text.length() >= TEXT_TOO_LONG_TO_ANNOUNCE) {
-                                Log.i(TAG, "Announcement skipped because it's too long: " + text);
-                                return false;
-                            }
-                            break;
-                    }
-                    return super.onRequestSendAccessibilityEvent(host, child, e);
-                }
-            };
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        if (mA11yManager.isEnabled()) {
-            View parent = (View) getParent();
-            parent.setAccessibilityDelegate(mA11yEventFilter);
-        }
-    }
-
-    private final AccessibilityNodeProvider mA11yNodeProvider =
-            new AccessibilityNodeProvider() {
-
-                /** Returns the original NodeProvider that WebView implements. */
-                private AccessibilityNodeProvider getParent() {
-                    return TerminalView.super.getAccessibilityNodeProvider();
-                }
-
-                /** Convenience method for reading a string resource. */
-                private String getString(int resId) {
-                    return TerminalView.this.getContext().getResources().getString(resId);
-                }
-
-                /** Checks if NodeInfo renders an empty line in the terminal. */
-                private boolean isEmptyLine(AccessibilityNodeInfo info) {
-                    final CharSequence text = info.getText();
-                    // Node with no text is not consiered a line. ttyd emits at least one character,
-                    // which usually is NBSP.
-                    if (text == null) {
-                        return false;
-                    }
-                    for (int i = 0; i < text.length(); i++) {
-                        char c = text.charAt(i);
-                        // Note: don't use Characters.isWhitespace as it doesn't recognize NBSP as a
-                        // whitespace.
-                        if (!TextUtils.isWhitespace(c)) {
-                            return false;
-                        }
-                    }
-                    return true;
-                }
-
-                @Override
-                public AccessibilityNodeInfo createAccessibilityNodeInfo(int id) {
-                    AccessibilityNodeInfo info = getParent().createAccessibilityNodeInfo(id);
-                    if (info == null) {
-                        return null;
-                    }
-
-                    final String className = info.getClassName().toString();
-
-                    // By default all views except the cursor is not click-able. Other views are
-                    // read-only. This ensures that user is not navigated to non-clickable elements
-                    // when using switches.
-                    if (!"android.widget.EditText".equals(className)) {
-                        info.removeAction(AccessibilityAction.ACTION_CLICK);
-                    }
-
-                    switch (className) {
-                        case "android.webkit.WebView":
-                            // There are two NodeInfo objects of class name WebView. The one is the
-                            // real WebView whose ID is View.NO_ID as it's at the root of the
-                            // virtual view hierarchy. The second one is a virtual view for the
-                            // iframe. The latter one's text is set to the command that we give to
-                            // ttyd, which is "login -f droid ...". This is an impl detail which
-                            // doesn't have to be announced.  Replace the text with "Terminal
-                            // display".
-                            if (id != View.NO_ID) {
-                                info.setText(null);
-                                info.setContentDescription(getString(R.string.terminal_display));
-                                // b/376827536
-                                info.setHintText(getString(R.string.double_tap_to_edit_text));
-                            }
-
-                            // These two lines below are to prevent this WebView element from being
-                            // fousable by the screen reader, while allowing any other element in
-                            // the WebView to be focusable by the reader. In our case, the EditText
-                            // is a117_focusable.
-                            info.setScreenReaderFocusable(false);
-                            info.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
-                            break;
-                        case "android.view.View":
-                            // Empty line was announced as "space" (via the NBSP character).
-                            // Localize the spoken text.
-                            if (isEmptyLine(info)) {
-                                info.setContentDescription(getString(R.string.empty_line));
-                                // b/376827536
-                                info.setHintText(getString(R.string.double_tap_to_edit_text));
-                            }
-                            break;
-                        case "android.widget.TextView":
-                            // There are several TextViews in the terminal, and one of them is an
-                            // invisible TextView which seems to be from the <div
-                            // class="live-region"> tag. Interestingly, its text is often populated
-                            // with the entire text on the screen. Silence this by forcibly setting
-                            // the text to null. Note that this TextView is identified by having a
-                            // zero width. This certainly is not elegant, but I couldn't find other
-                            // options.
-                            Rect rect = new Rect();
-                            info.getBoundsInScreen(rect);
-                            if (rect.width() == 0) {
-                                info.setText(null);
-                                info.setContentDescription(getString(R.string.empty_line));
-                            }
-                            info.setScreenReaderFocusable(false);
-                            break;
-                        case "android.widget.EditText":
-                            // This EditText is for the <textarea> accepting user input; the cursor.
-                            // ttyd name it as "Terminal input" but it's not i18n'ed. Override it
-                            // here for better i18n.
-                            info.setText(null);
-                            info.setHintText(getString(R.string.double_tap_to_edit_text));
-                            info.setContentDescription(getString(R.string.terminal_input));
-                            info.setScreenReaderFocusable(true);
-                            info.addAction(AccessibilityAction.ACTION_FOCUS);
-                            break;
-                    }
-                    return info;
-                }
-
-                @Override
-                public boolean performAction(int id, int action, Bundle arguments) {
-                    return getParent().performAction(id, action, arguments);
-                }
-
-                @Override
-                public void addExtraDataToAccessibilityNodeInfo(
-                        int virtualViewId,
-                        AccessibilityNodeInfo info,
-                        String extraDataKey,
-                        Bundle arguments) {
-                    getParent()
-                            .addExtraDataToAccessibilityNodeInfo(
-                                    virtualViewId, info, extraDataKey, arguments);
-                }
-
-                @Override
-                public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(
-                        String text, int virtualViewId) {
-                    return getParent().findAccessibilityNodeInfosByText(text, virtualViewId);
-                }
-
-                @Override
-                public AccessibilityNodeInfo findFocus(int focus) {
-                    return getParent().findFocus(focus);
-                }
-            };
-
-    @Override
-    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
-        AccessibilityNodeProvider p = super.getAccessibilityNodeProvider();
-        if (p != null && mA11yManager.isEnabled()) {
-            return mA11yNodeProvider;
-        }
-        return p;
-    }
-
-    @Override
-    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
-        InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
-        if (outAttrs != null) {
-            outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
-        }
-        return inputConnection;
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.kt b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.kt
new file mode 100644
index 0000000..18a39fa
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.kt
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2024 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.virtualization.terminal
+
+import android.content.Context
+import android.graphics.Rect
+import android.os.Bundle
+import android.text.InputType
+import android.text.TextUtils
+import android.util.AttributeSet
+import android.util.Log
+import android.view.View
+import android.view.ViewGroup
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityManager
+import android.view.accessibility.AccessibilityNodeInfo
+import android.view.accessibility.AccessibilityNodeProvider
+import android.view.inputmethod.EditorInfo
+import android.view.inputmethod.InputConnection
+import android.webkit.WebView
+import com.android.virtualization.terminal.MainActivity.TAG
+import java.io.IOException
+
+class TerminalView(context: Context, attrs: AttributeSet?) :
+    WebView(context, attrs),
+    AccessibilityManager.AccessibilityStateChangeListener,
+    AccessibilityManager.TouchExplorationStateChangeListener {
+    private val ctrlKeyHandler: String = readAssetAsString(context, "js/ctrl_key_handler.js")
+    private val enableCtrlKey: String = readAssetAsString(context, "js/enable_ctrl_key.js")
+    private val touchToMouseHandler: String =
+        readAssetAsString(context, "js/touch_to_mouse_handler.js")
+    private val a11yManager =
+        context.getSystemService<AccessibilityManager>(AccessibilityManager::class.java).also {
+            it.addTouchExplorationStateChangeListener(this)
+            it.addAccessibilityStateChangeListener(this)
+        }
+
+    @Throws(IOException::class)
+    private fun readAssetAsString(context: Context, filePath: String): String {
+        return String(context.assets.open(filePath).readAllBytes())
+    }
+
+    fun mapTouchToMouseEvent() {
+        this.evaluateJavascript(touchToMouseHandler, null)
+    }
+
+    fun mapCtrlKey() {
+        this.evaluateJavascript(ctrlKeyHandler, null)
+    }
+
+    fun enableCtrlKey() {
+        this.evaluateJavascript(enableCtrlKey, null)
+    }
+
+    override fun onAccessibilityStateChanged(enabled: Boolean) {
+        Log.d(TAG, "accessibility $enabled")
+        adjustToA11yStateChange()
+    }
+
+    override fun onTouchExplorationStateChanged(enabled: Boolean) {
+        Log.d(TAG, "touch exploration $enabled")
+        adjustToA11yStateChange()
+    }
+
+    private fun adjustToA11yStateChange() {
+        if (!a11yManager.isEnabled) {
+            setFocusable(true)
+            return
+        }
+
+        // When accessibility is on, the webview itself doesn't have to be focusable. The (virtual)
+        // edittext will be focusable to accept inputs. However, the webview has to be focusable for
+        // an accessibility purpose so that users can read the contents in it or scroll the view.
+        setFocusable(false)
+        setFocusableInTouchMode(true)
+    }
+
+    // AccessibilityEvents for WebView are sent directly from WebContentsAccessibilityImpl to the
+    // parent of WebView, without going through WebView. So, there's no WebView methods we can
+    // override to intercept the event handling process. To work around this, we attach an
+    // AccessibilityDelegate to the parent view where the events are sent to. And to guarantee that
+    // the parent view exists, wait until the WebView is attached to the window by when the parent
+    // must exist.
+    private val mA11yEventFilter: AccessibilityDelegate =
+        object : AccessibilityDelegate() {
+            override fun onRequestSendAccessibilityEvent(
+                host: ViewGroup,
+                child: View,
+                e: AccessibilityEvent,
+            ): Boolean {
+                // We filter only the a11y events from the WebView
+                if (child !== this@TerminalView) {
+                    return super.onRequestSendAccessibilityEvent(host, child, e)
+                }
+                when (e.eventType) {
+                    AccessibilityEvent.TYPE_ANNOUNCEMENT -> {
+                        val text = e.text[0] // there always is a text
+                        if (text.length >= TEXT_TOO_LONG_TO_ANNOUNCE) {
+                            Log.i(TAG, "Announcement skipped because it's too long: $text")
+                            return false
+                        }
+                    }
+                }
+                return super.onRequestSendAccessibilityEvent(host, child, e)
+            }
+        }
+
+    override fun onAttachedToWindow() {
+        super.onAttachedToWindow()
+        if (a11yManager.isEnabled) {
+            val parent = getParent() as View
+            parent.setAccessibilityDelegate(mA11yEventFilter)
+        }
+    }
+
+    private val mA11yNodeProvider: AccessibilityNodeProvider =
+        object : AccessibilityNodeProvider() {
+            /** Returns the original NodeProvider that WebView implements. */
+            private fun getParent(): AccessibilityNodeProvider? {
+                return super@TerminalView.getAccessibilityNodeProvider()
+            }
+
+            /** Convenience method for reading a string resource. */
+            private fun getString(resId: Int): String {
+                return this@TerminalView.context.getResources().getString(resId)
+            }
+
+            /** Checks if NodeInfo renders an empty line in the terminal. */
+            private fun isEmptyLine(info: AccessibilityNodeInfo): Boolean {
+                // Node with no text is not considered a line. ttyd emits at least one character,
+                // which usually is NBSP.
+                // Note: don't use Characters.isWhitespace as it doesn't recognize NBSP as a
+                // whitespace.
+                return (info.getText()?.all { TextUtils.isWhitespace(it.code) }) == true
+            }
+
+            override fun createAccessibilityNodeInfo(id: Int): AccessibilityNodeInfo? {
+                val info: AccessibilityNodeInfo? = getParent()?.createAccessibilityNodeInfo(id)
+                if (info == null) {
+                    return null
+                }
+
+                val className = info.className.toString()
+
+                // By default all views except the cursor is not click-able. Other views are
+                // read-only. This ensures that user is not navigated to non-clickable elements
+                // when using switches.
+                if ("android.widget.EditText" != className) {
+                    info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK)
+                }
+
+                when (className) {
+                    "android.webkit.WebView" -> {
+                        // There are two NodeInfo objects of class name WebView. The one is the
+                        // real WebView whose ID is View.NO_ID as it's at the root of the
+                        // virtual view hierarchy. The second one is a virtual view for the
+                        // iframe. The latter one's text is set to the command that we give to
+                        // ttyd, which is "login -f droid ...". This is an impl detail which
+                        // doesn't have to be announced.  Replace the text with "Terminal
+                        // display".
+                        if (id != NO_ID) {
+                            info.setText(null)
+                            info.setContentDescription(getString(R.string.terminal_display))
+                            // b/376827536
+                            info.setHintText(getString(R.string.double_tap_to_edit_text))
+                        }
+
+                        // These two lines below are to prevent this WebView element from being
+                        // focusable by the screen reader, while allowing any other element in
+                        // the WebView to be focusable by the reader. In our case, the EditText
+                        // is a117_focusable.
+                        info.isScreenReaderFocusable = false
+                        info.addAction(
+                            AccessibilityNodeInfo.AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS
+                        )
+                    }
+
+                    "android.view.View" ->
+                        // Empty line was announced as "space" (via the NBSP character).
+                        // Localize the spoken text.
+                        if (isEmptyLine(info)) {
+                            info.setContentDescription(getString(R.string.empty_line))
+                            // b/376827536
+                            info.setHintText(getString(R.string.double_tap_to_edit_text))
+                        }
+
+                    "android.widget.TextView" -> {
+                        // There are several TextViews in the terminal, and one of them is an
+                        // invisible TextView which seems to be from the <div
+                        // class="live-region"> tag. Interestingly, its text is often populated
+                        // with the entire text on the screen. Silence this by forcibly setting
+                        // the text to null. Note that this TextView is identified by having a
+                        // zero width. This certainly is not elegant, but I couldn't find other
+                        // options.
+                        val rect = Rect()
+                        info.getBoundsInScreen(rect)
+                        if (rect.width() == 0) {
+                            info.setText(null)
+                            info.setContentDescription(getString(R.string.empty_line))
+                        }
+                        info.isScreenReaderFocusable = false
+                    }
+
+                    "android.widget.EditText" -> {
+                        // This EditText is for the <textarea> accepting user input; the cursor.
+                        // ttyd name it as "Terminal input" but it's not i18n'ed. Override it
+                        // here for better i18n.
+                        info.setText(null)
+                        info.setHintText(getString(R.string.double_tap_to_edit_text))
+                        info.setContentDescription(getString(R.string.terminal_input))
+                        info.isScreenReaderFocusable = true
+                        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_FOCUS)
+                    }
+                }
+                return info
+            }
+
+            override fun performAction(id: Int, action: Int, arguments: Bundle?): Boolean {
+                return getParent()?.performAction(id, action, arguments) == true
+            }
+
+            override fun addExtraDataToAccessibilityNodeInfo(
+                virtualViewId: Int,
+                info: AccessibilityNodeInfo?,
+                extraDataKey: String?,
+                arguments: Bundle?,
+            ) {
+                getParent()
+                    ?.addExtraDataToAccessibilityNodeInfo(
+                        virtualViewId,
+                        info,
+                        extraDataKey,
+                        arguments,
+                    )
+            }
+
+            override fun findAccessibilityNodeInfosByText(
+                text: String?,
+                virtualViewId: Int,
+            ): MutableList<AccessibilityNodeInfo?>? {
+                return getParent()?.findAccessibilityNodeInfosByText(text, virtualViewId)
+            }
+
+            override fun findFocus(focus: Int): AccessibilityNodeInfo? {
+                return getParent()?.findFocus(focus)
+            }
+        }
+
+    override fun getAccessibilityNodeProvider(): AccessibilityNodeProvider? {
+        val p = super.getAccessibilityNodeProvider()
+        if (p != null && a11yManager.isEnabled) {
+            return mA11yNodeProvider
+        }
+        return p
+    }
+
+    override fun onCreateInputConnection(outAttrs: EditorInfo?): InputConnection? {
+        val inputConnection = super.onCreateInputConnection(outAttrs)
+        if (outAttrs != null) {
+            outAttrs.inputType = outAttrs.inputType or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
+        }
+        return inputConnection
+    }
+
+    companion object {
+        // Maximum length of texts the talk back announcements can be. This value is somewhat
+        // arbitrarily set. We may want to adjust this in the future.
+        private const val TEXT_TOO_LONG_TO_ANNOUNCE = 200
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
deleted file mode 100644
index 09b58d3..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * Copyright (C) 2024 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.virtualization.terminal;
-
-import static com.android.virtualization.terminal.MainActivity.TAG;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Icon;
-import android.net.nsd.NsdManager;
-import android.net.nsd.NsdServiceInfo;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.ResultReceiver;
-import android.system.virtualmachine.VirtualMachine;
-import android.system.virtualmachine.VirtualMachineConfig;
-import android.system.virtualmachine.VirtualMachineCustomImageConfig;
-import android.system.virtualmachine.VirtualMachineCustomImageConfig.Disk;
-import android.system.virtualmachine.VirtualMachineException;
-import android.util.Log;
-import android.widget.Toast;
-
-import io.grpc.Grpc;
-import io.grpc.InsecureServerCredentials;
-import io.grpc.Metadata;
-import io.grpc.Server;
-import io.grpc.ServerCall;
-import io.grpc.ServerCallHandler;
-import io.grpc.ServerInterceptor;
-import io.grpc.Status;
-import io.grpc.okhttp.OkHttpServerBuilder;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Objects;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-public class VmLauncherService extends Service {
-    private static final String EXTRA_NOTIFICATION = "EXTRA_NOTIFICATION";
-    private static final String ACTION_START_VM_LAUNCHER_SERVICE =
-            "android.virtualization.START_VM_LAUNCHER_SERVICE";
-
-    public static final String ACTION_STOP_VM_LAUNCHER_SERVICE =
-            "android.virtualization.STOP_VM_LAUNCHER_SERVICE";
-
-    private static final int RESULT_START = 0;
-    private static final int RESULT_STOP = 1;
-    private static final int RESULT_ERROR = 2;
-
-    private ExecutorService mExecutorService;
-    private VirtualMachine mVirtualMachine;
-    private ResultReceiver mResultReceiver;
-    private Server mServer;
-    private DebianServiceImpl mDebianService;
-    private PortNotifier mPortNotifier;
-
-    private static Intent getMyIntent(Context context) {
-        return new Intent(context.getApplicationContext(), VmLauncherService.class);
-    }
-
-    public interface VmLauncherServiceCallback {
-        void onVmStart();
-
-        void onVmStop();
-
-        void onVmError();
-    }
-
-    public static void run(
-            Context context, VmLauncherServiceCallback callback, Notification notification) {
-        Intent i = getMyIntent(context);
-        if (i == null) {
-            return;
-        }
-        ResultReceiver resultReceiver =
-                new ResultReceiver(new Handler(Looper.myLooper())) {
-                    @Override
-                    protected void onReceiveResult(int resultCode, Bundle resultData) {
-                        if (callback == null) {
-                            return;
-                        }
-                        switch (resultCode) {
-                            case RESULT_START:
-                                callback.onVmStart();
-                                return;
-                            case RESULT_STOP:
-                                callback.onVmStop();
-                                return;
-                            case RESULT_ERROR:
-                                callback.onVmError();
-                                return;
-                        }
-                    }
-                };
-        i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver));
-        i.putExtra(VmLauncherService.EXTRA_NOTIFICATION, notification);
-        context.startForegroundService(i);
-    }
-
-    private static ResultReceiver getResultReceiverForIntent(ResultReceiver r) {
-        Parcel parcel = Parcel.obtain();
-        r.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        r = ResultReceiver.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-        return r;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (Objects.equals(intent.getAction(), ACTION_STOP_VM_LAUNCHER_SERVICE)) {
-
-            if (mDebianService != null && mDebianService.shutdownDebian()) {
-                // During shutdown, change the notification content to indicate that it's closing
-                Notification notification = createNotificationForTerminalClose();
-                getSystemService(NotificationManager.class).notify(this.hashCode(), notification);
-            } else {
-                // If there is no Debian service or it fails to shutdown, just stop the service.
-                stopSelf();
-            }
-            return START_NOT_STICKY;
-        }
-        if (mVirtualMachine != null) {
-            Log.d(TAG, "VM instance is already started");
-            return START_NOT_STICKY;
-        }
-        mExecutorService =
-                Executors.newCachedThreadPool(new TerminalThreadFactory(getApplicationContext()));
-
-        InstalledImage image = InstalledImage.getDefault(this);
-        ConfigJson json = ConfigJson.from(this, image.getConfigPath());
-        VirtualMachineConfig.Builder configBuilder = json.toConfigBuilder(this);
-        VirtualMachineCustomImageConfig.Builder customImageConfigBuilder =
-                json.toCustomImageConfigBuilder(this);
-        if (overrideConfigIfNecessary(customImageConfigBuilder)) {
-            configBuilder.setCustomImageConfig(customImageConfigBuilder.build());
-        }
-        VirtualMachineConfig config = configBuilder.build();
-
-        Runner runner;
-        try {
-            android.os.Trace.beginSection("vmCreate");
-            runner = Runner.create(this, config);
-            android.os.Trace.endSection();
-            android.os.Trace.beginAsyncSection("debianBoot", 0);
-        } catch (VirtualMachineException e) {
-            throw new RuntimeException("cannot create runner", e);
-        }
-        mVirtualMachine = runner.getVm();
-        mResultReceiver =
-                intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER, ResultReceiver.class);
-
-        runner.getExitStatus()
-                .thenAcceptAsync(
-                        success -> {
-                            if (mResultReceiver != null) {
-                                mResultReceiver.send(success ? RESULT_STOP : RESULT_ERROR, null);
-                            }
-                            stopSelf();
-                        });
-        Path logPath = getFileStreamPath(mVirtualMachine.getName() + ".log").toPath();
-        Logger.setup(mVirtualMachine, logPath, mExecutorService);
-
-        Notification notification =
-                intent.getParcelableExtra(EXTRA_NOTIFICATION, Notification.class);
-
-        startForeground(this.hashCode(), notification);
-
-        mResultReceiver.send(RESULT_START, null);
-
-        mPortNotifier = new PortNotifier(this);
-
-        // TODO: dedup this part
-        NsdManager nsdManager = getSystemService(NsdManager.class);
-        NsdServiceInfo info = new NsdServiceInfo();
-        info.setServiceType("_http._tcp");
-        info.setServiceName("ttyd");
-        nsdManager.registerServiceInfoCallback(
-                info,
-                mExecutorService,
-                new NsdManager.ServiceInfoCallback() {
-                    @Override
-                    public void onServiceInfoCallbackRegistrationFailed(int errorCode) {}
-
-                    @Override
-                    public void onServiceInfoCallbackUnregistered() {}
-
-                    @Override
-                    public void onServiceLost() {}
-
-                    @Override
-                    public void onServiceUpdated(NsdServiceInfo info) {
-                        nsdManager.unregisterServiceInfoCallback(this);
-                        Log.i(TAG, "Service found: " + info.toString());
-                        String ipAddress = info.getHostAddresses().get(0).getHostAddress();
-                        startDebianServer(ipAddress);
-                    }
-                });
-
-        return START_NOT_STICKY;
-    }
-
-    private Notification createNotificationForTerminalClose() {
-        Intent stopIntent = new Intent();
-        stopIntent.setClass(this, VmLauncherService.class);
-        stopIntent.setAction(VmLauncherService.ACTION_STOP_VM_LAUNCHER_SERVICE);
-        PendingIntent stopPendingIntent =
-                PendingIntent.getService(
-                        this,
-                        0,
-                        stopIntent,
-                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
-        Icon icon = Icon.createWithResource(getResources(), R.drawable.ic_launcher_foreground);
-        String stopActionText =
-                getResources().getString(R.string.service_notification_force_quit_action);
-        String stopNotificationTitle =
-                getResources().getString(R.string.service_notification_close_title);
-        return new Notification.Builder(this, this.getPackageName())
-                .setSmallIcon(R.drawable.ic_launcher_foreground)
-                .setContentTitle(stopNotificationTitle)
-                .setOngoing(true)
-                .setSilent(true)
-                .addAction(
-                        new Notification.Action.Builder(icon, stopActionText, stopPendingIntent)
-                                .build())
-                .build();
-    }
-
-    private boolean overrideConfigIfNecessary(VirtualMachineCustomImageConfig.Builder builder) {
-        boolean changed = false;
-        // TODO: check if ANGLE is enabled for the app.
-        if (Files.exists(ImageArchive.getSdcardPathForTesting().resolve("virglrenderer"))) {
-            builder.setGpuConfig(
-                    new VirtualMachineCustomImageConfig.GpuConfig.Builder()
-                            .setBackend("virglrenderer")
-                            .setRendererUseEgl(true)
-                            .setRendererUseGles(true)
-                            .setRendererUseGlx(false)
-                            .setRendererUseSurfaceless(true)
-                            .setRendererUseVulkan(false)
-                            .setContextTypes(new String[] {"virgl2"})
-                            .build());
-            Toast.makeText(this, R.string.virgl_enabled, Toast.LENGTH_SHORT).show();
-            changed = true;
-        }
-
-        InstalledImage image = InstalledImage.getDefault(this);
-        if (image.hasBackup()) {
-            Path backup = image.getBackupFile();
-            builder.addDisk(Disk.RWDisk(backup.toString()));
-            changed = true;
-        }
-        return changed;
-    }
-
-    private void startDebianServer(String ipAddress) {
-        ServerInterceptor interceptor =
-                new ServerInterceptor() {
-                    @Override
-                    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
-                            ServerCall<ReqT, RespT> call,
-                            Metadata headers,
-                            ServerCallHandler<ReqT, RespT> next) {
-                        InetSocketAddress remoteAddr =
-                                (InetSocketAddress)
-                                        call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR);
-
-                        if (remoteAddr != null
-                                && Objects.equals(
-                                        remoteAddr.getAddress().getHostAddress(), ipAddress)) {
-                            // Allow the request only if it is from VM
-                            return next.startCall(call, headers);
-                        }
-                        Log.d(TAG, "blocked grpc request from " + remoteAddr);
-                        call.close(Status.Code.PERMISSION_DENIED.toStatus(), new Metadata());
-                        return new ServerCall.Listener<ReqT>() {};
-                    }
-                };
-        try {
-            // TODO(b/372666638): gRPC for java doesn't support vsock for now.
-            int port = 0;
-            mDebianService = new DebianServiceImpl(this);
-            mServer =
-                    OkHttpServerBuilder.forPort(port, InsecureServerCredentials.create())
-                            .intercept(interceptor)
-                            .addService(mDebianService)
-                            .build()
-                            .start();
-        } catch (IOException e) {
-            Log.d(TAG, "grpc server error", e);
-            return;
-        }
-
-        mExecutorService.execute(
-                () -> {
-                    // TODO(b/373533555): we can use mDNS for that.
-                    String debianServicePortFileName = "debian_service_port";
-                    File debianServicePortFile = new File(getFilesDir(), debianServicePortFileName);
-                    try (FileOutputStream writer = new FileOutputStream(debianServicePortFile)) {
-                        writer.write(String.valueOf(mServer.getPort()).getBytes());
-                    } catch (IOException e) {
-                        Log.d(TAG, "cannot write grpc port number", e);
-                    }
-                });
-    }
-
-    public static void stop(Context context) {
-        Intent i = getMyIntent(context);
-        i.setAction(VmLauncherService.ACTION_STOP_VM_LAUNCHER_SERVICE);
-        context.startService(i);
-    }
-
-    @Override
-    public void onDestroy() {
-        if (mPortNotifier != null) {
-            mPortNotifier.stop();
-        }
-        getSystemService(NotificationManager.class).cancelAll();
-        stopDebianServer();
-        if (mVirtualMachine != null) {
-            if (mVirtualMachine.getStatus() == VirtualMachine.STATUS_RUNNING) {
-                try {
-                    mVirtualMachine.stop();
-                    stopForeground(STOP_FOREGROUND_REMOVE);
-                } catch (VirtualMachineException e) {
-                    Log.e(TAG, "failed to stop a VM instance", e);
-                }
-            }
-            mExecutorService.shutdownNow();
-            mExecutorService = null;
-            mVirtualMachine = null;
-        }
-        super.onDestroy();
-    }
-
-    private void stopDebianServer() {
-        if (mDebianService != null) {
-            mDebianService.killForwarderHost();
-        }
-        if (mServer != null) {
-            mServer.shutdown();
-        }
-    }
-}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
new file mode 100644
index 0000000..2796b86
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2024 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.virtualization.terminal
+
+import android.app.Notification
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Context
+import android.content.Intent
+import android.graphics.drawable.Icon
+import android.net.nsd.NsdManager
+import android.net.nsd.NsdServiceInfo
+import android.os.Bundle
+import android.os.Handler
+import android.os.IBinder
+import android.os.Looper
+import android.os.Parcel
+import android.os.ResultReceiver
+import android.os.Trace
+import android.system.virtualmachine.VirtualMachine
+import android.system.virtualmachine.VirtualMachineCustomImageConfig
+import android.system.virtualmachine.VirtualMachineException
+import android.util.Log
+import android.widget.Toast
+import com.android.virtualization.terminal.MainActivity.TAG
+import com.android.virtualization.terminal.Runner.Companion.create
+import com.android.virtualization.terminal.VmLauncherService.VmLauncherServiceCallback
+import io.grpc.Grpc
+import io.grpc.InsecureServerCredentials
+import io.grpc.Metadata
+import io.grpc.Server
+import io.grpc.ServerCall
+import io.grpc.ServerCallHandler
+import io.grpc.ServerInterceptor
+import io.grpc.Status
+import io.grpc.okhttp.OkHttpServerBuilder
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.lang.RuntimeException
+import java.net.InetSocketAddress
+import java.net.SocketAddress
+import java.nio.file.Files
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Executors
+
+class VmLauncherService : Service() {
+    // TODO: using lateinit for some fields to avoid null
+    private var mExecutorService: ExecutorService? = null
+    private var mVirtualMachine: VirtualMachine? = null
+    private var mResultReceiver: ResultReceiver? = null
+    private var mServer: Server? = null
+    private var mDebianService: DebianServiceImpl? = null
+    private var mPortNotifier: PortNotifier? = null
+
+    interface VmLauncherServiceCallback {
+        fun onVmStart()
+
+        fun onVmStop()
+
+        fun onVmError()
+    }
+
+    override fun onBind(intent: Intent?): IBinder? {
+        return null
+    }
+
+    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+        if (intent.action == ACTION_STOP_VM_LAUNCHER_SERVICE) {
+            if (mDebianService != null && mDebianService!!.shutdownDebian()) {
+                // During shutdown, change the notification content to indicate that it's closing
+                val notification = createNotificationForTerminalClose()
+                getSystemService<NotificationManager?>(NotificationManager::class.java)
+                    .notify(this.hashCode(), notification)
+            } else {
+                // If there is no Debian service or it fails to shutdown, just stop the service.
+                stopSelf()
+            }
+            return START_NOT_STICKY
+        }
+        if (mVirtualMachine != null) {
+            Log.d(TAG, "VM instance is already started")
+            return START_NOT_STICKY
+        }
+        mExecutorService = Executors.newCachedThreadPool(TerminalThreadFactory(applicationContext))
+
+        val image = InstalledImage.getDefault(this)
+        val json = ConfigJson.from(this, image.configPath)
+        val configBuilder = json.toConfigBuilder(this)
+        val customImageConfigBuilder = json.toCustomImageConfigBuilder(this)
+        if (overrideConfigIfNecessary(customImageConfigBuilder)) {
+            configBuilder.setCustomImageConfig(customImageConfigBuilder.build())
+        }
+        val config = configBuilder.build()
+
+        Trace.beginSection("vmCreate")
+        val runner: Runner =
+            try {
+                create(this, config)
+            } catch (e: VirtualMachineException) {
+                throw RuntimeException("cannot create runner", e)
+            }
+        Trace.endSection()
+        Trace.beginAsyncSection("debianBoot", 0)
+
+        mVirtualMachine = runner.vm
+        mResultReceiver =
+            intent.getParcelableExtra<ResultReceiver?>(
+                Intent.EXTRA_RESULT_RECEIVER,
+                ResultReceiver::class.java,
+            )
+
+        runner.exitStatus.thenAcceptAsync { success: Boolean ->
+            mResultReceiver?.send(if (success) RESULT_STOP else RESULT_ERROR, null)
+            stopSelf()
+        }
+        val logPath = getFileStreamPath(mVirtualMachine!!.name + ".log").toPath()
+        Logger.setup(mVirtualMachine!!, logPath, mExecutorService!!)
+
+        val notification =
+            intent.getParcelableExtra<Notification?>(EXTRA_NOTIFICATION, Notification::class.java)
+
+        startForeground(this.hashCode(), notification)
+
+        mResultReceiver!!.send(RESULT_START, null)
+
+        mPortNotifier = PortNotifier(this)
+
+        // TODO: dedup this part
+        val nsdManager = getSystemService<NsdManager?>(NsdManager::class.java)
+        val info = NsdServiceInfo()
+        info.serviceType = "_http._tcp"
+        info.serviceName = "ttyd"
+        nsdManager.registerServiceInfoCallback(
+            info,
+            mExecutorService!!,
+            object : NsdManager.ServiceInfoCallback {
+                override fun onServiceInfoCallbackRegistrationFailed(errorCode: Int) {}
+
+                override fun onServiceInfoCallbackUnregistered() {}
+
+                override fun onServiceLost() {}
+
+                override fun onServiceUpdated(info: NsdServiceInfo) {
+                    nsdManager.unregisterServiceInfoCallback(this)
+                    Log.i(TAG, "Service found: $info")
+                    startDebianServer(info.hostAddresses[0].hostAddress)
+                }
+            },
+        )
+
+        return START_NOT_STICKY
+    }
+
+    private fun createNotificationForTerminalClose(): Notification {
+        val stopIntent = Intent()
+        stopIntent.setClass(this, VmLauncherService::class.java)
+        stopIntent.setAction(ACTION_STOP_VM_LAUNCHER_SERVICE)
+        val stopPendingIntent =
+            PendingIntent.getService(
+                this,
+                0,
+                stopIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
+            )
+        val icon = Icon.createWithResource(resources, R.drawable.ic_launcher_foreground)
+        val stopActionText: String? =
+            resources.getString(R.string.service_notification_force_quit_action)
+        val stopNotificationTitle: String? =
+            resources.getString(R.string.service_notification_close_title)
+        return Notification.Builder(this, this.packageName)
+            .setSmallIcon(R.drawable.ic_launcher_foreground)
+            .setContentTitle(stopNotificationTitle)
+            .setOngoing(true)
+            .setSilent(true)
+            .addAction(Notification.Action.Builder(icon, stopActionText, stopPendingIntent).build())
+            .build()
+    }
+
+    private fun overrideConfigIfNecessary(
+        builder: VirtualMachineCustomImageConfig.Builder
+    ): Boolean {
+        var changed = false
+        // TODO: check if ANGLE is enabled for the app.
+        if (Files.exists(ImageArchive.getSdcardPathForTesting().resolve("virglrenderer"))) {
+            builder.setGpuConfig(
+                VirtualMachineCustomImageConfig.GpuConfig.Builder()
+                    .setBackend("virglrenderer")
+                    .setRendererUseEgl(true)
+                    .setRendererUseGles(true)
+                    .setRendererUseGlx(false)
+                    .setRendererUseSurfaceless(true)
+                    .setRendererUseVulkan(false)
+                    .setContextTypes(arrayOf<String>("virgl2"))
+                    .build()
+            )
+            Toast.makeText(this, R.string.virgl_enabled, Toast.LENGTH_SHORT).show()
+            changed = true
+        }
+
+        val image = InstalledImage.getDefault(this)
+        if (image.hasBackup()) {
+            val backup = image.backupFile
+            builder.addDisk(VirtualMachineCustomImageConfig.Disk.RWDisk(backup.toString()))
+            changed = true
+        }
+        return changed
+    }
+
+    private fun startDebianServer(ipAddress: String?) {
+        val interceptor: ServerInterceptor =
+            object : ServerInterceptor {
+                override fun <ReqT, RespT> interceptCall(
+                    call: ServerCall<ReqT?, RespT?>,
+                    headers: Metadata?,
+                    next: ServerCallHandler<ReqT?, RespT?>,
+                ): ServerCall.Listener<ReqT?>? {
+                    val remoteAddr =
+                        call.attributes.get<SocketAddress?>(Grpc.TRANSPORT_ATTR_REMOTE_ADDR)
+                            as InetSocketAddress?
+
+                    if (remoteAddr?.address?.hostAddress == ipAddress) {
+                        // Allow the request only if it is from VM
+                        return next.startCall(call, headers)
+                    }
+                    Log.d(TAG, "blocked grpc request from $remoteAddr")
+                    call.close(Status.Code.PERMISSION_DENIED.toStatus(), Metadata())
+                    return object : ServerCall.Listener<ReqT?>() {}
+                }
+            }
+        try {
+            // TODO(b/372666638): gRPC for java doesn't support vsock for now.
+            val port = 0
+            mDebianService = DebianServiceImpl(this)
+            mServer =
+                OkHttpServerBuilder.forPort(port, InsecureServerCredentials.create())
+                    .intercept(interceptor)
+                    .addService(mDebianService)
+                    .build()
+                    .start()
+        } catch (e: IOException) {
+            Log.d(TAG, "grpc server error", e)
+            return
+        }
+
+        mExecutorService!!.execute(
+            Runnable {
+                // TODO(b/373533555): we can use mDNS for that.
+                val debianServicePortFile = File(filesDir, "debian_service_port")
+                try {
+                    FileOutputStream(debianServicePortFile).use { writer ->
+                        writer.write(mServer!!.port.toString().toByteArray())
+                    }
+                } catch (e: IOException) {
+                    Log.d(TAG, "cannot write grpc port number", e)
+                }
+            }
+        )
+    }
+
+    override fun onDestroy() {
+        mPortNotifier?.stop()
+        getSystemService<NotificationManager?>(NotificationManager::class.java).cancelAll()
+        stopDebianServer()
+        if (mVirtualMachine != null) {
+            if (mVirtualMachine!!.getStatus() == VirtualMachine.STATUS_RUNNING) {
+                try {
+                    mVirtualMachine!!.stop()
+                    stopForeground(STOP_FOREGROUND_REMOVE)
+                } catch (e: VirtualMachineException) {
+                    Log.e(TAG, "failed to stop a VM instance", e)
+                }
+            }
+            mExecutorService?.shutdownNow()
+            mExecutorService = null
+            mVirtualMachine = null
+        }
+        super.onDestroy()
+    }
+
+    private fun stopDebianServer() {
+        mDebianService?.killForwarderHost()
+        mServer?.shutdown()
+    }
+
+    companion object {
+        private const val EXTRA_NOTIFICATION = "EXTRA_NOTIFICATION"
+        private const val ACTION_START_VM_LAUNCHER_SERVICE =
+            "android.virtualization.START_VM_LAUNCHER_SERVICE"
+
+        const val ACTION_STOP_VM_LAUNCHER_SERVICE: String =
+            "android.virtualization.STOP_VM_LAUNCHER_SERVICE"
+
+        private const val RESULT_START = 0
+        private const val RESULT_STOP = 1
+        private const val RESULT_ERROR = 2
+
+        private fun getMyIntent(context: Context): Intent {
+            return Intent(context.getApplicationContext(), VmLauncherService::class.java)
+        }
+
+        @JvmStatic
+        fun run(
+            context: Context,
+            callback: VmLauncherServiceCallback?,
+            notification: Notification?,
+        ) {
+            val i = getMyIntent(context)
+            val resultReceiver: ResultReceiver =
+                object : ResultReceiver(Handler(Looper.myLooper()!!)) {
+                    override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
+                        if (callback == null) {
+                            return
+                        }
+                        when (resultCode) {
+                            RESULT_START -> callback.onVmStart()
+                            RESULT_STOP -> callback.onVmStop()
+                            RESULT_ERROR -> callback.onVmError()
+                        }
+                    }
+                }
+            i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver))
+            i.putExtra(EXTRA_NOTIFICATION, notification)
+            context.startForegroundService(i)
+        }
+
+        private fun getResultReceiverForIntent(r: ResultReceiver): ResultReceiver {
+            val parcel = Parcel.obtain()
+            r.writeToParcel(parcel, 0)
+            parcel.setDataPosition(0)
+            return ResultReceiver.CREATOR.createFromParcel(parcel).also { parcel.recycle() }
+        }
+
+        @JvmStatic
+        fun stop(context: Context) {
+            val i = getMyIntent(context)
+            i.setAction(ACTION_STOP_VM_LAUNCHER_SERVICE)
+            context.startService(i)
+        }
+    }
+}
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index a90c1ff..096d3b5 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -324,7 +324,7 @@
             let tap =
                 if let Some(tap_file) = &config.tap { Some(tap_file.try_clone()?) } else { None };
 
-            run_virtiofs(&config)?;
+            let vhost_fs_devices = run_virtiofs(&config)?;
 
             // If this fails and returns an error, `self` will be left in the `Failed` state.
             let child =
@@ -339,7 +339,13 @@
             let child_clone = child.clone();
             let instance_clone = instance.clone();
             let monitor_vm_exit_thread = Some(thread::spawn(move || {
-                instance_clone.monitor_vm_exit(child_clone, failure_pipe_read, vfio_devices, tap);
+                instance_clone.monitor_vm_exit(
+                    child_clone,
+                    failure_pipe_read,
+                    vfio_devices,
+                    tap,
+                    vhost_fs_devices,
+                );
             }));
 
             if detect_hangup {
@@ -486,6 +492,7 @@
         failure_pipe_read: File,
         vfio_devices: Vec<VfioDevice>,
         tap: Option<File>,
+        vhost_user_devices: Vec<SharedChild>,
     ) {
         let failure_reason_thread = std::thread::spawn(move || {
             // Read the pipe to see if any failure reason is written
@@ -513,6 +520,34 @@
             }
         }
 
+        // In crosvm, when vhost_user frontend is dead, vhost_user backend device will detect and
+        // exit. We can safely wait() for vhost user device after waiting crosvm main
+        // process.
+        for device in vhost_user_devices {
+            match device.wait() {
+                Ok(status) => {
+                    info!("Vhost user device({}) exited with status {}", device.id(), status);
+                    if !status.success() {
+                        if let Some(code) = status.code() {
+                            // vhost_user backend device exit with error code
+                            error!(
+                                "vhost user device({}) exited with error code: {}",
+                                device.id(),
+                                code
+                            );
+                        } else {
+                            // The spawned child process of vhost_user backend device is
+                            // killed by signal
+                            error!("vhost user device({}) killed by signal", device.id());
+                        }
+                    }
+                }
+                Err(e) => {
+                    error!("Error waiting for vhost user device({}) to die: {}", device.id(), e);
+                }
+            }
+        }
+
         let failure_reason = failure_reason_thread.join().expect("failure_reason_thread panic'd");
 
         let mut vm_state = self.vm_state.lock().unwrap();
@@ -915,7 +950,8 @@
     }
 }
 
-fn run_virtiofs(config: &CrosvmConfig) -> io::Result<()> {
+fn run_virtiofs(config: &CrosvmConfig) -> io::Result<Vec<SharedChild>> {
+    let mut devices: Vec<SharedChild> = Vec::new();
     for shared_path in &config.shared_paths {
         if shared_path.app_domain {
             continue;
@@ -947,9 +983,10 @@
 
         let result = SharedChild::spawn(&mut command)?;
         info!("Spawned virtiofs crosvm({})", result.id());
+        devices.push(result);
     }
 
-    Ok(())
+    Ok(devices)
 }
 
 /// Starts an instance of `crosvm` to manage a new VM.
diff --git a/build/debian/build.sh b/build/debian/build.sh
index 3db6a40..3f33ec8 100755
--- a/build/debian/build.sh
+++ b/build/debian/build.sh
@@ -57,18 +57,16 @@
 			;;
 	esac
 	if [[ "${*:$OPTIND:1}" ]]; then
-		built_image="${*:$OPTIND:1}"
+		output="${*:$OPTIND:1}"
 	fi
 }
 
 prepare_build_id() {
-	local filename=build_id
 	if [ -z "${KOKORO_BUILD_NUMBER}" ]; then
-		echo eng-$(hostname)-$(date --utc) > ${filename}
+		echo eng-$(hostname)-$(date --utc)
 	else
-		echo ${KOKORO_BUILD_NUMBER} > ${filename}
+		echo ${KOKORO_BUILD_NUMBER}
 	fi
-	echo ${filename}
 }
 
 install_prerequisites() {
@@ -302,17 +300,23 @@
 }
 
 run_fai() {
-	local out="${built_image}"
+	local out="${raw_disk_image}"
 	make -C "${debian_cloud_image}" "image_bookworm_nocloud_${debian_arch}"
 	mv "${debian_cloud_image}/image_bookworm_nocloud_${debian_arch}.raw" "${out}"
 }
 
-extract_partitions() {
-	root_partition_num=1
-	bios_partition_num=14
-	efi_partition_num=15
+generate_output_package() {
+	fdisk -l "${raw_disk_image}"
+	local vm_config="$(realpath $(dirname "$0"))/vm_config.json.${arch}"
+	local root_partition_num=1
+	local bios_partition_num=14
+	local efi_partition_num=15
 
-	loop=$(losetup -f --show --partscan $built_image)
+	pushd ${workdir} > /dev/null
+
+	echo ${build_id} > build_id
+
+	loop=$(losetup -f --show --partscan $raw_disk_image)
 	dd if="${loop}p$root_partition_num" of=root_part
 	if [[ "$arch" == "x86_64" ]]; then
 		dd if="${loop}p$bios_partition_num" of=bios_part
@@ -320,11 +324,38 @@
 	dd if="${loop}p$efi_partition_num" of=efi_part
 	losetup -d "${loop}"
 
-	sed -i "s/{root_part_guid}/$(sfdisk --part-uuid $built_image $root_partition_num)/g" vm_config.json
+	cp ${vm_config} vm_config.json
+	sed -i "s/{root_part_guid}/$(sfdisk --part-uuid $raw_disk_image $root_partition_num)/g" vm_config.json
 	if [[ "$arch" == "x86_64" ]]; then
-		sed -i "s/{bios_part_guid}/$(sfdisk --part-uuid $built_image $bios_partition_num)/g" vm_config.json
+		sed -i "s/{bios_part_guid}/$(sfdisk --part-uuid $raw_disk_image $bios_partition_num)/g" vm_config.json
 	fi
-	sed -i "s/{efi_part_guid}/$(sfdisk --part-uuid $built_image $efi_partition_num)/g" vm_config.json
+	sed -i "s/{efi_part_guid}/$(sfdisk --part-uuid $raw_disk_image $efi_partition_num)/g" vm_config.json
+
+	images=()
+	if [[ "$arch" == "aarch64" ]]; then
+		images+=(
+			root_part
+			efi_part
+		)
+	# TODO(b/365955006): remove these lines when uboot supports x86_64 EFI application
+	elif [[ "$arch" == "x86_64" ]]; then
+		rm -f vmlinuz initrd.img
+		virt-get-kernel -a "${raw_disk_image}"
+		mv vmlinuz* vmlinuz
+		mv initrd.img* initrd.img
+		images+=(
+			bios_part
+			root_part
+			efi_part
+			vmlinuz
+			initrd.img
+		)
+	fi
+
+	popd > /dev/null
+
+	# --sparse option isn't supported in apache-commons-compress
+	tar czv -f ${output} -C ${workdir} build_id "${images[@]}" vm_config.json
 }
 
 clean_up() {
@@ -334,8 +365,9 @@
 set -e
 trap clean_up EXIT
 
-built_image=image.raw
+output=images.tar.gz
 workdir=$(mktemp -d)
+raw_disk_image=${workdir}/image.raw
 build_id=$(prepare_build_id)
 debian_cloud_image=${workdir}/debian_cloud_image
 debian_version=bookworm
@@ -353,32 +385,4 @@
 copy_android_config
 package_custom_kernel
 run_fai
-fdisk -l "${built_image}"
-images=()
-
-cp "$(dirname "$0")/vm_config.json.${arch}" vm_config.json
-
-extract_partitions
-
-if [[ "$arch" == "aarch64" ]]; then
-	images+=(
-		root_part
-		efi_part
-	)
-# TODO(b/365955006): remove these lines when uboot supports x86_64 EFI application
-elif [[ "$arch" == "x86_64" ]]; then
-	rm -f vmlinuz initrd.img
-	virt-get-kernel -a "${built_image}"
-	mv vmlinuz* vmlinuz
-	mv initrd.img* initrd.img
-	images+=(
-		bios_part
-		root_part
-		efi_part
-		vmlinuz
-		initrd.img
-	)
-fi
-
-# --sparse option isn't supported in apache-commons-compress
-tar czv -f images.tar.gz ${build_id} "${images[@]}" vm_config.json
+generate_output_package
diff --git a/docs/getting_started.md b/docs/getting_started.md
index 0a7cca6..03657ed 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -9,7 +9,7 @@
 * aosp\_oriole (Pixel 6)
 * aosp\_raven (Pixel 6 Pro)
 * aosp\_felix (Pixel Fold)
-* aosp\_tangopro (Pixel Tablet)
+* aosp\_tangorpro (Pixel Tablet)
 * aosp\_cf\_x86\_64\_phone (Cuttlefish a.k.a. Cloud Android). Follow [this
   instruction](https://source.android.com/docs/setup/create/cuttlefish-use) to
   use.
diff --git a/libs/cstr/rules.mk b/libs/cstr/rules.mk
new file mode 100644
index 0000000..2309c30
--- /dev/null
+++ b/libs/cstr/rules.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2024 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+SRC_DIR := packages/modules/Virtualization/libs/cstr
+
+MODULE_SRCS := $(SRC_DIR)/src/lib.rs
+
+MODULE_CRATE_NAME := cstr
+
+MODULE_RUST_EDITION := 2021
+
+include make/library.mk
diff --git a/libs/libavf/Android.bp b/libs/libavf/Android.bp
index 079f4ae..b583e21 100644
--- a/libs/libavf/Android.bp
+++ b/libs/libavf/Android.bp
@@ -10,6 +10,7 @@
     source_stem: "bindings",
     bindgen_flags: ["--default-enum-style rust"],
     apex_available: ["com.android.virt"],
+    visibility: ["//packages/modules/Virtualization/tests/vts"],
 }
 
 rust_defaults {
diff --git a/libs/libavf/include/android/virtualization.h b/libs/libavf/include/android/virtualization.h
index 6b54bf7..ef57325 100644
--- a/libs/libavf/include/android/virtualization.h
+++ b/libs/libavf/include/android/virtualization.h
@@ -70,7 +70,13 @@
                                      const char* _Nonnull name) __INTRODUCED_IN(36);
 
 /**
- * Set an instance ID of a virtual machine.
+ * Set an instance ID of a virtual machine. Every virtual machine is identified by a unique
+ * `instanceId` which the virtual machine uses as its persistent identity while performing stateful
+ * operations that are expected to outlast single boot of the VM. For example, some virtual machines
+ * use it as a `Id` for storing secrets in Secretkeeper, which are retrieved on next boot of th VM.
+ *
+ * The `instanceId` is expected to be re-used for the VM instance with an associated state (secret,
+ * encrypted storage) - i.e., rebooting the VM must not change the instanceId.
  *
  * \param config a virtual machine config object.
  * \param instanceId a pointer to a 64-byte buffer for the instance ID.
diff --git a/libs/libfdt/bindgen/rules.mk b/libs/libfdt/bindgen/rules.mk
new file mode 100644
index 0000000..130a317
--- /dev/null
+++ b/libs/libfdt/bindgen/rules.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2024 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LOCAL_DIR)/src/lib.rs
+
+MODULE_CRATE_NAME := libfdt_bindgen
+
+MODULE_DEPS += \
+	external/dtc/libfdt \
+
+MODULE_BINDGEN_ALLOW_FUNCTIONS := \
+	fdt_.* \
+
+MODULE_BINDGEN_ALLOW_VARS := \
+	FDT_.* \
+
+MODULE_BINDGEN_ALLOW_TYPES := \
+	fdt_.* \
+
+MODULE_BINDGEN_SRC_HEADER := $(LOCAL_DIR)/fdt.h
+
+include make/library.mk
diff --git a/libs/libfdt/bindgen/src/lib.rs b/libs/libfdt/bindgen/src/lib.rs
new file mode 100644
index 0000000..015132b
--- /dev/null
+++ b/libs/libfdt/bindgen/src/lib.rs
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+//! # Interface library for libfdt.
+
+#![no_std]
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+include!(env!("BINDGEN_INC_FILE"));
diff --git a/libs/libfdt/rules.mk b/libs/libfdt/rules.mk
new file mode 100644
index 0000000..2b4e470
--- /dev/null
+++ b/libs/libfdt/rules.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2024 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+SRC_DIR := packages/modules/Virtualization/libs/libfdt
+
+MODULE_SRCS := $(SRC_DIR)/src/lib.rs
+
+MODULE_CRATE_NAME := libfdt
+
+MODULE_RUST_EDITION := 2021
+
+MODULE_LIBRARY_DEPS += \
+	external/dtc/libfdt \
+	packages/modules/Virtualization/libs/cstr \
+	packages/modules/Virtualization/libs/libfdt/bindgen \
+	$(call FIND_CRATE,zerocopy) \
+	$(call FIND_CRATE,static_assertions) \
+
+MODULE_RUST_USE_CLIPPY := true
+
+include make/library.mk
diff --git a/tests/hostside/Android.bp b/tests/hostside/Android.bp
index 48e369c..0966c20 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -2,14 +2,9 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-java_test_host {
-    name: "MicrodroidHostTestCases",
+java_defaults {
+    name: "MicrodroidHostTestCases.default",
     srcs: ["java/**/*.java"],
-    test_suites: [
-        "cts",
-        "general-tests",
-        "pts",
-    ],
     libs: [
         "androidx.annotation_annotation",
         "tradefed",
@@ -21,27 +16,6 @@
         "microdroid_payload_metadata",
     ],
     per_testcase_directory: true,
-    device_common_data: [
-        ":MicrodroidTestApp",
-        ":MicrodroidTestAppUpdated",
-        ":microdroid_general_sepolicy.conf",
-        ":test.com.android.virt.pem",
-        ":test2.com.android.virt.pem",
-        "java/**/goldens/dt_dump_*",
-    ],
-    data_native_bins: [
-        "sepolicy-analyze",
-        // For re-sign test
-        "avbtool",
-        "img2simg",
-        "initrd_bootconfig",
-        "lpmake",
-        "lpunpack",
-        "lz4",
-        "sign_virt_apex",
-        "simg2img",
-        "dtc",
-    ],
     // java_test_host doesn't have data_native_libs but jni_libs can be used to put
     // native modules under ./lib directory.
     // This works because host tools have rpath (../lib and ./lib).
@@ -58,3 +32,78 @@
         "libz",
     ],
 }
+
+DEVICE_DATA = [
+    ":MicrodroidTestApp",
+    ":MicrodroidTestAppUpdated",
+    ":microdroid_general_sepolicy.conf",
+    ":test.com.android.virt.pem",
+    ":test2.com.android.virt.pem",
+    "java/**/goldens/dt_dump_*",
+]
+
+BINS = [
+    "sepolicy-analyze",
+    // For re-sign test
+    "avbtool",
+    "img2simg",
+    "initrd_bootconfig",
+    "lpmake",
+    "lpunpack",
+    "lz4",
+    "sign_virt_apex",
+    "simg2img",
+    "dtc",
+]
+
+java_test_host {
+    name: "MicrodroidHostTestCases",
+    defaults: ["MicrodroidHostTestCases.default"],
+    test_config: "AndroidTest.xml",
+    test_suites: [
+        "general-tests",
+        "pts",
+    ],
+    device_common_data: DEVICE_DATA,
+    data_native_bins: BINS,
+}
+
+java_test_host {
+    name: "MicrodroidHostTestCases.CTS",
+    defaults: ["MicrodroidHostTestCases.default"],
+    test_config: ":MicrodroidHostTestCases.CTS.config",
+    test_suites: ["cts"],
+    device_common_data: DEVICE_DATA,
+    data_native_bins: BINS,
+}
+
+java_test_host {
+    name: "MicrodroidHostTestCases.VTS",
+    defaults: ["MicrodroidHostTestCases.default"],
+    test_config: ":MicrodroidHostTestCases.VTS.config",
+    test_suites: ["vts"],
+    device_common_data: DEVICE_DATA,
+    data_native_bins: BINS,
+}
+
+genrule {
+    name: "MicrodroidHostTestCases.CTS.config",
+    srcs: ["AndroidTest.xml"],
+    out: ["out.xml"],
+    cmd: "sed " +
+        "-e 's/<!-- PLACEHOLDER_FOR_ANNOTATION -->/" +
+        "<option name=\"include-annotation\" value=\"com.android.compatibility.common.util.CddTest\" \\/>/' " +
+        "-e 's/MicrodroidHostTestCases.jar/MicrodroidHostTestCases.CTS.jar/' " +
+        "$(in) > $(out)",
+}
+
+genrule {
+    name: "MicrodroidHostTestCases.VTS.config",
+    srcs: ["AndroidTest.xml"],
+    out: ["out.xml"],
+    cmd: "sed " +
+        "-e 's/<!-- PLACEHOLDER_FOR_ANNOTATION -->/" +
+        "<option name=\"include-annotation\" value=\"com.android.compatibility.common.util.VsrTest\" \\/>/' " +
+        "-e 's/MicrodroidHostTestCases.jar/MicrodroidHostTestCases.VTS.jar/' " +
+        "$(in) > $(out)",
+}
diff --git a/tests/hostside/AndroidTest.xml b/tests/hostside/AndroidTest.xml
index f77def3..c277865 100644
--- a/tests/hostside/AndroidTest.xml
+++ b/tests/hostside/AndroidTest.xml
@@ -32,4 +32,6 @@
     <!-- Controller that will skip the module if a native bridge situation is detected -->
     <!-- For example: module wants to run arm and device is x86 -->
     <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
+
+    <!-- PLACEHOLDER_FOR_ANNOTATION -->
 </configuration>
diff --git a/tests/vts/Android.bp b/tests/vts/Android.bp
new file mode 100644
index 0000000..c8e2523
--- /dev/null
+++ b/tests/vts/Android.bp
@@ -0,0 +1,36 @@
+prebuilt_etc {
+    name: "vts_libavf_test_kernel",
+    filename: "rialto.bin",
+    src: ":empty_file",
+    target: {
+        android_arm64: {
+            src: ":rialto_signed",
+        },
+    },
+    installable: false,
+    visibility: ["//visibility:private"],
+}
+
+rust_test {
+    name: "vts_libavf_test",
+    crate_name: "vts_libavf_test",
+    srcs: ["src/vts_libavf_test.rs"],
+    rustlibs: [
+        "libanyhow",
+        "libavf_bindgen",
+        "libciborium",
+        "liblog_rust",
+        "libhypervisor_props",
+        "libscopeguard",
+        "libservice_vm_comm",
+        "libvsock",
+    ],
+    shared_libs: ["libavf"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    data: [":vts_libavf_test_kernel"],
+    test_config: "AndroidTest.xml",
+    compile_multilib: "first",
+}
diff --git a/tests/vts/AndroidTest.xml b/tests/vts/AndroidTest.xml
new file mode 100644
index 0000000..75c8d31
--- /dev/null
+++ b/tests/vts/AndroidTest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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.
+-->
+<configuration description="Runs vts_libavf_test.">
+    <option name="test-suite-tag" value="vts" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="vts_libavf_test->/data/local/tmp/vts_libavf_test" />
+        <option name="push" value="rialto.bin->/data/local/tmp/rialto.bin" />
+    </target_preparer>
+
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.ArchModuleController">
+        <option name="arch" value="arm64" />
+    </object>
+
+    <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+        <option name="test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="vts_libavf_test" />
+        <!-- rialto uses a fixed port number for the host, can't run two tests at the same time -->
+        <option name="native-test-flag" value="--test-threads=1" />
+    </test>
+</configuration>
diff --git a/tests/vts/src/vts_libavf_test.rs b/tests/vts/src/vts_libavf_test.rs
new file mode 100644
index 0000000..e30c175
--- /dev/null
+++ b/tests/vts/src/vts_libavf_test.rs
@@ -0,0 +1,196 @@
+// Copyright 2024 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.
+
+//! Tests running a VM with LLNDK
+
+use anyhow::{bail, ensure, Context, Result};
+use log::info;
+use std::ffi::CStr;
+use std::fs::File;
+use std::io::{self, BufWriter, Write};
+use std::os::fd::IntoRawFd;
+use std::time::{Duration, Instant};
+use vsock::{VsockListener, VsockStream, VMADDR_CID_HOST};
+
+use avf_bindgen::*;
+use service_vm_comm::{Request, Response, ServiceVmRequest, VmType};
+
+const VM_MEMORY_MB: i32 = 16;
+const WRITE_BUFFER_CAPACITY: usize = 512;
+
+const LISTEN_TIMEOUT: Duration = Duration::from_secs(10);
+const READ_TIMEOUT: Duration = Duration::from_secs(10);
+const WRITE_TIMEOUT: Duration = Duration::from_secs(10);
+const STOP_TIMEOUT: timespec = timespec { tv_sec: 10, tv_nsec: 0 };
+
+/// Processes the request in the service VM.
+fn process_request(vsock_stream: &mut VsockStream, request: Request) -> Result<Response> {
+    write_request(vsock_stream, &ServiceVmRequest::Process(request))?;
+    read_response(vsock_stream)
+}
+
+/// Sends the request to the service VM.
+fn write_request(vsock_stream: &mut VsockStream, request: &ServiceVmRequest) -> Result<()> {
+    let mut buffer = BufWriter::with_capacity(WRITE_BUFFER_CAPACITY, vsock_stream);
+    ciborium::into_writer(request, &mut buffer)?;
+    buffer.flush().context("Failed to flush the buffer")?;
+    Ok(())
+}
+
+/// Reads the response from the service VM.
+fn read_response(vsock_stream: &mut VsockStream) -> Result<Response> {
+    let response: Response = ciborium::from_reader(vsock_stream)
+        .context("Failed to read the response from the service VM")?;
+    Ok(response)
+}
+
+fn listen_from_guest(port: u32) -> Result<VsockStream> {
+    let vsock_listener =
+        VsockListener::bind_with_cid_port(VMADDR_CID_HOST, port).context("Failed to bind vsock")?;
+    vsock_listener.set_nonblocking(true).context("Failed to set nonblocking")?;
+    let start_time = Instant::now();
+    loop {
+        if start_time.elapsed() >= LISTEN_TIMEOUT {
+            bail!("Timeout while listening");
+        }
+        match vsock_listener.accept() {
+            Ok((vsock_stream, _peer_addr)) => return Ok(vsock_stream),
+            Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
+                std::thread::sleep(Duration::from_millis(100));
+            }
+            Err(e) => bail!("Failed to listen: {e:?}"),
+        }
+    }
+}
+
+fn run_rialto(protected_vm: bool) -> Result<()> {
+    let kernel_file =
+        File::open("/data/local/tmp/rialto.bin").context("Failed to open kernel file")?;
+    let kernel_fd = kernel_file.into_raw_fd();
+
+    // SAFETY: AVirtualMachineRawConfig_create() isn't unsafe but rust_bindgen forces it to be seen
+    // as unsafe
+    let config = unsafe { AVirtualMachineRawConfig_create() };
+
+    info!("raw config created");
+
+    // SAFETY: config is the only reference to a valid object
+    unsafe {
+        AVirtualMachineRawConfig_setName(
+            config,
+            CStr::from_bytes_with_nul(b"vts_libavf_test_rialto\0").unwrap().as_ptr(),
+        );
+        AVirtualMachineRawConfig_setKernel(config, kernel_fd);
+        AVirtualMachineRawConfig_setProtectedVm(config, protected_vm);
+        AVirtualMachineRawConfig_setMemoryMiB(config, VM_MEMORY_MB);
+    }
+
+    let mut vm = std::ptr::null_mut();
+    let mut service = std::ptr::null_mut();
+
+    ensure!(
+        // SAFETY: &mut service is a valid pointer to *AVirtualizationService
+        unsafe { AVirtualizationService_create(&mut service, false) } == 0,
+        "AVirtualizationService_create failed"
+    );
+
+    scopeguard::defer! {
+        // SAFETY: service is a valid pointer to AVirtualizationService
+        unsafe { AVirtualizationService_destroy(service); }
+    }
+
+    ensure!(
+        // SAFETY: &mut vm is a valid pointer to *AVirtualMachine
+        unsafe {
+            AVirtualMachine_createRaw(
+                service, config, -1, // console_in
+                -1, // console_out
+                -1, // log
+                &mut vm,
+            )
+        } == 0,
+        "AVirtualMachine_createRaw failed"
+    );
+
+    scopeguard::defer! {
+        // SAFETY: vm is a valid pointer to AVirtualMachine
+        unsafe { AVirtualMachine_destroy(vm); }
+    }
+
+    info!("vm created");
+
+    let vm_type = if protected_vm { VmType::ProtectedVm } else { VmType::NonProtectedVm };
+
+    let listener_thread = std::thread::spawn(move || listen_from_guest(vm_type.port()));
+
+    // SAFETY: vm is the only reference to a valid object
+    unsafe {
+        AVirtualMachine_start(vm);
+    }
+
+    info!("VM started");
+
+    let mut vsock_stream = listener_thread.join().unwrap()?;
+    vsock_stream.set_read_timeout(Some(READ_TIMEOUT))?;
+    vsock_stream.set_write_timeout(Some(WRITE_TIMEOUT))?;
+
+    info!("client connected");
+
+    let request_data = vec![1, 2, 3, 4, 5];
+    let expected_data = vec![5, 4, 3, 2, 1];
+    let response = process_request(&mut vsock_stream, Request::Reverse(request_data))
+        .context("Failed to process request")?;
+    let Response::Reverse(reversed_data) = response else {
+        bail!("Expected Response::Reverse but was {response:?}");
+    };
+    ensure!(reversed_data == expected_data, "Expected {expected_data:?} but was {reversed_data:?}");
+
+    info!("request processed");
+
+    write_request(&mut vsock_stream, &ServiceVmRequest::Shutdown)
+        .context("Failed to send shutdown")?;
+
+    info!("shutdown sent");
+
+    let mut stop_reason = AVirtualMachineStopReason::AVIRTUAL_MACHINE_UNRECOGNISED;
+    ensure!(
+        // SAFETY: vm is the only reference to a valid object
+        unsafe { AVirtualMachine_waitForStop(vm, &STOP_TIMEOUT, &mut stop_reason) },
+        "AVirtualMachine_waitForStop failed"
+    );
+
+    info!("stopped");
+
+    Ok(())
+}
+
+#[test]
+fn test_run_rialto_protected() -> Result<()> {
+    if hypervisor_props::is_protected_vm_supported()? {
+        run_rialto(true /* protected_vm */)
+    } else {
+        info!("pVMs are not supported on device. skipping test");
+        Ok(())
+    }
+}
+
+#[test]
+fn test_run_rialto_non_protected() -> Result<()> {
+    if hypervisor_props::is_vm_supported()? {
+        run_rialto(false /* protected_vm */)
+    } else {
+        info!("non-pVMs are not supported on device. skipping test");
+        Ok(())
+    }
+}
