Merge "Support deleting param for preconnected sessions" into main
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Application.kt b/android/TerminalApp/java/com/android/virtualization/terminal/Application.kt
index efe651e..9f4909d 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/Application.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/Application.kt
@@ -18,12 +18,21 @@
 import android.app.Application as AndroidApplication
 import android.app.NotificationChannel
 import android.app.NotificationManager
+import android.content.ComponentName
 import android.content.Context
+import android.content.Intent
+import android.content.ServiceConnection
+import android.os.IBinder
+import androidx.lifecycle.DefaultLifecycleObserver
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.ProcessLifecycleOwner
 
 public class Application : AndroidApplication() {
     override fun onCreate() {
         super.onCreate()
         setupNotificationChannels()
+        val lifecycleObserver = ApplicationLifecycleObserver()
+        ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleObserver)
     }
 
     private fun setupNotificationChannels() {
@@ -52,4 +61,53 @@
 
         fun getInstance(c: Context): Application = c.getApplicationContext() as Application
     }
+
+    /**
+     * Observes application lifecycle events and interacts with the VmLauncherService to manage
+     * virtual machine state based on application lifecycle transitions. This class binds to the
+     * VmLauncherService and notifies it of application lifecycle events (onStart, onStop), allowing
+     * the service to manage the VM accordingly.
+     */
+    inner class ApplicationLifecycleObserver() : DefaultLifecycleObserver {
+        private var vmLauncherService: VmLauncherService? = null
+        private val connection =
+            object : ServiceConnection {
+                override fun onServiceConnected(className: ComponentName, service: IBinder) {
+                    val binder = service as VmLauncherService.VmLauncherServiceBinder
+                    vmLauncherService = binder.getService()
+                }
+
+                override fun onServiceDisconnected(arg0: ComponentName) {
+                    vmLauncherService = null
+                }
+            }
+
+        override fun onCreate(owner: LifecycleOwner) {
+            super.onCreate(owner)
+            bindToVmLauncherService()
+        }
+
+        override fun onStart(owner: LifecycleOwner) {
+            super.onStart(owner)
+            vmLauncherService?.processAppLifeCycleEvent(ApplicationLifeCycleEvent.APP_ON_START)
+        }
+
+        override fun onStop(owner: LifecycleOwner) {
+            vmLauncherService?.processAppLifeCycleEvent(ApplicationLifeCycleEvent.APP_ON_STOP)
+            super.onStop(owner)
+        }
+
+        override fun onDestroy(owner: LifecycleOwner) {
+            if (vmLauncherService != null) {
+                this@Application.unbindService(connection)
+                vmLauncherService = null
+            }
+            super.onDestroy(owner)
+        }
+
+        fun bindToVmLauncherService() {
+            val intent = Intent(this@Application, VmLauncherService::class.java)
+            this@Application.bindService(intent, connection, 0) // No BIND_AUTO_CREATE
+        }
+    }
 }
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ApplicationLifeCycleEvent.kt b/android/TerminalApp/java/com/android/virtualization/terminal/ApplicationLifeCycleEvent.kt
new file mode 100644
index 0000000..4e26c3c
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ApplicationLifeCycleEvent.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2025 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
+
+enum class ApplicationLifeCycleEvent {
+    APP_ON_START,
+    APP_ON_STOP,
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
index 017ff89..be1f922 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.kt
@@ -65,6 +65,14 @@
         }
     }
 
+    /** Returns path to the archive. */
+    fun getPath(): String {
+        return when (source) {
+            is UrlSource -> source.value.toString()
+            is PathSource -> source.value.toString()
+        }
+    }
+
     /** Returns size of the archive in bytes */
     @Throws(IOException::class)
     fun getSize(): Long {
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.kt
index 7180e87..01c3880 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.kt
@@ -150,21 +150,26 @@
 
     private fun downloadFromSdcard(): Boolean {
         val archive = fromSdCard()
+        val archive_path = archive.getPath()
 
         // Installing from sdcard is preferred, but only supported only in debuggable build.
-        if (Build.isDebuggable() && archive.exists()) {
-            Log.i(TAG, "trying to install /sdcard/linux/images.tar.gz")
+        if (!Build.isDebuggable()) {
+            Log.i(TAG, "Non-debuggable build doesn't support installation from $archive_path")
+            return false
+        }
+        if (!archive.exists()) {
+            return false
+        }
 
-            val dest = getDefault(this).installDir
-            try {
-                archive.installTo(dest, null)
-                Log.i(TAG, "image is installed from /sdcard/linux/images.tar.gz")
-                return true
-            } catch (e: IOException) {
-                Log.i(TAG, "Failed to install /sdcard/linux/images.tar.gz", e)
-            }
-        } else {
-            Log.i(TAG, "Non-debuggable build doesn't support installation from /sdcard/linux")
+        Log.i(TAG, "trying to install $archive_path")
+
+        val dest = getDefault(this).installDir
+        try {
+            archive.installTo(dest, null)
+            Log.i(TAG, "image is installed from $archive_path")
+            return true
+        } catch (e: IOException) {
+            Log.i(TAG, "Failed to install $archive_path", e)
         }
         return false
     }
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
index 6301da4..4bfad62 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
@@ -62,6 +62,12 @@
 import java.util.concurrent.Executors
 
 class VmLauncherService : Service() {
+    inner class VmLauncherServiceBinder : android.os.Binder() {
+        fun getService(): VmLauncherService = this@VmLauncherService
+    }
+
+    private val binder = VmLauncherServiceBinder()
+
     // TODO: using lateinit for some fields to avoid null
     private var executorService: ExecutorService? = null
     private var virtualMachine: VirtualMachine? = null
@@ -79,7 +85,32 @@
     }
 
     override fun onBind(intent: Intent?): IBinder? {
-        return null
+        return binder
+    }
+
+    /**
+     * Processes application lifecycle events and adjusts the virtual machine's memory balloon
+     * accordingly.
+     *
+     * @param event The application lifecycle event.
+     */
+    fun processAppLifeCycleEvent(event: ApplicationLifeCycleEvent) {
+        when (event) {
+            // When the app starts, reset the memory balloon to 0%.
+            // This gives the app maximum available memory.
+            ApplicationLifeCycleEvent.APP_ON_START -> {
+                virtualMachine?.setMemoryBalloonByPercent(0)
+            }
+            ApplicationLifeCycleEvent.APP_ON_STOP -> {
+                // When the app stops, inflate the memory balloon to 10%.
+                // This allows the system to reclaim memory while the app is in the background.
+                // TODO(b/400590341) Inflate the balloon while the application remains Stop status.
+                virtualMachine?.setMemoryBalloonByPercent(10)
+            }
+            else -> {
+                Log.e(TAG, "unrecognized lifecycle event: $event")
+            }
+        }
     }
 
     override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
diff --git a/android/TerminalApp/res/values-af/strings.xml b/android/TerminalApp/res/values-af/strings.xml
index 6928614..d906b07 100644
--- a/android/TerminalApp/res/values-af/strings.xml
+++ b/android/TerminalApp/res/values-af/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> is geaktiveer"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Take wat lank neem"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Stelselgebeurtenisse"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Tab"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-az/strings.xml b/android/TerminalApp/res/values-az/strings.xml
index 9b84701..b3ad1f6 100644
--- a/android/TerminalApp/res/values-az/strings.xml
+++ b/android/TerminalApp/res/values-az/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> aktivləşdirilib"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Uzunmüddətli tapşırıqlar"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistem tədbirləri"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Tab"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-b+sr+Latn/strings.xml b/android/TerminalApp/res/values-b+sr+Latn/strings.xml
index 1bdef6d..6ec0a06 100644
--- a/android/TerminalApp/res/values-b+sr+Latn/strings.xml
+++ b/android/TerminalApp/res/values-b+sr+Latn/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> je omogućen"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dugotrajni zadaci"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistemski događaji"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Kartica"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-be/strings.xml b/android/TerminalApp/res/values-be/strings.xml
index a056517..e78ba9c 100644
--- a/android/TerminalApp/res/values-be/strings.xml
+++ b/android/TerminalApp/res/values-be/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"Модуль <xliff:g id="ID_1">VirGL</xliff:g> уключаны"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Працяглыя задачы"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Сістэмныя падзеі"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Укладка"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-bn/strings.xml b/android/TerminalApp/res/values-bn/strings.xml
index e81c3ea..f871f00 100644
--- a/android/TerminalApp/res/values-bn/strings.xml
+++ b/android/TerminalApp/res/values-bn/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> চালু করা আছে"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"দীর্ঘ সময় ধরে চালানো টাস্ক"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"সিস্টেম ইভেন্ট"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"ট্যাব"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-bs/strings.xml b/android/TerminalApp/res/values-bs/strings.xml
index 914cff9..1971481 100644
--- a/android/TerminalApp/res/values-bs/strings.xml
+++ b/android/TerminalApp/res/values-bs/strings.xml
@@ -90,5 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"Omogućeno: <xliff:g id="ID_1">VirGL</xliff:g>"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dugotrajni zadaci"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Događaji sistema"</string>
-    <string name="tab_default_title" msgid="2300417689389397930">"Tab"</string>
+    <string name="tab_default_title" msgid="2300417689389397930">"Kartica"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ca/strings.xml b/android/TerminalApp/res/values-ca/strings.xml
index 7cb50d9..db72829 100644
--- a/android/TerminalApp/res/values-ca/strings.xml
+++ b/android/TerminalApp/res/values-ca/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> està activat"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tasques de llarga durada"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Esdeveniments del sistema"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Tab"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-cs/strings.xml b/android/TerminalApp/res/values-cs/strings.xml
index 41e7756..14fcd27 100644
--- a/android/TerminalApp/res/values-cs/strings.xml
+++ b/android/TerminalApp/res/values-cs/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"Modul <xliff:g id="ID_1">VirGL</xliff:g> je aktivován"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dlouho spuštěné úlohy"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systémové události"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Karta"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-da/strings.xml b/android/TerminalApp/res/values-da/strings.xml
index e3eb0a8..4e153ef 100644
--- a/android/TerminalApp/res/values-da/strings.xml
+++ b/android/TerminalApp/res/values-da/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> er aktiveret"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Længerevarende opgaver"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systemhændelser"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Fane"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-es/strings.xml b/android/TerminalApp/res/values-es/strings.xml
index 3cabc84..76ebaf9 100644
--- a/android/TerminalApp/res/values-es/strings.xml
+++ b/android/TerminalApp/res/values-es/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> se ha habilitado"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tareas de larga duración"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Eventos del sistema"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Tab"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-et/strings.xml b/android/TerminalApp/res/values-et/strings.xml
index 4adaa33..5234a4e 100644
--- a/android/TerminalApp/res/values-et/strings.xml
+++ b/android/TerminalApp/res/values-et/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> on lubatud"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Pikalt kestvad ülesanded"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Süsteemisündmused"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Tabulaator"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-eu/strings.xml b/android/TerminalApp/res/values-eu/strings.xml
index 63aa7bb..403c305 100644
--- a/android/TerminalApp/res/values-eu/strings.xml
+++ b/android/TerminalApp/res/values-eu/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> gaituta dago"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Luze exekutatzen diren zereginak"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistemako gertaerak"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Fitxa"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-fr-rCA/strings.xml b/android/TerminalApp/res/values-fr-rCA/strings.xml
index 3660576..d4c1235 100644
--- a/android/TerminalApp/res/values-fr-rCA/strings.xml
+++ b/android/TerminalApp/res/values-fr-rCA/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> est activé"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tâches de longue durée"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Événements système"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Onglet"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-hu/strings.xml b/android/TerminalApp/res/values-hu/strings.xml
index afde089..bd4fe52 100644
--- a/android/TerminalApp/res/values-hu/strings.xml
+++ b/android/TerminalApp/res/values-hu/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"A(z) <xliff:g id="ID_1">VirGL</xliff:g> engedélyezve van"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Hosszan futó feladatok"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Rendszeresemények"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Lap"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-hy/strings.xml b/android/TerminalApp/res/values-hy/strings.xml
index 0df7a91..d33642c 100644
--- a/android/TerminalApp/res/values-hy/strings.xml
+++ b/android/TerminalApp/res/values-hy/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g>-ը միացված է"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Երկար աշխատող առաջադրանքներ"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Համակարգի իրադարձություններ"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Ներդիր"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-is/strings.xml b/android/TerminalApp/res/values-is/strings.xml
index 4d3d7a6..e7aad2b 100644
--- a/android/TerminalApp/res/values-is/strings.xml
+++ b/android/TerminalApp/res/values-is/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"Kveikt er á <xliff:g id="ID_1">VirGL</xliff:g>"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Langvarandi verkefni"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Kerfistilvik"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Flipi"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-iw/strings.xml b/android/TerminalApp/res/values-iw/strings.xml
index 6b56764..6d2a0f3 100644
--- a/android/TerminalApp/res/values-iw/strings.xml
+++ b/android/TerminalApp/res/values-iw/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"‫<xliff:g id="ID_1">VirGL</xliff:g> מופעל"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"משימות ממושכות"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"אירועי מערכת"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"כרטיסייה"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ky/strings.xml b/android/TerminalApp/res/values-ky/strings.xml
index 814c808..c80f891 100644
--- a/android/TerminalApp/res/values-ky/strings.xml
+++ b/android/TerminalApp/res/values-ky/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> иштетилди"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Узак тапшырмалар"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Тутумдук иш-чаралар"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Өтмөк"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-lv/strings.xml b/android/TerminalApp/res/values-lv/strings.xml
index 412b454..b87f61f 100644
--- a/android/TerminalApp/res/values-lv/strings.xml
+++ b/android/TerminalApp/res/values-lv/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ir iespējots"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Ilgstoši uzdevumi"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistēmas notikumi"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Cilne"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-mk/strings.xml b/android/TerminalApp/res/values-mk/strings.xml
index 00ee26b..d071f41 100644
--- a/android/TerminalApp/res/values-mk/strings.xml
+++ b/android/TerminalApp/res/values-mk/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"Овозможено: <xliff:g id="ID_1">VirGL</xliff:g>"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Задачи што се извршуваат долго"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Системски настани"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Картичка"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-nb/strings.xml b/android/TerminalApp/res/values-nb/strings.xml
index 3d3a50a..7481be8 100644
--- a/android/TerminalApp/res/values-nb/strings.xml
+++ b/android/TerminalApp/res/values-nb/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> er aktivert"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Langvarige oppgaver"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systemhendelser"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Fane"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-pl/strings.xml b/android/TerminalApp/res/values-pl/strings.xml
index 59710d0..b5ad6d7 100644
--- a/android/TerminalApp/res/values-pl/strings.xml
+++ b/android/TerminalApp/res/values-pl/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"Układ <xliff:g id="ID_1">VirGL</xliff:g> jest włączony"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Długotrwałe zadania"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Zdarzenia systemowe"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Karta"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-pt/strings.xml b/android/TerminalApp/res/values-pt/strings.xml
index ddfb46d..8c05964 100644
--- a/android/TerminalApp/res/values-pt/strings.xml
+++ b/android/TerminalApp/res/values-pt/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"O <xliff:g id="ID_1">VirGL</xliff:g> está ativado"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tarefas de longa duração"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Eventos do sistema"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Guia"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ro/strings.xml b/android/TerminalApp/res/values-ro/strings.xml
index b5575b4..c333535 100644
--- a/android/TerminalApp/res/values-ro/strings.xml
+++ b/android/TerminalApp/res/values-ro/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> este activat"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Activități de durată"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Evenimente de sistem"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Tab"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ru/strings.xml b/android/TerminalApp/res/values-ru/strings.xml
index c8ab061..7e86cb1 100644
--- a/android/TerminalApp/res/values-ru/strings.xml
+++ b/android/TerminalApp/res/values-ru/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g>: включено."</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Длительные задачи"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Системные события"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Вкладка"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-si/strings.xml b/android/TerminalApp/res/values-si/strings.xml
index 84c4840..7085d17 100644
--- a/android/TerminalApp/res/values-si/strings.xml
+++ b/android/TerminalApp/res/values-si/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> සබලයි"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"දිගු කාලයක් ධාවනය වන කාර්යයන්"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"පද්ධති සිදුවීම්"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"පටිත්ත"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sk/strings.xml b/android/TerminalApp/res/values-sk/strings.xml
index 35a9806..b11ada0 100644
--- a/android/TerminalApp/res/values-sk/strings.xml
+++ b/android/TerminalApp/res/values-sk/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"Procesor <xliff:g id="ID_1">VirGL</xliff:g> je aktivovaný"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dlho spustené úlohy"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systémové udalosti"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Tab"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sl/strings.xml b/android/TerminalApp/res/values-sl/strings.xml
index ecd3931..8785b84 100644
--- a/android/TerminalApp/res/values-sl/strings.xml
+++ b/android/TerminalApp/res/values-sl/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> je omogočen"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dolgotrajna opravila"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistemski dogodki"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Zavihek"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sq/strings.xml b/android/TerminalApp/res/values-sq/strings.xml
index d1a5fe1..f540af8 100644
--- a/android/TerminalApp/res/values-sq/strings.xml
+++ b/android/TerminalApp/res/values-sq/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> është aktivizuar"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Detyrat afatgjata"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Ngjarjet e sistemit"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Tab"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sr/strings.xml b/android/TerminalApp/res/values-sr/strings.xml
index 635c467..8620b8a 100644
--- a/android/TerminalApp/res/values-sr/strings.xml
+++ b/android/TerminalApp/res/values-sr/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> је омогућен"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Дуготрајни задаци"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Системски догађаји"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Картица"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ta/strings.xml b/android/TerminalApp/res/values-ta/strings.xml
index 1b4c766..ba6edbf 100644
--- a/android/TerminalApp/res/values-ta/strings.xml
+++ b/android/TerminalApp/res/values-ta/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> இயக்கப்பட்டது"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"நீண்ட நேரம் இயங்கும் பணிகள்"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"சிஸ்டம் நிகழ்வுகள்"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"பிரிவு"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-tr/strings.xml b/android/TerminalApp/res/values-tr/strings.xml
index e97728c..cc3812e 100644
--- a/android/TerminalApp/res/values-tr/strings.xml
+++ b/android/TerminalApp/res/values-tr/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> etkinleştirildi"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Uzun süredir çalışan görevler"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistem etkinlikleri"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Sekme"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-uk/strings.xml b/android/TerminalApp/res/values-uk/strings.xml
index 8cb7601..4224d98 100644
--- a/android/TerminalApp/res/values-uk/strings.xml
+++ b/android/TerminalApp/res/values-uk/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> увімкнено"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Довготривалі завдання"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Події системи"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Вкладка"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zh-rTW/strings.xml b/android/TerminalApp/res/values-zh-rTW/strings.xml
index 7ddb8cd..94f473d 100644
--- a/android/TerminalApp/res/values-zh-rTW/strings.xml
+++ b/android/TerminalApp/res/values-zh-rTW/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> 已啟用"</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"長時間執行的工作"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"系統事件"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"分頁"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zu/strings.xml b/android/TerminalApp/res/values-zu/strings.xml
index 1af2744..432102b 100644
--- a/android/TerminalApp/res/values-zu/strings.xml
+++ b/android/TerminalApp/res/values-zu/strings.xml
@@ -90,6 +90,5 @@
     <string name="virgl_enabled" msgid="5242525588039698086">"I-<xliff:g id="ID_1">VirGL</xliff:g> inikwe amandla."</string>
     <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Imisebenzi esebenza isikhathi eside"</string>
     <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Imicimbi yesistimu"</string>
-    <!-- no translation found for tab_default_title (2300417689389397930) -->
-    <skip />
+    <string name="tab_default_title" msgid="2300417689389397930">"Ithebhu"</string>
 </resources>
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index eefaa65..1c4c2eb 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -151,6 +151,17 @@
     }
 });
 
+// TODO(ioffe): add service for guest-ffa.
+const KNOWN_TEE_SERVICES: [&str; 0] = [];
+
+fn check_known_tee_service(tee_service: &str) -> binder::Result<()> {
+    if !KNOWN_TEE_SERVICES.contains(&tee_service) {
+        return Err(anyhow!("unknown tee_service {tee_service}"))
+            .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION);
+    }
+    Ok(())
+}
+
 fn create_or_update_idsig_file(
     input_fd: &ParcelFileDescriptor,
     idsig_fd: &ParcelFileDescriptor,
@@ -716,11 +727,38 @@
         *is_protected = config.protectedVm;
 
         if !config.teeServices.is_empty() {
+            if !config.protectedVm {
+                return Err(anyhow!("only protected VMs can request tee services"))
+                    .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION);
+            }
             check_tee_service_permission(&caller_secontext, &config.teeServices)
                 .with_log()
                 .or_binder_exception(ExceptionCode::SECURITY)?;
         }
 
+        let mut system_tee_services = Vec::new();
+        let mut vendor_tee_services = Vec::new();
+        for tee_service in config.teeServices.clone() {
+            if !tee_service.starts_with("vendor.") {
+                check_known_tee_service(&tee_service)?;
+                system_tee_services.push(tee_service);
+            } else {
+                vendor_tee_services.push(tee_service);
+            }
+        }
+
+        // TODO(b/391774181): handle vendor tee services (which require talking to HAL) as well.
+        if !vendor_tee_services.is_empty() {
+            return Err(anyhow!("support for vendor tee services is coming soon!"))
+                .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION);
+        }
+
+        // TODO(b/391774181): remove this check in a follow-up patch.
+        if !system_tee_services.is_empty() {
+            return Err(anyhow!("support for system tee services is coming soon!"))
+                .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION);
+        }
+
         let kernel = maybe_clone_file(&config.kernel)?;
         let initrd = maybe_clone_file(&config.initrd)?;
 
@@ -897,6 +935,20 @@
             })
             .collect::<binder::Result<_>>()?;
 
+        let memory_reclaim_supported =
+            system_properties::read_bool("hypervisor.memory_reclaim.supported", false)
+                .unwrap_or(false);
+
+        let balloon = config.balloon && memory_reclaim_supported;
+
+        if !balloon {
+            warn!(
+                "Memory balloon not enabled:
+                config.balloon={},hypervisor.memory_reclaim.supported={}",
+                config.balloon, memory_reclaim_supported
+            );
+        }
+
         // Actually start the VM.
         let crosvm_config = CrosvmConfig {
             cid,
@@ -936,7 +988,7 @@
             boost_uclamp: config.boostUclamp,
             gpu_config,
             audio_config,
-            balloon: config.balloon,
+            balloon,
             usb_config,
             dump_dt_fd,
             enable_hypervisor_specific_auth_method: config.enableHypervisorSpecificAuthMethod,
@@ -1408,7 +1460,7 @@
     calling_partition: CallingPartition,
 ) -> Result<()> {
     let path = format!("/proc/self/fd/{}", fd.as_raw_fd());
-    let link = fs::read_link(&path).context(format!("can't read_link {path}"))?;
+    let link = fs::read_link(&path).with_context(|| format!("can't read_link {path}"))?;
 
     // microdroid vendor image is OK
     if cfg!(vendor_modules) && link == Path::new("/vendor/etc/avf/microdroid/microdroid_vendor.img")
@@ -1416,7 +1468,10 @@
         return Ok(());
     }
 
-    let is_fd_vendor = link.starts_with("/vendor") || link.starts_with("/odm");
+    let fd_partition = find_partition(Some(&link))
+        .with_context(|| format!("can't find_partition {}", link.display()))?;
+    let is_fd_vendor =
+        fd_partition == CallingPartition::Vendor || fd_partition == CallingPartition::Odm;
     let is_caller_vendor =
         calling_partition == CallingPartition::Vendor || calling_partition == CallingPartition::Odm;
 
@@ -1592,9 +1647,8 @@
         | "virtualizationservice_data_file" // files created by VS / VirtMgr
         | "vendor_microdroid_file" // immutable dm-verity protected partition (/vendor/etc/avf/microdroid/.*)
          => Ok(()),
-        // It is difficult to require specific label types for vendor initiated VM's files, so we
-        // allow anything with a vendor prefix.
-        t if calling_partition == CallingPartition::Vendor && t.starts_with("vendor_")  => Ok(()),
+        // It is difficult to require specific label types for vendor initiated VM's files.
+        _ if calling_partition == CallingPartition::Vendor => Ok(()),
         _ => bail!("Label {} is not allowed", context),
     }
 }
@@ -1693,6 +1747,10 @@
             .or_service_specific_exception(-1)
     }
 
+    fn isMemoryBalloonEnabled(&self) -> binder::Result<bool> {
+        Ok(self.instance.balloon_enabled)
+    }
+
     fn getMemoryBalloon(&self) -> binder::Result<i64> {
         let balloon = self
             .instance
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 77710c3..5f81e90 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -417,6 +417,8 @@
     pub vm_service: Mutex<Option<Strong<dyn IVirtualMachineService>>>,
     /// Recorded metrics of VM such as timestamp or cpu / memory usage.
     pub vm_metric: Mutex<VmMetric>,
+    // Whether virtio-balloon is enabled
+    pub balloon_enabled: bool,
     /// The latest lifecycle state which the payload reported itself to be in.
     payload_state: Mutex<PayloadState>,
     /// Represents the condition that payload_state was updated
@@ -449,6 +451,7 @@
         let cid = config.cid;
         let name = config.name.clone();
         let protected = config.protected;
+        let balloon_enabled = config.balloon;
         let requester_uid_name = User::from_uid(Uid::from_raw(requester_uid))
             .ok()
             .flatten()
@@ -469,6 +472,7 @@
             payload_state: Mutex::new(PayloadState::Starting),
             payload_state_updated: Condvar::new(),
             requester_uid_name,
+            balloon_enabled,
         };
         info!("{} created", &instance);
         Ok(instance)
@@ -722,6 +726,9 @@
 
     /// Returns current virtio-balloon size.
     pub fn get_memory_balloon(&self) -> Result<u64, Error> {
+        if !self.balloon_enabled {
+            bail!("virtio-balloon is not enabled");
+        }
         let socket_path_cstring = path_to_cstring(&self.crosvm_control_socket_path);
         let mut balloon_actual = 0u64;
         // SAFETY: Pointers are valid for the lifetime of the call. Null `stats` is valid.
@@ -741,6 +748,9 @@
     /// Inflates the virtio-balloon by `num_bytes` to reclaim guest memory. Called in response to
     /// memory-trimming notifications.
     pub fn set_memory_balloon(&self, num_bytes: u64) -> Result<(), Error> {
+        if !self.balloon_enabled {
+            bail!("virtio-balloon is not enabled");
+        }
         let socket_path_cstring = path_to_cstring(&self.crosvm_control_socket_path);
         // SAFETY: Pointer is valid for the lifetime of the call.
         let success = unsafe {
@@ -1038,8 +1048,7 @@
         .arg("--cid")
         .arg(config.cid.to_string());
 
-    if system_properties::read_bool("hypervisor.memory_reclaim.supported", false)? && config.balloon
-    {
+    if config.balloon {
         command.arg("--balloon-page-reporting");
     } else {
         command.arg("--no-balloon");
diff --git a/android/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl b/android/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
index a01d385..e7aeefd 100644
--- a/android/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
+++ b/android/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
@@ -49,6 +49,7 @@
     void stop();
 
     /** Access to the VM's memory balloon. */
+    boolean isMemoryBalloonEnabled();
     long getMemoryBalloon();
     void setMemoryBalloon(long num_bytes);
 
diff --git a/android/vm/src/main.rs b/android/vm/src/main.rs
index ff846a1..7178de5 100644
--- a/android/vm/src/main.rs
+++ b/android/vm/src/main.rs
@@ -22,8 +22,6 @@
     CpuOptions::CpuTopology::CpuTopology, IVirtualizationService::IVirtualizationService,
     PartitionType::PartitionType, VirtualMachineAppConfig::DebugLevel::DebugLevel,
 };
-#[cfg(not(llpvm_changes))]
-use anyhow::anyhow;
 use anyhow::{bail, Context, Error};
 use binder::{ProcessState, Strong};
 use clap::{Args, Parser};
@@ -220,7 +218,6 @@
     instance: PathBuf,
 
     /// Path to file containing instance_id. Required iff llpvm feature is enabled.
-    #[cfg(llpvm_changes)]
     #[arg(long = "instance-id-file")]
     instance_id: PathBuf,
 
@@ -255,26 +252,8 @@
         }
     }
 
-    fn instance_id(&self) -> Result<PathBuf, Error> {
-        cfg_if::cfg_if! {
-            if #[cfg(llpvm_changes)] {
-                Ok(self.instance_id.clone())
-            } else {
-                Err(anyhow!("LLPVM feature is disabled, --instance_id flag not supported"))
-            }
-        }
-    }
-
-    fn set_instance_id(&mut self, instance_id_file: PathBuf) -> Result<(), Error> {
-        cfg_if::cfg_if! {
-            if #[cfg(llpvm_changes)] {
-                self.instance_id = instance_id_file;
-                Ok(())
-            } else {
-                let _ = instance_id_file;
-                Err(anyhow!("LLPVM feature is disabled, --instance_id flag not supported"))
-            }
-        }
+    fn set_instance_id(&mut self, instance_id_file: PathBuf) {
+        self.instance_id = instance_id_file;
     }
 }
 
diff --git a/android/vm/src/run.rs b/android/vm/src/run.rs
index 8385fb4..1033164 100644
--- a/android/vm/src/run.rs
+++ b/android/vm/src/run.rs
@@ -87,8 +87,8 @@
         )?;
     }
 
-    let instance_id = if cfg!(llpvm_changes) {
-        let id_file = config.instance_id()?;
+    let instance_id = {
+        let id_file = config.instance_id;
         if id_file.exists() {
             let mut id = [0u8; 64];
             let mut instance_id_file = File::open(id_file)?;
@@ -100,9 +100,6 @@
             instance_id_file.write_all(&id)?;
             id
         }
-    } else {
-        // if llpvm feature flag is disabled, instance_id is not used.
-        [0u8; 64]
     };
 
     let storage = if let Some(ref path) = config.microdroid.storage {
@@ -254,10 +251,8 @@
         ..Default::default()
     };
 
-    if cfg!(llpvm_changes) {
-        app_config.set_instance_id(work_dir.join("instance_id"))?;
-        println!("instance_id file path: {}", app_config.instance_id()?.display());
-    }
+    app_config.set_instance_id(work_dir.join("instance_id"));
+    println!("instance_id file path: {}", app_config.instance_id.display());
 
     command_run_app(app_config)
 }
diff --git a/build/apex/Android.bp b/build/apex/Android.bp
index 20f44fe..79675cb 100644
--- a/build/apex/Android.bp
+++ b/build/apex/Android.bp
@@ -251,11 +251,6 @@
     srcs: [
         "sign_virt_apex.py",
     ],
-    version: {
-        py3: {
-            embedded_launcher: true,
-        },
-    },
     required: [
         // sign_virt_apex should be runnable from outside the source tree,
         // therefore, any required tool should be listed in build/make/core/Makefile as well.
@@ -324,11 +319,6 @@
     srcs: [
         "replace_bytes.py",
     ],
-    version: {
-        py3: {
-            embedded_launcher: true,
-        },
-    },
 }
 
 // Encapsulate the contributions made by the com.android.virt to the bootclasspath.
diff --git a/build/debian/build.sh b/build/debian/build.sh
index 5aa3f28..9c4d4b1 100755
--- a/build/debian/build.sh
+++ b/build/debian/build.sh
@@ -318,9 +318,8 @@
 
 generate_output_package() {
 	fdisk -l "${raw_disk_image}"
-	local vm_config="$SCRIPT_DIR/vm_config.json.${arch}"
+	local vm_config="$SCRIPT_DIR/vm_config.json"
 	local root_partition_num=1
-	local bios_partition_num=14
 	local efi_partition_num=15
 
 	pushd ${workdir} > /dev/null
@@ -329,9 +328,6 @@
 
 	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
-	fi
 	dd if="${loop}p$efi_partition_num" of=efi_part
 	losetup -d "${loop}"
 
@@ -342,9 +338,6 @@
 	fi
 
 	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 $raw_disk_image $bios_partition_num)/g" vm_config.json
-	fi
 	sed -i "s/{efi_part_guid}/$(sfdisk --part-uuid $raw_disk_image $efi_partition_num)/g" vm_config.json
 
 	popd > /dev/null
diff --git a/build/debian/vm_config.json.aarch64 b/build/debian/vm_config.json
similarity index 100%
rename from build/debian/vm_config.json.aarch64
rename to build/debian/vm_config.json
diff --git a/build/debian/vm_config.json.x86_64 b/build/debian/vm_config.json.x86_64
deleted file mode 100644
index 463583f..0000000
--- a/build/debian/vm_config.json.x86_64
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-    "name": "debian",
-    "disks": [
-        {
-            "partitions": [
-                {
-                    "label": "ROOT",
-                    "path": "$PAYLOAD_DIR/root_part",
-                    "writable": true,
-                    "guid": "{root_part_guid}"
-                },
-                {
-                    "label": "EFI",
-                    "path": "$PAYLOAD_DIR/efi_part",
-                    "writable": false,
-                    "guid": "{efi_part_guid}"
-                }
-            ],
-            "writable": true
-        }
-    ],
-    "sharedPath": [
-        {
-            "sharedPath": "/storage/emulated"
-        },
-        {
-            "sharedPath": "$APP_DATA_DIR/files"
-        }
-    ],
-    "protected": false,
-    "cpu_topology": "match_host",
-    "platform_version": "~1.0",
-    "memory_mib": 4096,
-    "debuggable": true,
-    "console_out": true,
-    "console_input_device": "ttyS0",
-    "network": true,
-    "auto_memory_balloon": true,
-    "gpu": {
-        "backend": "2d"
-    }
-}
diff --git a/guest/microdroid_manager/src/main.rs b/guest/microdroid_manager/src/main.rs
index d665c87..4537834 100644
--- a/guest/microdroid_manager/src/main.rs
+++ b/guest/microdroid_manager/src/main.rs
@@ -244,13 +244,14 @@
 fn verify_payload_with_instance_img(
     metadata: &Metadata,
     dice: &DiceDriver,
+    state: &mut VmInstanceState,
 ) -> Result<MicrodroidData> {
     let mut instance = InstanceDisk::new().context("Failed to load instance.img")?;
     let saved_data = instance.read_microdroid_data(dice).context("Failed to read identity data")?;
 
     if is_strict_boot() {
         // Provisioning must happen on the first boot and never again.
-        if is_new_instance_legacy() {
+        if Path::new(AVF_NEW_INSTANCE).exists() {
             ensure!(
                 saved_data.is_none(),
                 MicrodroidError::PayloadInvalidConfig(
@@ -286,12 +287,14 @@
             );
             info!("Saved data is verified.");
         }
+        *state = VmInstanceState::PreviouslySeen;
         saved_data
     } else {
         info!("Saving verified data.");
         instance
             .write_microdroid_data(&extracted_data, dice)
             .context("Failed to write identity data")?;
+        *state = VmInstanceState::NewlyCreated;
         extracted_data
     };
     Ok(instance_data)
@@ -321,13 +324,14 @@
             .context("Failed to load DICE from driver")?
     };
 
+    let mut state = VmInstanceState::Unknown;
     // Microdroid skips checking payload against instance image iff the device supports
-    // secretkeeper. In that case Microdroid use VmSecret::V2, which provide protection against
-    // rollback of boot images and packages.
+    // secretkeeper. In that case Microdroid use VmSecret::V2, which provides instance state
+    // and protection against rollback of boot images and packages.
     let instance_data = if should_defer_rollback_protection() {
         verify_payload(&metadata, None)?
     } else {
-        verify_payload_with_instance_img(&metadata, &dice)?
+        verify_payload_with_instance_img(&metadata, &dice, &mut state)?
     };
 
     let payload_metadata = metadata.payload.ok_or_else(|| {
@@ -337,7 +341,6 @@
     // To minimize the exposure to untrusted data, derive dice profile as soon as possible.
     info!("DICE derivation for payload");
     let dice_artifacts = dice_derivation(dice, &instance_data, &payload_metadata)?;
-    let mut state = VmInstanceState::Unknown;
     let vm_secret = VmSecret::new(dice_artifacts, service, &mut state)
         .context("Failed to create VM secrets")?;
 
@@ -345,15 +348,7 @@
         VmInstanceState::NewlyCreated => true,
         VmInstanceState::PreviouslySeen => false,
         VmInstanceState::Unknown => {
-            // VmSecret instantiation was not able to determine the state. This should only happen
-            // for legacy secret mechanism (V1) - in which case fallback to legacy
-            // instance.img based determination of state.
-            ensure!(
-                !should_defer_rollback_protection(),
-                "VmInstanceState is Unknown whilst guest is expected to use V2 based secrets.
-                This should've never happened"
-            );
-            is_new_instance_legacy()
+            bail!("Vm instance state is still unknown, this should not have happened");
         }
     };
 
@@ -519,10 +514,6 @@
     Path::new(AVF_STRICT_BOOT).exists()
 }
 
-fn is_new_instance_legacy() -> bool {
-    Path::new(AVF_NEW_INSTANCE).exists()
-}
-
 fn is_verified_boot() -> bool {
     !Path::new(DEBUG_MICRODROID_NO_VERIFIED_BOOT).exists()
 }
diff --git a/guest/microdroid_manager/src/vm_secret.rs b/guest/microdroid_manager/src/vm_secret.rs
index f031859..674f010 100644
--- a/guest/microdroid_manager/src/vm_secret.rs
+++ b/guest/microdroid_manager/src/vm_secret.rs
@@ -35,6 +35,9 @@
     StoreSecretRequest, GetSecretResponse, GetSecretRequest};
 use secretkeeper_comm::data_types::error::SecretkeeperError;
 use std::fs;
+use std::thread;
+use rand::Rng;
+use std::time::Duration;
 use zeroize::Zeroizing;
 use std::sync::Mutex;
 use std::sync::Arc;
@@ -63,6 +66,8 @@
     0x55, 0xF8, 0x08, 0x23, 0x81, 0x5F, 0xF5, 0x16, 0x20, 0x3E, 0xBE, 0xBA, 0xB7, 0xA8, 0x43, 0x92,
 ];
 
+const BACKOFF_SK_ACCESS_MS: u64 = 100;
+
 pub enum VmSecret {
     // V2 secrets are derived from 2 independently secured secrets:
     //      1. Secretkeeper protected secrets (skp secret).
@@ -118,15 +123,19 @@
             .map_err(|e| anyhow!("Failed to build a sealing_policy: {e}"))?;
         let session = SkVmSession::new(vm_service, &explicit_dice, policy)?;
         let mut skp_secret = Zeroizing::new([0u8; SECRET_SIZE]);
-        if let Some(secret) = session.get_secret(id)? {
-            *skp_secret = secret;
-            *state = VmInstanceState::PreviouslySeen;
-        } else {
-            log::warn!("No entry found in Secretkeeper for this VM instance, creating new secret.");
-            *skp_secret = rand::random();
-            session.store_secret(id, skp_secret.clone())?;
-            *state = VmInstanceState::NewlyCreated;
-        }
+        get_or_create_sk_secret(&session, id, &mut skp_secret, state).or_else(|e| {
+            // TODO(b/399304956): Secretkeeper rejects requests when overloaded with
+            // connections from multiple clients. Backoff & retry again, hoping it is
+            // less busy then. Secretkeeper changes are required for more robust solutions.
+            log::info!(
+                "get_or_create_sk_secret failed with {e:?}. Refreshing connection & retrying!"
+            );
+            let mut rng = rand::thread_rng();
+            let backoff = rng.gen_range(BACKOFF_SK_ACCESS_MS..2 * BACKOFF_SK_ACCESS_MS);
+            thread::sleep(Duration::from_millis(backoff));
+            session.refresh()?;
+            get_or_create_sk_secret(&session, id, &mut skp_secret, state)
+        })?;
         Ok(Self::V2 {
             instance_id: id,
             dice_artifacts: explicit_dice,
@@ -283,8 +292,6 @@
     sealing_policy: Vec<u8>,
 }
 
-// TODO(b/378911776): This get_secret/store_secret fails on expired session.
-// Introduce retry after refreshing the session
 impl SkVmSession {
     fn new(
         vm_service: &Strong<dyn IVirtualMachineService>,
@@ -366,3 +373,21 @@
             ))
         })?)
 }
+
+fn get_or_create_sk_secret(
+    session: &SkVmSession,
+    id: [u8; ID_SIZE],
+    skp_secret: &mut Zeroizing<[u8; SECRET_SIZE]>,
+    state: &mut VmInstanceState,
+) -> Result<()> {
+    if let Some(secret) = session.get_secret(id)? {
+        **skp_secret = secret;
+        *state = VmInstanceState::PreviouslySeen;
+    } else {
+        log::warn!("No entry found in Secretkeeper for this VM instance, creating new secret.");
+        **skp_secret = rand::random();
+        session.store_secret(id, skp_secret.clone())?;
+        *state = VmInstanceState::NewlyCreated;
+    }
+    Ok(())
+}
diff --git a/guest/trusty/common/Android.bp b/guest/trusty/common/Android.bp
index d6c524f..1a4c4d7 100644
--- a/guest/trusty/common/Android.bp
+++ b/guest/trusty/common/Android.bp
@@ -1,22 +1,3 @@
-soong_config_module_type {
-    name: "trusty_vm_prebuilt_etc",
-    module_type: "prebuilt_etc",
-    config_namespace: "trusty_system_vm",
-    bool_variables: [
-        "enabled",
-        "placeholder_trusted_hal",
-    ],
-    properties: ["src"],
-}
-
-soong_config_module_type {
-    name: "trusty_vm_avb_add_hash_footer",
-    module_type: "avb_add_hash_footer",
-    config_namespace: "trusty_system_vm",
-    bool_variables: ["enabled"],
-    properties: ["src"],
-}
-
 prebuilt_etc {
     name: "early_vms.xml",
     filename: "early_vms.xml",
diff --git a/guest/trusty/security_vm/launcher/security_vm_launcher-arm64.rc b/guest/trusty/security_vm/launcher/security_vm_launcher-arm64.rc
index c0e0537..b9c7147 100644
--- a/guest/trusty/security_vm/launcher/security_vm_launcher-arm64.rc
+++ b/guest/trusty/security_vm/launcher/security_vm_launcher-arm64.rc
@@ -1,9 +1,9 @@
-# TODO(b/393848713): use --protected for the vm launcher when issues are fixed
 # TODO(b/393848753): determine whether task_profiles shall be defined
 service trusty_security_vm_launcher /system_ext/bin/trusty_security_vm_launcher \
 --name trusty_security_vm_launcher \
 --kernel /system_ext/etc/vm/trusty_vm/trusty_security_vm.elf \
---memory-size-mib 32
+--memory-size-mib 32 \
+--protected
     disabled
     user system
     group system virtualmachine
diff --git a/guest/trusty/security_vm/vm/Android.bp b/guest/trusty/security_vm/vm/Android.bp
index cc01d1c..35d7313 100644
--- a/guest/trusty/security_vm/vm/Android.bp
+++ b/guest/trusty/security_vm/vm/Android.bp
@@ -2,11 +2,6 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-soong_config_module_type_import {
-    from: "packages/modules/Virtualization/guest/trusty/common/Android.bp",
-    module_types: ["trusty_vm_avb_add_hash_footer"],
-}
-
 // - Trusty VM payloads on arm64 are pvmfw enabled
 //   AVF VM build system uses the raw binary image (:trusty_security_vm_unsigned),
 //   adds pvmfw footer and generates a pvmfw-compliant signed elf file)
@@ -115,7 +110,7 @@
 
 TRUSTY_SECURITY_VM_VERSION = 1
 
-trusty_vm_avb_add_hash_footer {
+avb_add_hash_footer {
     name: "trusty_security_vm_signed_bin",
     filename: "trusty_security_vm_signed.bin",
     partition_name: "boot",
diff --git a/guest/trusty/test_vm/Android.bp b/guest/trusty/test_vm/Android.bp
index 699b673..06b7d9d 100644
--- a/guest/trusty/test_vm/Android.bp
+++ b/guest/trusty/test_vm/Android.bp
@@ -20,6 +20,7 @@
 prebuilt_etc {
     name: "trusty_test_vm_config",
     enabled: false,
+    installable: false,
     arch: {
         arm64: {
             src: "trusty-test_vm-config-arm64.json",
@@ -33,38 +34,10 @@
     filename: "trusty-test_vm-config.json",
 }
 
-prebuilt_etc {
-    name: "trusty_vm_launcher_sh",
-    enabled: false,
-    arch: {
-        arm64: {
-            enabled: true,
-        },
-        x86_64: {
-            enabled: true,
-        },
-    },
-    src: "trusty-vm-launcher.sh",
-    filename: "trusty-vm-launcher.sh",
-}
-
-prebuilt_etc {
-    name: "trusty_wait_ready_sh",
-    enabled: false,
-    arch: {
-        arm64: {
-            enabled: true,
-        },
-        x86_64: {
-            enabled: true,
-        },
-    },
-    src: "trusty-wait-ready.sh",
-    filename: "trusty-wait-ready.sh",
-}
-
 sh_test {
-    name: "TrustyTestVM_UnitTests",
+    // VTS tests for all Trusted HALs defined
+    // under hardware/interfaces/security/see
+    name: "VtsSeeHalTargetTest",
     src: "trusty-ut-ctrl.sh",
     enabled: false,
     arch: {
@@ -81,9 +54,8 @@
         ":trusty_test_vm_config",
         "trusty-vm-launcher.sh",
         "trusty-wait-ready.sh",
+        ":trusty-ut-ctrl.system",
     ],
-    // TODO(b/378367793) use the AndroidTest.xml generated from the trusty
-    // test-map for test_vm payload
     test_config_template: "AndroidTest.xml",
     test_suites: [
         "general-tests",
diff --git a/guest/trusty/test_vm/AndroidTest.xml b/guest/trusty/test_vm/AndroidTest.xml
index 6fb0879..925b43c 100644
--- a/guest/trusty/test_vm/AndroidTest.xml
+++ b/guest/trusty/test_vm/AndroidTest.xml
@@ -23,6 +23,7 @@
     <!-- Target Preparers - Run Shell Commands -->
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
+        <option name="push-file" key="trusty-ut-ctrl.system" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl" />
         <option name="push-file" key="trusty-ut-ctrl.sh" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh" />
         <option name="push-file" key="trusty-vm-launcher.sh" value="/data/local/tmp/trusty_test_vm/trusty-vm-launcher.sh" />
         <option name="push-file" key="trusty-wait-ready.sh" value="/data/local/tmp/trusty_test_vm/trusty-wait-ready.sh" />
@@ -34,76 +35,16 @@
         <!--Note: the first run-command shall not expect the background command to have started -->
         <option name="run-bg-command" value="sh /data/local/tmp/trusty_test_vm/trusty-vm-launcher.sh" />
         <option name="run-command" value="sh /data/local/tmp/trusty_test_vm/trusty-wait-ready.sh" />
-        <option name="run-command" value="start storageproxyd_test_system" />
-        <option name="teardown-command" value="stop storageproxyd_test_system" />
-        <option name="teardown-command" value="killall storageproxyd_test_system || true" />
+        <option name="run-command" value="start storageproxyd_test_vm" />
+        <option name="teardown-command" value="stop storageproxyd_test_vm" />
+        <option name="teardown-command" value="killall storageproxyd_test_vm || true" />
     </target_preparer>
     <test class="com.android.tradefed.testtype.binary.ExecutableTargetTest" >
         <option name="parse-gtest" value="true" />
         <option name="abort-if-device-lost" value="true"/>
         <option name="abort-if-root-lost" value="true" />
         <option name="per-binary-timeout" value="10m" />
-        <option name="test-command-line" key="com.android.kernel.mmutest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.mmutest"/>
-        <option name="test-command-line" key="com.android.kernel.threadtest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.threadtest"/>
-        <option name="test-command-line" key="com.android.kernel.iovectest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.iovectest"/>
-        <option name="test-command-line" key="com.android.kernel.timertest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.timertest"/>
-        <option name="test-command-line" key="com.android.kernel.btitest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.btitest"/>
-        <option name="test-command-line" key="com.android.kernel.cachetest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.cachetest"/>
-        <option name="test-command-line" key="com.android.kernel.console-unittest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.console-unittest"/>
-        <option name="test-command-line" key="com.android.kernel.dpc-unittest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.dpc-unittest"/>
-        <option name="test-command-line" key="com.android.kernel.iovectest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.iovectest"/>
-        <option name="test-command-line" key="com.android.kernel.ktipc.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.ktipc.test"/>
-        <option name="test-command-line" key="com.android.kernel.memorytest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.memorytest"/>
-        <option name="test-command-line" key="com.android.kernel.pactest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.pactest"/>
-        <option name="test-command-line" key="com.android.kernel.uirq-unittest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.uirq-unittest"/>
-        <option name="test-command-line" key="com.android.kernel.usercopy-unittest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.usercopy-unittest"/>
-        <option name="test-command-line" key="com.android.kernel.userscstest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.kernel.userscstest"/>
-        <option name="test-command-line" key="com.android.trusty.rust.keymint.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.keymint.test"/>
-        <option name="test-command-line" key="com.android.manifesttest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.manifesttest"/>
-        <option name="test-command-line" key="com.android.memref.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.memref.test"/>
-        <option name="test-command-line" key="com.android.trusty.rust.memref.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.memref.test"/>
-        <option name="test-command-line" key="com.android.timer-unittest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.timer-unittest"/>
-        <option name="test-command-line" key="com.android.ipc-unittest.ctrl" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.ipc-unittest.ctrl"/>
-        <!--option name="test-command-line" key="com.android.trusty.cfitest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.cfitest"/-->
-        <option name="test-command-line" key="com.android.trusty.crashtest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.crashtest"/>
-        <option name="test-command-line" key="com.android.trusty.dlmalloctest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.dlmalloctest"/>
-        <option name="test-command-line" key="com.android.trusty.hwaes.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.hwaes.test"/>
-        <option name="test-command-line" key="com.android.trusty.hwbcc.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.hwbcc.test"/>
-        <option name="test-command-line" key="com.android.trusty.rust.tipc.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.tipc.test"/>
-        <option name="test-command-line" key="com.android.trusty.rust.hwkey.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.hwkey.test"/>
-        <option name="test-command-line" key="com.android.trusty.rust.hwbcc.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.hwbcc.test"/>
-        <option name="test-command-line" key="com.android.trusty.rust.hwwsk.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.hwwsk.test"/>
-        <option name="test-command-line" key="com.android.trusty.rust.storage.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.storage.test"/>
-        <option name="test-command-line" key="com.android.trusty.smc.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.smc.test"/>
-        <option name="test-command-line" key="com.android.uirq-unittest" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.uirq-unittest"/>
-        <!-- Unit tests for legacy hwcrypto services - these hwcrypto services are used by hwcryptohal /-->
-        <option name="test-command-line" key="com.android.trusty.hwcrypto.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.hwcrypto.test"/>
-        <option name="test-command-line" key="com.android.trusty.hwrng.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.hwrng.test"/>
-        <!-- Unit tests for hwcryptohal (exposing IHWCryptoKey/IHWCryptoOperations AIDL) - Note: VTS tests are defined alongside the interface /-->
-        <option name="test-command-line" key="com.android.trusty.rust.hwcryptohalserver.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.hwcryptohalserver.test"/>
-        <option name="test-command-line" key="com.android.trusty.rust.hwcryptohal_common.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.hwcryptohal_common.test"/>
         <option name="test-command-line" key="com.android.trusty.rust.hwcryptokey_test.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.hwcryptokey_test.test"/>
-    </test>
-    <!-- disabling storage test as they are redundant with the VTS -->
-    <!--test class="com.android.tradefed.testtype.binary.ExecutableTargetTest" >
-        <option name="parse-gtest" value="true" />
-        <option name="abort-if-device-lost" value="true" />
-        <option name="abort-if-root-lost" value="true" />
-        <option name="per-binary-timeout" value="40m" />
         <option name="test-command-line" key="com.android.trusty.rust.storage_unittest_aidl.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.storage_unittest_aidl.test"/>
-        <option name="test-command-line" key="com.android.trusty.rust.storage_unittest_aidl_ns.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.storage_unittest_aidl_ns.test"/>
-        <option name="test-command-line" key="com.android.storage-unittest.tp" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.storage-unittest.tp"/>
-        <option name="test-command-line" key="com.android.storage-unittest.tdea" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.storage-unittest.tdea"/>
-        <option name="test-command-line" key="com.android.storage-unittest.nsp" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.storage-unittest.nsp"/>
-        <option name="test-command-line" key="com.android.storage-unittest.td" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.storage-unittest.td"/>
-        <option name="test-command-line" key="com.android.storage-unittest.tdp" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.storage-unittest.tdp"/>
-    </test-->
-    <test class="com.android.tradefed.testtype.binary.ExecutableTargetTest" >
-        <option name="parse-gtest" value="true" />
-        <!--option name="abort-if-device-lost" value="true" /-->
-        <!--option name="abort-if-root-lost" value="true" /-->
-        <option name="per-binary-timeout" value="40m" />
-        <option name="test-command-line" key="com.android.trusty.rust.binder_rpc_test.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.rust.binder_rpc_test.test"/>
-        <option name="test-command-line" key="com.android.trusty.binder.test" value="/data/local/tmp/trusty_test_vm/trusty-ut-ctrl.sh com.android.trusty.binder.test"/>
     </test>
     </configuration>
diff --git a/guest/trusty/test_vm/README.md b/guest/trusty/test_vm/README.md
index 1673844..71368b5 100644
--- a/guest/trusty/test_vm/README.md
+++ b/guest/trusty/test_vm/README.md
@@ -1,7 +1,13 @@
-## Trusty test_vm
+## test_vm
 
-The Trusty test_vm ought to include the test TAs for different test types:
-- Trusty kernel OS test
-- Trusty IPC tests
-- Trusty user-space tests for service TAs (DT tree for example)
-- and most importantly the VTS tests TA for the trusted HALs.
+The Trusty test_vm ought to include the test TAs for the Trusted HALs,
+defined under hardware/interfaces/security/see:
+
+- AuthMgr
+- Secure Storage
+- HWCrypto
+- HDCP
+
+The Trusty test_vm also includes the VINTF test which allows to check the vendor
+support of the Trusted HALs (version and API hash), against the expected
+compatibility matrix for a given Android Dessert Release.
diff --git a/guest/trusty/test_vm/trusty-test_vm-config-arm64.json b/guest/trusty/test_vm/trusty-test_vm-config-arm64.json
index 18b275e..ac95aab 100644
--- a/guest/trusty/test_vm/trusty-test_vm-config-arm64.json
+++ b/guest/trusty/test_vm/trusty-test_vm-config-arm64.json
@@ -1,7 +1,8 @@
 {
     "name": "trusty_test_vm",
-    "kernel": "/data/local/tmp/trusty_test_vm/trusty_test_vm_.elf",
+    "kernel": "/data/local/tmp/trusty_test_vm/trusty_test_vm.elf",
     "platform_version": "1.0",
+    "cpu_topology": "one_cpu",
     "memory_mib": 112,
     "protected": true
 }
diff --git a/guest/trusty/test_vm/trusty-test_vm-config-x86_64.json b/guest/trusty/test_vm/trusty-test_vm-config-x86_64.json
index d491c3a..5ce65ba 100644
--- a/guest/trusty/test_vm/trusty-test_vm-config-x86_64.json
+++ b/guest/trusty/test_vm/trusty-test_vm-config-x86_64.json
@@ -2,5 +2,6 @@
     "name": "trusty_test_vm",
     "kernel": "/data/local/tmp/trusty_test_vm/trusty_test_vm.elf",
     "platform_version": "1.0",
+    "cpu_topology": "one_cpu",
     "memory_mib": 112
 }
diff --git a/guest/trusty/test_vm/trusty-ut-ctrl.sh b/guest/trusty/test_vm/trusty-ut-ctrl.sh
index 77a9459..2317496 100644
--- a/guest/trusty/test_vm/trusty-ut-ctrl.sh
+++ b/guest/trusty/test_vm/trusty-ut-ctrl.sh
@@ -14,4 +14,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-/system_ext/bin/trusty-ut-ctrl.system -D VSOCK:${2:-$(getprop trusty.test_vm.vm_cid)}:1 $1
+/data/local/tmp/trusty_test_vm/trusty-ut-ctrl -D VSOCK:${2:-$(getprop trusty.test_vm.vm_cid)}:1 $1
diff --git a/guest/trusty/test_vm/vm/Android.bp b/guest/trusty/test_vm/vm/Android.bp
index 4f696b1..f978c92 100644
--- a/guest/trusty/test_vm/vm/Android.bp
+++ b/guest/trusty/test_vm/vm/Android.bp
@@ -2,11 +2,6 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-soong_config_module_type_import {
-    from: "packages/modules/Virtualization/guest/trusty/common/Android.bp",
-    module_types: ["trusty_vm_avb_add_hash_footer"],
-}
-
 prebuilt_etc {
     name: "trusty_test_vm_elf",
     system_ext_specific: true,
@@ -94,7 +89,7 @@
 
 TRUSTY_TEST_VM_VERSION = 1
 
-trusty_vm_avb_add_hash_footer {
+avb_add_hash_footer {
     name: "trusty_test_vm_signed_bin",
     filename: "trusty_test_vm_signed.bin",
     partition_name: "boot",
diff --git a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java
index 0445fcb..40050c0 100644
--- a/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java
+++ b/libs/framework-virtualization/src/android/system/virtualmachine/VirtualMachine.java
@@ -288,17 +288,7 @@
                 percent = 50;
             }
 
-            synchronized (mLock) {
-                try {
-                    if (mVirtualMachine != null) {
-                        long bytes = mConfig.getMemoryBytes();
-                        mVirtualMachine.setMemoryBalloon(bytes * percent / 100);
-                    }
-                } catch (Exception e) {
-                    /* Caller doesn't want our exceptions. Log them instead. */
-                    Log.w(TAG, "TrimMemory failed: ", e);
-                }
-            }
+            setMemoryBalloonByPercent(percent);
         }
     }
 
@@ -1392,6 +1382,24 @@
         }
     }
 
+    /** @hide */
+    public void setMemoryBalloonByPercent(int percent) {
+        if (percent < 0 || percent > 100) {
+            Log.e(TAG, String.format("Invalid percent value: %d", percent));
+            return;
+        }
+        synchronized (mLock) {
+            try {
+                if (mVirtualMachine != null && mVirtualMachine.isMemoryBalloonEnabled()) {
+                    long bytes = mConfig.getMemoryBytes();
+                    mVirtualMachine.setMemoryBalloon(bytes * percent / 100);
+                }
+            } catch (RemoteException | ServiceSpecificException e) {
+                Log.w(TAG, "Cannot setMemoryBalloon", e);
+            }
+        }
+    }
+
     private boolean writeEventsToSock(ParcelFileDescriptor sock, List<InputEvent> evtList) {
         ByteBuffer byteBuffer =
                 ByteBuffer.allocate(8 /* (type: u16 + code: u16 + value: i32) */ * evtList.size());
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 418a88e..9d08ed7 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -2166,11 +2166,6 @@
         assumeFalse(
                 "Cuttlefish/Goldfish doesn't support device tree under /proc/device-tree",
                 isCuttlefish() || isGoldfish());
-        if (!isUpdatableVmSupported()) {
-            // TODO(b/389611249): Non protected VMs using legacy secret mechanisms do not reliably
-            // implement `AVmPayload_isNewInstance`.
-            assumeProtectedVM();
-        }
         VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_a", config);
         TestResults testResults =
                 runVmTestService(
diff --git a/tests/vts/AndroidTest.xml b/tests/vts/AndroidTest.xml
index 6926f9f..a59f161 100644
--- a/tests/vts/AndroidTest.xml
+++ b/tests/vts/AndroidTest.xml
@@ -21,7 +21,7 @@
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
         <option name="push" value="vts_libavf_test->/data/nativetest64/vendor/vts_libavf_test" />
-        <option name="push" value="rialto.bin->/data/local/tmp/rialto.bin" />
+        <option name="push" value="rialto.bin->/data/nativetest64/vendor/rialto.bin" />
     </target_preparer>
 
     <object type="module_controller" class="com.android.tradefed.testtype.suite.module.ArchModuleController">
diff --git a/tests/vts/src/vts_libavf_test.rs b/tests/vts/src/vts_libavf_test.rs
index dc37aad..c13b510 100644
--- a/tests/vts/src/vts_libavf_test.rs
+++ b/tests/vts/src/vts_libavf_test.rs
@@ -75,7 +75,7 @@
 
 fn run_rialto(protected_vm: bool) -> Result<()> {
     let kernel_file =
-        File::open("/data/local/tmp/rialto.bin").context("Failed to open kernel file")?;
+        File::open("/data/nativetest64/vendor/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