Merge "Handle URL in browser" into main
diff --git a/android/TerminalApp/AndroidManifest.xml b/android/TerminalApp/AndroidManifest.xml
index 726004c..53fdafc 100644
--- a/android/TerminalApp/AndroidManifest.xml
+++ b/android/TerminalApp/AndroidManifest.xml
@@ -35,7 +35,8 @@
         android:theme="@style/VmTerminalAppTheme"
         android:usesCleartextTraffic="true"
         android:supportsRtl="true"
-        android:enabled="false">
+        android:enabled="false"
+        android:name=".Application">
         <activity android:name=".MainActivity"
                   android:configChanges="orientation|screenSize|keyboard|keyboardHidden|navigation|uiMode|screenLayout|smallestScreenSize"
                   android:exported="true">
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Application.kt b/android/TerminalApp/java/com/android/virtualization/terminal/Application.kt
new file mode 100644
index 0000000..efe651e
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/Application.kt
@@ -0,0 +1,55 @@
+/*
+ * 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
+
+import android.app.Application as AndroidApplication
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+
+public class Application : AndroidApplication() {
+    override fun onCreate() {
+        super.onCreate()
+        setupNotificationChannels()
+    }
+
+    private fun setupNotificationChannels() {
+        val nm = getSystemService<NotificationManager>(NotificationManager::class.java)
+
+        nm.createNotificationChannel(
+            NotificationChannel(
+                CHANNEL_LONG_RUNNING_ID,
+                getString(R.string.notification_channel_long_running_name),
+                NotificationManager.IMPORTANCE_DEFAULT,
+            )
+        )
+
+        nm.createNotificationChannel(
+            NotificationChannel(
+                CHANNEL_SYSTEM_EVENTS_ID,
+                getString(R.string.notification_channel_system_events_name),
+                NotificationManager.IMPORTANCE_HIGH,
+            )
+        )
+    }
+
+    companion object {
+        const val CHANNEL_LONG_RUNNING_ID = "long_running"
+        const val CHANNEL_SYSTEM_EVENTS_ID = "system_events"
+
+        fun getInstance(c: Context): Application = c.getApplicationContext() as Application
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/BaseActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/BaseActivity.kt
index e7ac8d9..70bc5e4 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/BaseActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/BaseActivity.kt
@@ -16,8 +16,6 @@
 package com.android.virtualization.terminal
 
 import android.Manifest
-import android.app.NotificationChannel
-import android.app.NotificationManager
 import android.content.pm.PackageManager
 import android.os.Bundle
 import androidx.appcompat.app.AppCompatActivity
@@ -25,18 +23,6 @@
 abstract class BaseActivity : AppCompatActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        val notificationManager =
-            getSystemService<NotificationManager>(NotificationManager::class.java)
-        if (notificationManager.getNotificationChannel(this.packageName) == null) {
-            val channel =
-                NotificationChannel(
-                    this.packageName,
-                    getString(R.string.app_name),
-                    NotificationManager.IMPORTANCE_HIGH,
-                )
-            notificationManager.createNotificationChannel(channel)
-        }
-
         if (this !is ErrorActivity) {
             val currentThread = Thread.currentThread()
             if (currentThread.uncaughtExceptionHandler !is TerminalExceptionHandler) {
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.kt
index 423d66b..7180e87 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.kt
@@ -71,7 +71,7 @@
                 PendingIntent.FLAG_IMMUTABLE,
             )
         notification =
-            Notification.Builder(this, this.packageName)
+            Notification.Builder(this, Application.CHANNEL_LONG_RUNNING_ID)
                 .setSilent(true)
                 .setSmallIcon(R.drawable.ic_launcher_foreground)
                 .setContentTitle(getString(R.string.installer_notif_title_text))
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
index e2721ef..1ae6ec5 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
@@ -40,7 +40,7 @@
 import android.view.Menu
 import android.view.MenuItem
 import android.view.View
-import android.view.WindowInsets
+import android.view.ViewGroup
 import android.view.accessibility.AccessibilityManager
 import android.webkit.ClientCertRequest
 import android.webkit.SslErrorHandler
@@ -81,10 +81,12 @@
     private lateinit var image: InstalledImage
     private var certificates: Array<X509Certificate>? = null
     private var privateKey: PrivateKey? = null
+    private lateinit var terminalContainer: ViewGroup
     private lateinit var terminalView: TerminalView
     private lateinit var accessibilityManager: AccessibilityManager
     private val bootCompleted = ConditionVariable()
     private lateinit var manageExternalStorageActivityResultLauncher: ActivityResultLauncher<Intent>
+    private lateinit var modifierKeysController: ModifierKeysController
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -104,7 +106,9 @@
         terminalView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE)
         terminalView.setWebChromeClient(WebChromeClient())
 
-        setupModifierKeys()
+        terminalContainer = terminalView.parent as ViewGroup
+
+        modifierKeysController = ModifierKeysController(this, terminalView, terminalContainer)
 
         accessibilityManager =
             getSystemService<AccessibilityManager>(AccessibilityManager::class.java)
@@ -117,11 +121,6 @@
                 StartActivityForResult(),
                 ActivityResultCallback { startVm() },
             )
-        window.decorView.rootView.setOnApplyWindowInsetsListener { _: View?, insets: WindowInsets ->
-            updateModifierKeysVisibility()
-            insets
-        }
-
         executorService =
             Executors.newSingleThreadExecutor(TerminalThreadFactory(applicationContext))
 
@@ -147,30 +146,7 @@
     override fun onConfigurationChanged(newConfig: Configuration) {
         super.onConfigurationChanged(newConfig)
         lockOrientationIfNecessary()
-        updateModifierKeysVisibility()
-    }
-
-    private fun setupModifierKeys() {
-        // Only ctrl key is special, it communicates with xtermjs to modify key event with ctrl key
-        findViewById<View>(R.id.btn_ctrl)
-            .setOnClickListener(
-                View.OnClickListener {
-                    terminalView.mapCtrlKey()
-                    terminalView.enableCtrlKey()
-                }
-            )
-
-        val modifierButtonClickListener =
-            View.OnClickListener { v: View ->
-                BTN_KEY_CODE_MAP[v.id]?.also { keyCode ->
-                    terminalView.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, keyCode))
-                    terminalView.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_UP, keyCode))
-                }
-            }
-
-        for (btn in BTN_KEY_CODE_MAP.keys) {
-            findViewById<View>(btn).setOnClickListener(modifierButtonClickListener)
-        }
+        modifierKeysController.update()
     }
 
     override fun dispatchKeyEvent(event: KeyEvent): Boolean {
@@ -279,10 +255,9 @@
                                 if (completedRequestId == requestId) {
                                     Trace.endAsyncSection("executeTerminal", 0)
                                     findViewById<View?>(R.id.boot_progress).visibility = View.GONE
-                                    findViewById<View?>(R.id.webview_container).visibility =
-                                        View.VISIBLE
+                                    terminalContainer.visibility = View.VISIBLE
                                     bootCompleted.open()
-                                    updateModifierKeysVisibility()
+                                    modifierKeysController.update()
                                     terminalView.mapTouchToMouseEvent()
                                 }
                             }
@@ -321,6 +296,8 @@
             info,
             executorService,
             object : NsdManager.ServiceInfoCallback {
+                var loaded: Boolean = false
+
                 override fun onServiceInfoCallbackRegistrationFailed(errorCode: Int) {}
 
                 override fun onServiceInfoCallbackUnregistered() {}
@@ -328,13 +305,15 @@
                 override fun onServiceLost() {}
 
                 override fun onServiceUpdated(info: NsdServiceInfo) {
-                    nsdManager.unregisterServiceInfoCallback(this)
-
                     Log.i(TAG, "Service found: $info")
                     val ipAddress = info.hostAddresses[0].hostAddress
                     val port = info.port
                     val url = getTerminalServiceUrl(ipAddress, port)
-                    runOnUiThread(Runnable { terminalView.loadUrl(url.toString()) })
+                    if (!loaded) {
+                        loaded = true
+                        nsdManager.unregisterServiceInfoCallback(this)
+                        runOnUiThread(Runnable { terminalView.loadUrl(url.toString()) })
+                    }
                 }
             },
         )
@@ -382,15 +361,6 @@
         connectToTerminalService()
     }
 
-    private fun updateModifierKeysVisibility() {
-        val imeShown = window.decorView.rootWindowInsets.isVisible(WindowInsets.Type.ime())
-        val hasHwQwertyKeyboard = resources.configuration.keyboard == Configuration.KEYBOARD_QWERTY
-        val showModifierKeys = imeShown && !hasHwQwertyKeyboard
-
-        val modifierKeys = findViewById<View>(R.id.modifier_keys)
-        modifierKeys.visibility = if (showModifierKeys) View.VISIBLE else View.GONE
-    }
-
     private val installerLauncher =
         registerForActivityResult(StartActivityForResult()) { result ->
             val resultCode = result.resultCode
@@ -446,7 +416,7 @@
             )
         val icon = Icon.createWithResource(resources, R.drawable.ic_launcher_foreground)
         val notification: Notification =
-            Notification.Builder(this, this.packageName)
+            Notification.Builder(this, Application.CHANNEL_LONG_RUNNING_ID)
                 .setSilent(true)
                 .setSmallIcon(R.drawable.ic_launcher_foreground)
                 .setContentTitle(resources.getString(R.string.service_notification_title))
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ModifierKeysController.kt b/android/TerminalApp/java/com/android/virtualization/terminal/ModifierKeysController.kt
new file mode 100644
index 0000000..f8f30f9
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ModifierKeysController.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 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
+
+import android.app.Activity
+import android.content.res.Configuration
+import android.view.KeyEvent
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.WindowInsets
+
+class ModifierKeysController(
+    val activity: Activity,
+    val terminalView: TerminalView,
+    val parent: ViewGroup,
+) {
+    private val window = activity.window
+    private val keysSingleLine: View
+    private val keysDoubleLine: View
+
+    private var keysInSingleLine: Boolean = false
+
+    init {
+        // Prepare the two modifier keys layout, but don't add them yet because we don't know which
+        // layout will be needed.
+        val layout = LayoutInflater.from(activity)
+        keysSingleLine = layout.inflate(R.layout.modifier_keys_singleline, parent, false)
+        keysDoubleLine = layout.inflate(R.layout.modifier_keys_doubleline, parent, false)
+
+        addClickListeners(keysSingleLine)
+        addClickListeners(keysDoubleLine)
+
+        keysSingleLine.visibility = View.GONE
+        keysDoubleLine.visibility = View.GONE
+
+        // Setup for the update to be called when needed
+        window.decorView.rootView.setOnApplyWindowInsetsListener { _: View?, insets: WindowInsets ->
+            update()
+            insets
+        }
+
+        terminalView.setOnFocusChangeListener { _: View, _: Boolean -> update() }
+    }
+
+    private fun addClickListeners(keys: View) {
+        // Only ctrl key is special, it communicates with xtermjs to modify key event with ctrl key
+        keys
+            .findViewById<View>(R.id.btn_ctrl)
+            .setOnClickListener({
+                terminalView.mapCtrlKey()
+                terminalView.enableCtrlKey()
+            })
+
+        val listener =
+            View.OnClickListener { v: View ->
+                BTN_KEY_CODE_MAP[v.id]?.also { keyCode ->
+                    terminalView.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, keyCode))
+                    terminalView.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_UP, keyCode))
+                }
+            }
+
+        for (btn in BTN_KEY_CODE_MAP.keys) {
+            keys.findViewById<View>(btn).setOnClickListener(listener)
+        }
+    }
+
+    fun update() {
+        // select single line or double line
+        val needSingleLine = needsKeysInSingleLine()
+        if (keysInSingleLine != needSingleLine) {
+            if (needSingleLine) {
+                parent.removeView(keysDoubleLine)
+                parent.addView(keysSingleLine)
+            } else {
+                parent.removeView(keysSingleLine)
+                parent.addView(keysDoubleLine)
+            }
+            keysInSingleLine = needSingleLine
+        }
+
+        // set visibility
+        val needShow = needToShowKeys()
+        val keys = if (keysInSingleLine) keysSingleLine else keysDoubleLine
+        keys.visibility = if (needShow) View.VISIBLE else View.GONE
+    }
+
+    // Modifier keys are required only when IME is shown and the HW qwerty keyboard is not present
+    private fun needToShowKeys(): Boolean {
+        val imeShown = activity.window.decorView.rootWindowInsets.isVisible(WindowInsets.Type.ime())
+        val hasFocus = terminalView.hasFocus()
+        val hasHwQwertyKeyboard =
+            activity.resources.configuration.keyboard == Configuration.KEYBOARD_QWERTY
+        return imeShown && hasFocus && !hasHwQwertyKeyboard
+    }
+
+    // If terminal's height is less than 30% of the screen height, we need to show modifier keys in
+    // a single line to save the vertical space
+    private fun needsKeysInSingleLine(): Boolean =
+        (terminalView.height / activity.window.decorView.height.toFloat()) < 0.3f
+
+    companion object {
+        private val BTN_KEY_CODE_MAP =
+            mapOf(
+                R.id.btn_tab to KeyEvent.KEYCODE_TAB, // Alt key sends ESC keycode
+                R.id.btn_alt to KeyEvent.KEYCODE_ESCAPE,
+                R.id.btn_esc to KeyEvent.KEYCODE_ESCAPE,
+                R.id.btn_left to KeyEvent.KEYCODE_DPAD_LEFT,
+                R.id.btn_right to KeyEvent.KEYCODE_DPAD_RIGHT,
+                R.id.btn_up to KeyEvent.KEYCODE_DPAD_UP,
+                R.id.btn_down to KeyEvent.KEYCODE_DPAD_DOWN,
+                R.id.btn_home to KeyEvent.KEYCODE_MOVE_HOME,
+                R.id.btn_end to KeyEvent.KEYCODE_MOVE_END,
+                R.id.btn_pgup to KeyEvent.KEYCODE_PAGE_UP,
+                R.id.btn_pgdn to KeyEvent.KEYCODE_PAGE_DOWN,
+            )
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt
index 7c48303..7e58b36 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.kt
@@ -100,7 +100,7 @@
                 )
                 .build()
         val notification: Notification =
-            Notification.Builder(context, context.getPackageName())
+            Notification.Builder(context, Application.CHANNEL_SYSTEM_EVENTS_ID)
                 .setSmallIcon(R.drawable.ic_launcher_foreground)
                 .setContentTitle(title)
                 .setContentText(content)
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
index 8c0368d..f8b1b45 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
@@ -149,6 +149,8 @@
             info,
             executorService!!,
             object : NsdManager.ServiceInfoCallback {
+                var started: Boolean = false
+
                 override fun onServiceInfoCallbackRegistrationFailed(errorCode: Int) {}
 
                 override fun onServiceInfoCallbackUnregistered() {}
@@ -156,9 +158,12 @@
                 override fun onServiceLost() {}
 
                 override fun onServiceUpdated(info: NsdServiceInfo) {
-                    nsdManager.unregisterServiceInfoCallback(this)
                     Log.i(TAG, "Service found: $info")
-                    startDebianServer(info.hostAddresses[0].hostAddress)
+                    if (!started) {
+                        started = true
+                        nsdManager.unregisterServiceInfoCallback(this)
+                        startDebianServer(info.hostAddresses[0].hostAddress)
+                    }
                 }
             },
         )
@@ -182,7 +187,7 @@
             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)
+        return Notification.Builder(this, Application.CHANNEL_SYSTEM_EVENTS_ID)
             .setSmallIcon(R.drawable.ic_launcher_foreground)
             .setContentTitle(stopNotificationTitle)
             .setOngoing(true)
diff --git a/android/TerminalApp/res/layout/activity_headless.xml b/android/TerminalApp/res/layout/activity_headless.xml
index b4a65cc..e18aa5c 100644
--- a/android/TerminalApp/res/layout/activity_headless.xml
+++ b/android/TerminalApp/res/layout/activity_headless.xml
@@ -48,7 +48,6 @@
                 android:layout_height="wrap_content"/>
         </LinearLayout>
         <LinearLayout
-            android:id="@+id/webview_container"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_marginBottom="5dp"
@@ -59,7 +58,6 @@
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:layout_weight="1" />
-            <include layout="@layout/layout_modifier_keys" />
         </LinearLayout>
     </FrameLayout>
 
diff --git a/android/TerminalApp/res/layout/layout_modifier_keys.xml b/android/TerminalApp/res/layout/modifier_keys_doubleline.xml
similarity index 100%
rename from android/TerminalApp/res/layout/layout_modifier_keys.xml
rename to android/TerminalApp/res/layout/modifier_keys_doubleline.xml
diff --git a/android/TerminalApp/res/layout/modifier_keys_singleline.xml b/android/TerminalApp/res/layout/modifier_keys_singleline.xml
new file mode 100644
index 0000000..6ccf48f
--- /dev/null
+++ b/android/TerminalApp/res/layout/modifier_keys_singleline.xml
@@ -0,0 +1,84 @@
+<?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.
+ -->
+<!--TODO(b/376813452): we might want tablet UI for that-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/modifier_keys"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal" >
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_esc"
+        android:textSize="10sp"
+        android:text="@string/btn_esc_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_tab"
+        android:textSize="10sp"
+        android:text="@string/btn_tab_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_ctrl"
+        android:textSize="10sp"
+        android:text="@string/btn_ctrl_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_alt"
+        android:textSize="10sp"
+        android:text="@string/btn_alt_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_home"
+        android:textSize="10sp"
+        android:text="@string/btn_home_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_end"
+        android:textSize="10sp"
+        android:text="@string/btn_end_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_left"
+        android:textSize="10sp"
+        android:text="@string/btn_left_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_down"
+        android:textSize="10sp"
+        android:text="@string/btn_down_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_up"
+        android:textSize="10sp"
+        android:text="@string/btn_up_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_right"
+        android:textSize="10sp"
+        android:text="@string/btn_right_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_pgdn"
+        android:textSize="10sp"
+        android:text="@string/btn_pgdn_text" />
+    <Button
+        style="@style/ModifierKeyStyle"
+        android:id="@+id/btn_pgup"
+        android:textSize="10sp"
+        android:text="@string/btn_pgup_text" />
+</LinearLayout>
diff --git a/android/TerminalApp/res/values-af/strings.xml b/android/TerminalApp/res/values-af/strings.xml
index 31046ae..1e8d8ff 100644
--- a/android/TerminalApp/res/values-af/strings.xml
+++ b/android/TerminalApp/res/values-af/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Poortkontrole"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Laat luisterpoorte toe of weier hulle"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Luisterpoorte"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Het toegelate poorte gestoor"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Voeg by"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Vee <xliff:g id="PORT_NUMBER">%d</xliff:g> uit"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Ongeldige poortnommer"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Poort bestaan reeds"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminaal probeer om ’n nuwe poort oop te maak"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Poort versoek: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Poort versoek: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Aanvaar"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Weier"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Herwin"</string>
diff --git a/android/TerminalApp/res/values-am/strings.xml b/android/TerminalApp/res/values-am/strings.xml
index 8f7bd25..faa7339 100644
--- a/android/TerminalApp/res/values-am/strings.xml
+++ b/android/TerminalApp/res/values-am/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"የወደብ ቁጥጥር"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"የማዳመጫ ወደቦችን ይፍቀዱ/ይከልክሉ"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"የማዳመጫ ወደቦች"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"የተቀመጡ የሚፈቀዱ ወደቦች"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"አክል"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g>ን ሰርዝ"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"ልክ ያልሆነ የወደብ ቁጥር"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"ወደብ ቀድሞውኑ ይገኛል"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ተርሚናል አዲስ ወደብ ለመክፈት እየጠየቀ ነው"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"የተጠየቀ ወደብ፦ <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"የተጠየቀ ወደብ፦ <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ተቀበል"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"ከልክል"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"መልሶ ማግኘት"</string>
diff --git a/android/TerminalApp/res/values-ar/strings.xml b/android/TerminalApp/res/values-ar/strings.xml
index 81dc053..9d1f2b7 100644
--- a/android/TerminalApp/res/values-ar/strings.xml
+++ b/android/TerminalApp/res/values-ar/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"التحكّم في المنافذ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"السماح بمنافذ الاستماع أو حظرها"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"منافذ الاستماع"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"‫<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"المنافذ المسموح بها المحفوظة"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"إضافة"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"حذف <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"رقم المنفذ غير صالح"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"المنفذ متوفِّر حاليًا"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"تطلُب الوحدة الطرفية فتح منفذ جديد"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"المنفذ المطلوب: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"المنفذ المطلوب: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"قبول"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"رفض"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"الاسترداد"</string>
diff --git a/android/TerminalApp/res/values-as/strings.xml b/android/TerminalApp/res/values-as/strings.xml
index 3f8d5f7..630efc4 100644
--- a/android/TerminalApp/res/values-as/strings.xml
+++ b/android/TerminalApp/res/values-as/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"প’ৰ্ট নিয়ন্ত্ৰণ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"শুনা প’ৰ্টৰ অনুমতি দিয়ক/অস্বীকাৰ কৰক"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"শুনা প’ৰ্ট"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"ছেভ কৰা অনুমোদিত প’ৰ্ট"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"যোগ দিয়ক"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> মচক"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"অমান্য প’ৰ্টৰ নম্বৰ"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"প’ৰ্ট ইতিমধ্যে আছে"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"টাৰ্মিনেলটোৱে এটা নতুন প’ৰ্ট খুলিবলৈ অনুৰোধ কৰি আছে"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"প\'ৰ্ট অনুৰোধ কৰা হৈছে: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"প’ৰ্ট অনুৰোধ কৰা হৈছে: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"গ্ৰহণ কৰক"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"অস্বীকাৰ কৰক"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"পুনৰুদ্ধাৰ"</string>
diff --git a/android/TerminalApp/res/values-az/strings.xml b/android/TerminalApp/res/values-az/strings.xml
index 5870590..7c134f0 100644
--- a/android/TerminalApp/res/values-az/strings.xml
+++ b/android/TerminalApp/res/values-az/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Port nəzarəti"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Dinləmə portlarına icazə verin/imtina edin"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Dinləmə portları"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Yadda saxlanılmış icazə verilən portlar"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Əlavə edin"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Silin: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Yanlış port nömrəsi"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port artıq mövcuddur"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal yeni port açmağı tələb edir"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port tələb edildi: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port tələb edildi: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Qəbul edin"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Rədd edin"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Bərpa"</string>
diff --git a/android/TerminalApp/res/values-b+sr+Latn/strings.xml b/android/TerminalApp/res/values-b+sr+Latn/strings.xml
index 9d46706..0e77081 100644
--- a/android/TerminalApp/res/values-b+sr+Latn/strings.xml
+++ b/android/TerminalApp/res/values-b+sr+Latn/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Kontrola porta"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Dozvolite ili zabranite portove za slušanje"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Portovi za slušanje"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Sačuvani dozvoljeni portovi"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Dodaj"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Izbriši <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Nevažeći broj porta"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port već postoji"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal traži da otvori novi port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Obavezan port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Obavezan port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Prihvati"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Odbij"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Oporavak"</string>
diff --git a/android/TerminalApp/res/values-be/strings.xml b/android/TerminalApp/res/values-be/strings.xml
index 003e4f5..31d1341 100644
--- a/android/TerminalApp/res/values-be/strings.xml
+++ b/android/TerminalApp/res/values-be/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Кіраванне портам"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Дазволіць (адмовіць) доступ да партоў праслухоўвання"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Парты праслухоўвання"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Захаваць дазволеныя парты"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Дадаць"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Выдаліць порт <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Няправільны нумар порта"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Порт ужо існуе"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Тэрмінал запытвае адкрыць новы порт"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Запытаны порт: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Запытаны порт: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Прыняць"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Адмовіць"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Аднаўленне"</string>
diff --git a/android/TerminalApp/res/values-bg/strings.xml b/android/TerminalApp/res/values-bg/strings.xml
index e55062c..5112c08 100644
--- a/android/TerminalApp/res/values-bg/strings.xml
+++ b/android/TerminalApp/res/values-bg/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Контрол на портовете"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Разрешаване/отхвърляне на портовете за слушане"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Портове за слушане"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Запазени разрешени портове"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Добавяне"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Изтриване на <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Невалиден номер на порт"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Портът вече съществува"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Терминалът заявява отварянето на нов порт"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Заявен порт: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Заявен порт: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Приемам"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Отказ"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Възстановя­ване"</string>
diff --git a/android/TerminalApp/res/values-bn/strings.xml b/android/TerminalApp/res/values-bn/strings.xml
index 34f45a1..fdf59b3 100644
--- a/android/TerminalApp/res/values-bn/strings.xml
+++ b/android/TerminalApp/res/values-bn/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"পোর্ট কন্ট্রোল"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"লিসিনিং পোর্টের অনুমতি দিন/অনুমতি দেবেন না"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"লিসিনিং পোর্ট"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"অনুমতি দেওয়া পোর্ট সেভ করা হয়েছে"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"যোগ করুন"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> মুছুন"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"পোর্ট নম্বর ভুল আছে"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"পোর্ট আগে থেকেই রয়েছে"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"টার্মিনাল নতুন পোর্ট খোলার অনুরোধ করছে"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"পোর্ট ফরওয়ার্ড করা সম্পর্কে অনুরোধ করা হয়েছে: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"পোর্টের অনুরোধ করা হয়েছে: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"সম্মতি দিন"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"বাতিল করুন"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"আগের অবস্থায় ফেরানো"</string>
diff --git a/android/TerminalApp/res/values-bs/strings.xml b/android/TerminalApp/res/values-bs/strings.xml
index 4ce1abd..b59bdf5 100644
--- a/android/TerminalApp/res/values-bs/strings.xml
+++ b/android/TerminalApp/res/values-bs/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Upravljanje priključkom"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Dozvoli/odbij priključke za slušanje"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Priključci za slušanje"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Sačuvani dozvoljeni priključci"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Dodavanje"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Brisanje priključka <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Nevažeći broj priključka"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Priključak već postoji"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal zahtijeva otvaranje novog priključka"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Zatražen je priključak: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Zatražen je priključak: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Prihvati"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Odbij"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Oporavak"</string>
diff --git a/android/TerminalApp/res/values-ca/strings.xml b/android/TerminalApp/res/values-ca/strings.xml
index cbb5b5b..58fdeaf 100644
--- a/android/TerminalApp/res/values-ca/strings.xml
+++ b/android/TerminalApp/res/values-ca/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Control de ports"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Permet o denega els ports d\'escolta"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Ports d\'escolta"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Ports permesos desats"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Afegeix"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Suprimeix <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"El número de port no és vàlid"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"El port ja existeix"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"El terminal està sol·licitant obrir un port nou"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port sol·licitat: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port sol·licitat: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accepta"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Denega"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recuperació"</string>
diff --git a/android/TerminalApp/res/values-cs/strings.xml b/android/TerminalApp/res/values-cs/strings.xml
index 1206132..563ad9f 100644
--- a/android/TerminalApp/res/values-cs/strings.xml
+++ b/android/TerminalApp/res/values-cs/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Ovládání portů"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Povolit/zakázat naslouchající porty"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Naslouchající porty"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Uložené povolené porty"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Přidat"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Smazat port <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Neplatné číslo portu"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port už existuje"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminál se pokouší otevřít nový port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Požadovaný port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Požadovaný port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Přijmout"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Zamítnout"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Obnovení"</string>
diff --git a/android/TerminalApp/res/values-da/strings.xml b/android/TerminalApp/res/values-da/strings.xml
index 8e8bc3f..2382c4b 100644
--- a/android/TerminalApp/res/values-da/strings.xml
+++ b/android/TerminalApp/res/values-da/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Portstyring"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Tillad/afvis aktive porte"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Aktive porte"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Gemte tilladte porte"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Tilføj"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Slet <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Ugyldigt portnummer"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Porten findes allerede"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminalen anmoder om at åbne en ny port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port, der anmodes om: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port, der anmodes om: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Acceptér"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Afvis"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Gendannelse"</string>
diff --git a/android/TerminalApp/res/values-de/strings.xml b/android/TerminalApp/res/values-de/strings.xml
index 5d488c2..bb71de3 100644
--- a/android/TerminalApp/res/values-de/strings.xml
+++ b/android/TerminalApp/res/values-de/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Portsteuerung"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Überwachungsports zulassen / ablehnen"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Überwachungsports"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Gespeicherte zulässige Ports"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Hinzufügen"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"„<xliff:g id="PORT_NUMBER">%d</xliff:g>“ löschen"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Ungültige Portnummer"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port ist bereits vorhanden"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal fordert an, einen neuen Port zu öffnen"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Angeforderter Port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Angeforderter Port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Akzeptieren"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Ablehnen"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Wieder­herstellung"</string>
diff --git a/android/TerminalApp/res/values-el/strings.xml b/android/TerminalApp/res/values-el/strings.xml
index 15606c1..72882b8 100644
--- a/android/TerminalApp/res/values-el/strings.xml
+++ b/android/TerminalApp/res/values-el/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Έλεγχος θυρών"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Να επιτρέπονται/μην επιτρέπονται οι θύρες ακρόασης"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Θύρες ακρόασης"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Αποθηκευμένες επιτρεπόμενες θύρες"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Προσθήκη"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Διαγραφή θύρας <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Μη έγκυρος αριθμός θύρας"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Η θύρα υπάρχει ήδη"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Το τερματικό ζητά να ανοίξει μια νέα θύρα"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Ζητήθηκε θύρα: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Ζητήθηκε θύρα: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Αποδοχή"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Απόρριψη"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Ανάκτηση"</string>
diff --git a/android/TerminalApp/res/values-en-rAU/strings.xml b/android/TerminalApp/res/values-en-rAU/strings.xml
index c02591c..f208e38 100644
--- a/android/TerminalApp/res/values-en-rAU/strings.xml
+++ b/android/TerminalApp/res/values-en-rAU/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Port control"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Allow/deny listening ports"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Listening ports"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Saved allowed ports"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Add"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Delete <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Invalid port number"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port already exists"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal is requesting to open a new port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port requested: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port requested: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accept"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Deny"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recovery"</string>
diff --git a/android/TerminalApp/res/values-en-rCA/strings.xml b/android/TerminalApp/res/values-en-rCA/strings.xml
index c02591c..f208e38 100644
--- a/android/TerminalApp/res/values-en-rCA/strings.xml
+++ b/android/TerminalApp/res/values-en-rCA/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Port control"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Allow/deny listening ports"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Listening ports"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Saved allowed ports"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Add"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Delete <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Invalid port number"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port already exists"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal is requesting to open a new port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port requested: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port requested: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accept"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Deny"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recovery"</string>
diff --git a/android/TerminalApp/res/values-en-rGB/strings.xml b/android/TerminalApp/res/values-en-rGB/strings.xml
index c02591c..f208e38 100644
--- a/android/TerminalApp/res/values-en-rGB/strings.xml
+++ b/android/TerminalApp/res/values-en-rGB/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Port control"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Allow/deny listening ports"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Listening ports"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Saved allowed ports"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Add"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Delete <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Invalid port number"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port already exists"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal is requesting to open a new port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port requested: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port requested: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accept"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Deny"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recovery"</string>
diff --git a/android/TerminalApp/res/values-en-rIN/strings.xml b/android/TerminalApp/res/values-en-rIN/strings.xml
index c02591c..f208e38 100644
--- a/android/TerminalApp/res/values-en-rIN/strings.xml
+++ b/android/TerminalApp/res/values-en-rIN/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Port control"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Allow/deny listening ports"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Listening ports"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Saved allowed ports"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Add"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Delete <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Invalid port number"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port already exists"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal is requesting to open a new port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port requested: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port requested: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accept"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Deny"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recovery"</string>
diff --git a/android/TerminalApp/res/values-es-rUS/strings.xml b/android/TerminalApp/res/values-es-rUS/strings.xml
index 3aeb2f2..ff2ae6d 100644
--- a/android/TerminalApp/res/values-es-rUS/strings.xml
+++ b/android/TerminalApp/res/values-es-rUS/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Control del puerto"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Permitir o denegar los puertos de escucha"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Puertos de escucha"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Puertos permitidos guardados"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Agregar"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Borrar <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"El número de puerto no es válido"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"El puerto ya existe"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"La terminal está solicitando abrir un puerto nuevo"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Puerto solicitado: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Puerto solicitado: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Aceptar"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Rechazar"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recuperación"</string>
diff --git a/android/TerminalApp/res/values-es/strings.xml b/android/TerminalApp/res/values-es/strings.xml
index f7dfa95..0a8932e 100644
--- a/android/TerminalApp/res/values-es/strings.xml
+++ b/android/TerminalApp/res/values-es/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Control de puerto"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Permitir/Denegar puertos de escucha"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Puertos de escucha"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Puertos permitidos guardados"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Añadir"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Eliminar <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Número de puerto no válido"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"El puerto ya existe"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"El terminal está solicitando abrir un nuevo puerto"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Puerto solicitado: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Puerto solicitado: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Aceptar"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Denegar"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recuperación"</string>
diff --git a/android/TerminalApp/res/values-et/strings.xml b/android/TerminalApp/res/values-et/strings.xml
index affff44..d6754d8 100644
--- a/android/TerminalApp/res/values-et/strings.xml
+++ b/android/TerminalApp/res/values-et/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Portide haldamine"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Kuulamisportide lubamine/keelamine"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Kuulamispordid"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Salvestatud lubatud pordid"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Lisa"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Kustuta <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Sobimatu pordi number"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port on juba olemas"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal taotleb uue pordi avamist"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Taotletud port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Taotletud port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Nõustu"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Keela"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Taastamine"</string>
diff --git a/android/TerminalApp/res/values-eu/strings.xml b/android/TerminalApp/res/values-eu/strings.xml
index e65c992..0cdcca5 100644
--- a/android/TerminalApp/res/values-eu/strings.xml
+++ b/android/TerminalApp/res/values-eu/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Ataka kontrolatzeko aukerak"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Onartu/Baztertu ataka aktiboak"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Ataka aktiboak"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Gorde dira onartutako atakak"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Gehitu"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Ezabatu <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Ataka-zenbakiak ez du balio"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Ataka jada badago"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminalak beste ataka bat irekitzeko eskatu du"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Ataka hau eskatu da: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Ataka hau eskatu da: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Onartu"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Ukatu"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Berreskuratzea"</string>
diff --git a/android/TerminalApp/res/values-fa/strings.xml b/android/TerminalApp/res/values-fa/strings.xml
index 7ce2713c9..4ec4d0a 100644
--- a/android/TerminalApp/res/values-fa/strings.xml
+++ b/android/TerminalApp/res/values-fa/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"کنترل درگاه"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"مجاز/ رد کردن درگاه‌های گوش کردن"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"درگاه‌های گوش کردن"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"‫<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"درگاه‌های مجاز ذخیره شدند"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"افزودن"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"حذف کردن <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"شماره درگاه نامعتبر است"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"درگاه ازقبل موجود است"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"پایانه می‌خواهد درگاه جدیدی باز کند"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"درگاه درخواست‌شده: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"درگاه درخواست‌شده: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"پذیرفتن"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"رد کردن"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"بازیابی"</string>
diff --git a/android/TerminalApp/res/values-fi/strings.xml b/android/TerminalApp/res/values-fi/strings.xml
index 5d7a66b..aec6a47 100644
--- a/android/TerminalApp/res/values-fi/strings.xml
+++ b/android/TerminalApp/res/values-fi/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Porttien ohjaus"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Salli/kiellä kuunteluportit"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Kuunteluportit"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Tallennetut sallitut portit"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Lisää"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Poista <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Virheellinen portin numero"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Portti on jo olemassa"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Pääte yrittää avata uuden portin"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Pyydetty portti: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Pyydetty portti: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Hyväksy"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Hylkää"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Palautus"</string>
diff --git a/android/TerminalApp/res/values-fr-rCA/strings.xml b/android/TerminalApp/res/values-fr-rCA/strings.xml
index 4a0a9c3..7d54372 100644
--- a/android/TerminalApp/res/values-fr-rCA/strings.xml
+++ b/android/TerminalApp/res/values-fr-rCA/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Contrôle du port"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Autoriser/Refuser les ports en mode Réception"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Ports en mode Réception"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Ports autorisés enregistrés"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Ajouter"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Supprimer le port <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Numéro de port incorrect"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Le port existe déjà"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Le terminal demande d\'ouvrir un nouveau port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port demandé : <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port demandé : <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accepter"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Refuser"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Récupération"</string>
diff --git a/android/TerminalApp/res/values-fr/strings.xml b/android/TerminalApp/res/values-fr/strings.xml
index f043582..3fe8772 100644
--- a/android/TerminalApp/res/values-fr/strings.xml
+++ b/android/TerminalApp/res/values-fr/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Contrôle de port"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Autoriser/refuser les ports d\'écoute"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Ports d\'écoute"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Ports autorisés enregistrés"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Ajouter"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Supprimer <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Numéro de port incorrect"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Le port existe déjà"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Le terminal demande l\'ouverture d\'un nouveau port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port demandé : <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port demandé : <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accepter"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Refuser"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Récupération"</string>
diff --git a/android/TerminalApp/res/values-gl/strings.xml b/android/TerminalApp/res/values-gl/strings.xml
index 6435389..ec98910 100644
--- a/android/TerminalApp/res/values-gl/strings.xml
+++ b/android/TerminalApp/res/values-gl/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Control de portos"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Permitir ou rexeitar portos de escoita"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Portos de escoita"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Gardáronse os portos permitidos"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Engadir"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Eliminar <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"O número de porto non é válido"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Xa existe o porto"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"O terminal está solicitando que se abra outro porto"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Porto solicitado: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Porto solicitado: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Aceptar"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Denegar"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recuperación"</string>
diff --git a/android/TerminalApp/res/values-gu/strings.xml b/android/TerminalApp/res/values-gu/strings.xml
index c21c364..d53d3eb 100644
--- a/android/TerminalApp/res/values-gu/strings.xml
+++ b/android/TerminalApp/res/values-gu/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"પોર્ટ નિયંત્રણ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"સાંભળનાર પોર્ટને મંજૂરી આપો/નકારો"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"સાંભળનાર પોર્ટ"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"સાચવેલા મંજૂરીપ્રાપ્ત પોર્ટ"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"ઉમેરો"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> ડિલીટ કરો"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"પોર્ટ નંબર અમાન્ય છે"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"પોર્ટ પહેલેથી અસ્તિત્વમાં છે"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ટર્મિનલ નવું પોર્ટ ખોલવા માટે વિનંતી કરી રહ્યું છે"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"પોર્ટની વિનંતી કરવામાં આવી: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"પોર્ટ કરવાની વિનંતી કરવામાં આવી: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"સ્વીકારો"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"નકારો"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"રિકવરી"</string>
diff --git a/android/TerminalApp/res/values-hi/strings.xml b/android/TerminalApp/res/values-hi/strings.xml
index e0242d3..b644e1f 100644
--- a/android/TerminalApp/res/values-hi/strings.xml
+++ b/android/TerminalApp/res/values-hi/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"पोर्ट कंट्रोल"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"लिसनिंग पोर्ट को अनुमति दें या अनुमति न दें"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"लिसनिंग पोर्ट"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"अनुमति पा चुके सभी पोर्ट को सेव किया गया"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"जोड़ें"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> को मिटाएं"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"अमान्य पोर्ट संख्या"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"पोर्ट पहले से मौजूद है"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"टर्मिनल, एक नया पोर्ट खोलने का अनुरोध कर रहा है"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"पोर्ट खोलने का अनुरोध किया गया: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"पोर्ट खोलने का अनुरोध किया गया: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"स्वीकार करें"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"अस्वीकार करें"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"इमेज रिकवर करें"</string>
diff --git a/android/TerminalApp/res/values-hr/strings.xml b/android/TerminalApp/res/values-hr/strings.xml
index 7027632..8ce5af5 100644
--- a/android/TerminalApp/res/values-hr/strings.xml
+++ b/android/TerminalApp/res/values-hr/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Kontrola priključka"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Dopusti/odbij priključke za slušanje"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Priključci za slušanje"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Spremljeni dopušteni priključci"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Dodaj"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Izbriši priključak <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Nevažeći broj priključka"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Priključak već postoji"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal zahtijeva da se otvori novi priključak"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Zatraženi priključak: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Zatraženi priključak: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Prihvati"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Odbij"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Oporavak"</string>
diff --git a/android/TerminalApp/res/values-hu/strings.xml b/android/TerminalApp/res/values-hu/strings.xml
index 8195547..f3058d0 100644
--- a/android/TerminalApp/res/values-hu/strings.xml
+++ b/android/TerminalApp/res/values-hu/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Portvezérlés"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Figyelő portok engedélyezése/letiltása"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Figyelő portok"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Mentett engedélyezett portok"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Hozzáadás"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> törlése"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Érvénytelen a portszám"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"A port már létezik"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"A terminál új port megnyitását kéri"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Kért port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Kért port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Elfogadás"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Elutasítás"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Helyreállítás"</string>
diff --git a/android/TerminalApp/res/values-hy/strings.xml b/android/TerminalApp/res/values-hy/strings.xml
index ecf0cb9..f11469b 100644
--- a/android/TerminalApp/res/values-hy/strings.xml
+++ b/android/TerminalApp/res/values-hy/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Միացքների կառավարում"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Թույլատրել/մերժել ունկնդրման միացքները"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Ունկնդրման միացքներ"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Պահված թույլատրված միացքներ"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Ավելացնել"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Ջնջել <xliff:g id="PORT_NUMBER">%d</xliff:g> համարի միացքը"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Միացքի անվավեր համար"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Միացքն արդեն գոյություն ունի"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Տերմինալը խնդրում է նոր միացք բացել"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Հարցված միացքը՝ <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Հարցված միացքը՝ <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Ընդունել"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Մերժել"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Վերականգ­նում"</string>
diff --git a/android/TerminalApp/res/values-in/strings.xml b/android/TerminalApp/res/values-in/strings.xml
index c8d16f3..a2c4b01 100644
--- a/android/TerminalApp/res/values-in/strings.xml
+++ b/android/TerminalApp/res/values-in/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Kontrol port"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Izinkan/tolak port yang sedang dalam proses"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Port yang sedang dalam proses"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Port yang diizinkan tersimpan"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Tambahkan"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Hapus <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Nomor port tidak valid"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port sudah ada"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal meminta untuk membuka port baru"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port yang diminta: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port yang diminta: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Terima"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Tolak"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Pemulihan"</string>
diff --git a/android/TerminalApp/res/values-is/strings.xml b/android/TerminalApp/res/values-is/strings.xml
index 277e807..2e97d0c 100644
--- a/android/TerminalApp/res/values-is/strings.xml
+++ b/android/TerminalApp/res/values-is/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Gáttarstýring"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Leyfa hlustunargáttir/hafna hlustunargáttum"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Hlustunargáttir"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Vistaðar leyfðar gáttir"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Bæta við"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Eyða <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Ógilt númer tengis"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Tengi er þegar til"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Útstöðin bað um að opna nýja gátt"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Beiðni um gátt: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Gátt sem beðið var um: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Samþykkja"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Hafna"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Endurheimt"</string>
diff --git a/android/TerminalApp/res/values-it/strings.xml b/android/TerminalApp/res/values-it/strings.xml
index 8dfb347..1cfd2b5 100644
--- a/android/TerminalApp/res/values-it/strings.xml
+++ b/android/TerminalApp/res/values-it/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Controllo porte"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Consenti/rifiuta porte di ascolto"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Porte di ascolto"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Porte consentite salvate"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Aggiungi"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Elimina <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Numero di porta non valido"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"La porta esiste già"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Il terminale sta chiedendo di aprire una nuova porta"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Porta richiesta: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Porta richiesta: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accetta"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Rifiuta"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Ripristino"</string>
diff --git a/android/TerminalApp/res/values-iw/strings.xml b/android/TerminalApp/res/values-iw/strings.xml
index 91e768e..8859e5f 100644
--- a/android/TerminalApp/res/values-iw/strings.xml
+++ b/android/TerminalApp/res/values-iw/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"בקרת יציאות"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"אישור או דחייה של יציאות להאזנה"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"יציאות להאזנה"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"‫<xliff:g id="PORT_NUMBER">%1$d</xliff:g> ‏(<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"יציאות מורשות שנשמרו"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"הוספה"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"מחיקה של <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"מספר היציאה לא תקין"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"היציאה כבר קיימת"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"הטרמינל מבקש לפתוח יציאה חדשה"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"נשלחה בקשה ליציאה: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"נשלחה בקשה ליציאה: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> ‏(<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"אישור"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"דחייה"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"שחזור"</string>
diff --git a/android/TerminalApp/res/values-ja/strings.xml b/android/TerminalApp/res/values-ja/strings.xml
index b4c1cd9..19c4af8 100644
--- a/android/TerminalApp/res/values-ja/strings.xml
+++ b/android/TerminalApp/res/values-ja/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"ポートの管理"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"リスニング ポートの許可 / 拒否"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"リスニング ポート"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g>(<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"保存済みの許可ポート"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"追加"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> を削除"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"ポート番号が無効です"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"ポートはすでに存在します"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ターミナルが新しいポートを開くリクエストをしました"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"移行リクエスト済み: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"リクエストされたポート: <xliff:g id="PORT_NUMBER">%1$d</xliff:g>(<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"許可する"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"許可しない"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"リカバリ"</string>
diff --git a/android/TerminalApp/res/values-ka/strings.xml b/android/TerminalApp/res/values-ka/strings.xml
index c2c500f..be79f8b 100644
--- a/android/TerminalApp/res/values-ka/strings.xml
+++ b/android/TerminalApp/res/values-ka/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"პორტის მართვა"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"მოსმენის პორტების დაშვება/აკრძალვა"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"მოსმენის პორტები"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"შენახული დაშვებული პორტები"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"დამატება"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g>-ის წაშლა"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"პორტის არასწორი ნომერი"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"პორტი უკვე არსებობს"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ტერმინალი ითხოვს ახალი პორტის გახსნას"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"მოთხოვნილი პორტი: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"მოთხოვნილი პორტი: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"დათანხმება"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"უარყოფა"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"აღდგენა"</string>
diff --git a/android/TerminalApp/res/values-kk/strings.xml b/android/TerminalApp/res/values-kk/strings.xml
index d8c49bd..5477c04 100644
--- a/android/TerminalApp/res/values-kk/strings.xml
+++ b/android/TerminalApp/res/values-kk/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Портты басқару"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Тыңдау порттарына рұқсат беру/тыйым салу"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Тыңдау порттары"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Рұқсат берілген порттар сақталды"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Қосу"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> портты жою"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Порт нөмірі жарамсыз."</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Порт бұрыннан бар."</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Терминал жаңа порт ашуды сұрайды"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Қажетті порт: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Қажетті порт: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Қабылдау"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Қабылдамау"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Қалпына келтіру"</string>
diff --git a/android/TerminalApp/res/values-km/strings.xml b/android/TerminalApp/res/values-km/strings.xml
index 28a1620..1ec9a0a 100644
--- a/android/TerminalApp/res/values-km/strings.xml
+++ b/android/TerminalApp/res/values-km/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"ការគ្រប់គ្រងច្រក"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"អនុញ្ញាត/បដិសេធច្រកស្ដាប់"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"ច្រកស្ដាប់"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"បានរក្សាទុកច្រកដែលត្រូវបានអនុញ្ញាត"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"បញ្ចូល"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"លុប <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"លេខច្រកមិនត្រឹមត្រូវ"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"មានច្រករួចហើយ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ទែមីណាល់កំពុងស្នើសុំបើកច្រកថ្មី"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"បានស្នើសុំច្រក៖ <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"បានស្នើសុំច្រក៖ <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ទទួលយក"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"បដិសេធ"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"ស្ដារ"</string>
diff --git a/android/TerminalApp/res/values-kn/strings.xml b/android/TerminalApp/res/values-kn/strings.xml
index a17c185..3c53299 100644
--- a/android/TerminalApp/res/values-kn/strings.xml
+++ b/android/TerminalApp/res/values-kn/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"ಪೋರ್ಟ್ ನಿಯಂತ್ರಣ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"ಆಲಿಸುವ ಪೋರ್ಟ್‌ಗಳನ್ನು ಅನುಮತಿಸಿ/ನಿರಾಕರಿಸಿ"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"ಆಲಿಸುವ ಪೋರ್ಟ್‌ಗಳು"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"ಅನುಮತಿಸಲಾದ ಪೋರ್ಟ್‌ಗಳನ್ನು ಸೇವ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"ಸೇರಿಸಿ"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> ಅನ್ನು ಅಳಿಸಿ"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"ಅಮಾನ್ಯ ಪೋರ್ಟ್ ಸಂಖ್ಯೆ"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"ಪೋರ್ಟ್ ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ಟರ್ಮಿನಲ್‌ ಹೊಸ ಪೋರ್ಟ್‌ ಅನ್ನು ತೆರೆಯಲು ವಿನಂತಿಸುತ್ತಿದೆ"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"ಪೋರ್ಟ್ ಅನ್ನು ವಿನಂತಿಸಲಾಗಿದೆ: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"ಪೋರ್ಟ್ ಅನ್ನು ವಿನಂತಿಸಲಾಗಿದೆ: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ಸಮ್ಮತಿಸಿ"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"ನಿರಾಕರಿಸಿ"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"ರಿಕವರಿ"</string>
diff --git a/android/TerminalApp/res/values-ko/strings.xml b/android/TerminalApp/res/values-ko/strings.xml
index 9ecaca7..4ec1613 100644
--- a/android/TerminalApp/res/values-ko/strings.xml
+++ b/android/TerminalApp/res/values-ko/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"포트 제어"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"리스닝 포트 허용/거부"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"리스닝 포트"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g>(<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"저장된 허용 포트"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"추가"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> 삭제"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"포트 번호가 잘못되었습니다."</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"포트가 이미 존재합니다."</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"터미널에서 새 포트를 열려고 합니다"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"요청된 포트: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"요청된 포트: <xliff:g id="PORT_NUMBER">%1$d</xliff:g>(<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"수락"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"거부"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"복구"</string>
diff --git a/android/TerminalApp/res/values-ky/strings.xml b/android/TerminalApp/res/values-ky/strings.xml
index 9268dae..17fc4ea 100644
--- a/android/TerminalApp/res/values-ky/strings.xml
+++ b/android/TerminalApp/res/values-ky/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Портту көзөмөлдөө"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Угуу портторуна уруксат берүү/тыюу салуу"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Угуу порттору"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Уруксат берилген порттор сакталды"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Кошуу"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Өчүрүү: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Порттун номери жараксыз"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Порт бар"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Терминал жаңы оюкчаны ачууну суранып жатат"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Оюкча суралды: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Оюкча суралды: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Кабыл алуу"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Четке кагуу"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Калыбына келтирүү"</string>
diff --git a/android/TerminalApp/res/values-lo/strings.xml b/android/TerminalApp/res/values-lo/strings.xml
index 7854f77..cb8bc0c 100644
--- a/android/TerminalApp/res/values-lo/strings.xml
+++ b/android/TerminalApp/res/values-lo/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"ການຄວບຄຸມຜອດ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"ອະນຸຍາດ/ປະຕິເສດຜອດການຟັງ"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"ຜອດການຟັງ"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"ຜອດທີ່ອະນຸຍາດເຊິ່ງບັນທຶກໄວ້"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"ເພີ່ມ"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"ລຶບ <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"ໝາຍເລກຜອດບໍ່ຖືກຕ້ອງ"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"ມີຜອດຢູ່ກ່ອນແລ້ວ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ເທີມິນອນກຳລັງສົ່ງຄຳຮ້ອງຂໍໃຫ້ເປີດຜອດໃໝ່"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"ຜອດທີ່ຮ້ອງຂໍ: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"ຜອດທີ່ຮ້ອງຂໍ: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ຍອມຮັບ"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"ປະຕິເສດ"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"ການກູ້ຄືນ"</string>
diff --git a/android/TerminalApp/res/values-lt/strings.xml b/android/TerminalApp/res/values-lt/strings.xml
index 919c4ef..76f5158 100644
--- a/android/TerminalApp/res/values-lt/strings.xml
+++ b/android/TerminalApp/res/values-lt/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Prievado valdymas"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Leisti klausymo prievadus / neleisti jų"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Klausymo prievadai"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Išsaugoti leidžiami prievadai"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Pridėti"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Ištrinti <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Netinkamas prievado numeris"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Prievadas jau yra"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminalas bando atidaryti naują prievadą"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Prievadas, kurio užklausa pateikta: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Prievadas, kurio užklausa pateikta: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Sutikti"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Atmesti"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Atkūrimas"</string>
diff --git a/android/TerminalApp/res/values-lv/strings.xml b/android/TerminalApp/res/values-lv/strings.xml
index b888f53..a0730a1 100644
--- a/android/TerminalApp/res/values-lv/strings.xml
+++ b/android/TerminalApp/res/values-lv/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Portu kontrole"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Atļaut/aizliegt klausīšanās portus"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Klausīšanās porti"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Saglabātie atļautie porti"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Pievienot"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Dzēst <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Nederīgs porta numurs"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Ports jau pastāv"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminālis pieprasa jauna porta atvēršanu"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Pieprasītais ports: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Pieprasītais ports: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Piekrist"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Noraidīt"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Atkopšana"</string>
@@ -77,7 +78,7 @@
     <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Dublējuma datu noņemšana"</string>
     <string name="settings_recovery_remove_backup_sub_title" msgid="7791375988320242059">"Datu noņemšana no ceļa <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
     <string name="error_title" msgid="405150657301906598">"Neatkopjama kļūda"</string>
-    <string name="error_desc" msgid="4588252235686826721">"Neizdevās veikt atkopšanu pēc kļūdas.\nVarat restartēt termināli vai izmēģināt kādu no atkopšanas opcijām.\nJa neviens mēģinājums neizdodas, notīriet visus datus, izstrādātāja opcijās ieslēdzot/izslēdzot Linux termināli."</string>
+    <string name="error_desc" msgid="4588252235686826721">"Neizdevās veikt atkopšanu pēc kļūdas.\nVarat restartēt termināli vai izmēģināt kādu no atkopšanas opcijām.\nJa neviens mēģinājums neizdodas, notīriet visus datus, izstrādātāju opcijās ieslēdzot/izslēdzot Linux termināli."</string>
     <string name="error_code" msgid="3585291676855383649">"Kļūdas kods: <xliff:g id="ERROR_CODE">%s</xliff:g>"</string>
     <string name="service_notification_settings" msgid="1437365721184401135">"Iestatījumi"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminālis darbojas"</string>
diff --git a/android/TerminalApp/res/values-mk/strings.xml b/android/TerminalApp/res/values-mk/strings.xml
index 123074c..ac328d7 100644
--- a/android/TerminalApp/res/values-mk/strings.xml
+++ b/android/TerminalApp/res/values-mk/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Контрола на портите"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Дозволете/одбијте порти за примање барања"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Порти за примање барања"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Дозволените порти се зачувани"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Додај"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Избриши <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Неважечки број на порта"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Портата веќе постои"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Терминалот бара да отвори нова порта"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Побарана е порта: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Побарана е порта: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Прифати"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Одбиј"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Враќање"</string>
diff --git a/android/TerminalApp/res/values-ml/strings.xml b/android/TerminalApp/res/values-ml/strings.xml
index edf01b7..1ff795d 100644
--- a/android/TerminalApp/res/values-ml/strings.xml
+++ b/android/TerminalApp/res/values-ml/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"പോർട്ട് നിയന്ത്രണം"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"ശ്രവണ പോർട്ടുകൾ അനുവദിക്കുക/നിരസിക്കുക"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"ശ്രവണ പോർട്ടുകൾ"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"സംരക്ഷിച്ച അനുവദനീയമായ പോർട്ടുകൾ"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"ചേർക്കുക"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> ഇല്ലാതാക്കുക"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"പോർട്ട് നമ്പർ അസാധുവാണ്"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"പോർട്ട് ഇതിനകം നിലവിലുണ്ട്"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ഒരു പുതിയ പോർട്ട് തുറക്കാൻ ടെർമിനൽ അഭ്യർത്ഥിക്കുന്നു"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"പോർട്ട് അഭ്യർത്ഥിച്ചു: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"അഭ്യർത്ഥിച്ച പോർട്ട്: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"അംഗീകരിക്കുക"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"നിരസിക്കുക"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"വീണ്ടെടുക്കുക"</string>
diff --git a/android/TerminalApp/res/values-mn/strings.xml b/android/TerminalApp/res/values-mn/strings.xml
index 20a5925..5b6ce4a 100644
--- a/android/TerminalApp/res/values-mn/strings.xml
+++ b/android/TerminalApp/res/values-mn/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Портын тохиргоо"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Сүлжээний хүсэлт хүлээж буй портуудыг зөвшөөрөх/татгалзах"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Сүлжээний хүсэлт хүлээж буй портууд"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Хадгалсан зөвшөөрөгдсөн портууд"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Нэмэх"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g>-г устгах"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Портын дугаар буруу байна"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Порт аль хэдийн байна"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Терминал шинэ порт нээхийг хүсэж байна"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Хүссэн порт: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Хүссэн порт: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Зөвшөөрөх"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Татгалзах"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Сэргээх"</string>
diff --git a/android/TerminalApp/res/values-mr/strings.xml b/android/TerminalApp/res/values-mr/strings.xml
index eb5e53c..1701983 100644
--- a/android/TerminalApp/res/values-mr/strings.xml
+++ b/android/TerminalApp/res/values-mr/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"पोर्ट नियंत्रण"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"ऐकण्याच्या पोर्टना अनुमती द्या/नाकारा"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"ऐकण्याचे पोर्ट"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"सेव्ह केलेले व अनुमती असलेले पोर्ट"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"जोडा"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> हटवा"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"पोर्ट नंबर चुकीचा आहे"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"पोर्ट आधीपासून अस्तित्वात आहे"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"टर्मिनल नवीन पोर्ट उघडण्याची विनंती करत आहे"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"विनंती केलेला पोर्ट: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"पोर्टसंबंधित विनंती केली: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"स्वीकारा"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"नकार द्या"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"रिकव्हरी"</string>
diff --git a/android/TerminalApp/res/values-ms/strings.xml b/android/TerminalApp/res/values-ms/strings.xml
index 07d2221..1709e51 100644
--- a/android/TerminalApp/res/values-ms/strings.xml
+++ b/android/TerminalApp/res/values-ms/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Kawalan port"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Benarkan/tolak port mendengar"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Port mendengar"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Port yang dibenarkan disimpan"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Tambah"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Padamkan <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Nombor port tidak sah"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port sudah wujud"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal membuat permintaan untuk membuka port baharu"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port diminta: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port diminta: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Terima"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Tolak"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Pemulihan"</string>
diff --git a/android/TerminalApp/res/values-my/strings.xml b/android/TerminalApp/res/values-my/strings.xml
index 815dd19..dc3e555 100644
--- a/android/TerminalApp/res/values-my/strings.xml
+++ b/android/TerminalApp/res/values-my/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"ပို့တ်ထိန်းချုပ်မှု"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"စောင့်နေသောပို့တ်များကို ခွင့်ပြုရန်/ငြင်းပယ်ရန်"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"စောင့်နေသောပို့တ်များ"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"ခွင့်ပြုထားသောပို့တ်များ သိမ်းပြီးပြီ"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"ထည့်ရန်"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> ကို ဖျက်ရန်"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"ပို့တ်နံပါတ် မမှန်ပါ"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"ပို့တ်ရှိပြီးသားဖြစ်သည်"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"တာမီနယ်က ပို့တ်အသစ်ဖွင့်ရန် တောင်းဆိုနေသည်"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"တောင်းဆိုထားသော ပို့တ်- <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"တောင်းဆိုထားသော ပို့တ်- <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"လက်ခံရန်"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"ငြင်းပယ်ရန်"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"ပြန်လည်ရယူခြင်း"</string>
diff --git a/android/TerminalApp/res/values-nb/strings.xml b/android/TerminalApp/res/values-nb/strings.xml
index 1423e22..c0a84e5 100644
--- a/android/TerminalApp/res/values-nb/strings.xml
+++ b/android/TerminalApp/res/values-nb/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Portkontroll"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Tillat/avslå lytteporter"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Lytteporter"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Lagrede tillatte porter"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Legg til"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Slett <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Ugyldig portnummer"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Porten finnes allerede"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminalen prøver å åpne en ny port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Forespurt port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Ønsket port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Godta"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Avvis"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Gjenoppretting"</string>
diff --git a/android/TerminalApp/res/values-ne/strings.xml b/android/TerminalApp/res/values-ne/strings.xml
index 025cfe5..8cbda87 100644
--- a/android/TerminalApp/res/values-ne/strings.xml
+++ b/android/TerminalApp/res/values-ne/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"पोर्टसम्बन्धी कन्ट्रोल"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"लिसनिङ पोर्टहरू हाल्ने अनुमति दिनुहोस्/नदिनुहोस्"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"लिसनिङ पोर्टहरू"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"सेभ गरिएका अनुमति दिइएका पोर्टहरू"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"हाल्नुहोस्"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> मेटाउनुहोस्"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"अवैध पोर्ट नम्बर"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"पोर्ट पहिल्यैदेखि छ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"टर्मिनलले एउटा नयाँ पोर्ट खोल्न अनुरोध गरिरहेको छ"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"निम्न पोर्ट खोल्न अनुरोध गरिएको छ: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"निम्न पोर्ट खोल्न अनुरोध गरिएको छ: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"स्वीकार गर्नुहोस्"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"अस्वीकार गर्नुहोस्"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"रिकभरी"</string>
diff --git a/android/TerminalApp/res/values-nl/strings.xml b/android/TerminalApp/res/values-nl/strings.xml
index 8f68f11..27fbc26 100644
--- a/android/TerminalApp/res/values-nl/strings.xml
+++ b/android/TerminalApp/res/values-nl/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Poortcontrole"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Luisterende poorten toestaan/weigeren"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Luisterende poorten"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Toegestane poorten opgeslagen"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Toevoegen"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> verwijderen"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Ongeldig poortnummer"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Poort bestaat al"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal verzoekt om een nieuwe poort te openen"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Poort aangevraagd: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Poort aangevraagd: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Accepteren"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Weigeren"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Herstel"</string>
diff --git a/android/TerminalApp/res/values-or/strings.xml b/android/TerminalApp/res/values-or/strings.xml
index c6a67ae..034849f 100644
--- a/android/TerminalApp/res/values-or/strings.xml
+++ b/android/TerminalApp/res/values-or/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"ପୋର୍ଟ ନିୟନ୍ତ୍ରଣ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"ଶୁଣିବା ପୋର୍ଟଗୁଡ଼ିକୁ ଅନୁମତି ଦିଅନ୍ତୁ/ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"ଶୁଣିବା ପୋର୍ଟ"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"ଅନୁମତି ଦିଆଯାଇଥିବା ପୋର୍ଟଗୁଡ଼ିକୁ ସେଭ କରାଯାଇଛି"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"ଯୋଗ କରନ୍ତୁ"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g>କୁ ଡିଲିଟ କରନ୍ତୁ"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"ଅବୈଧ ପୋର୍ଟ ନମ୍ବର"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"ପୋର୍ଟ ପୂର୍ବରୁ ଉପଲବ୍ଧ ଅଛି"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ଏକ ନୂଆ ପୋର୍ଟ ଖୋଲିବାକୁ ଟର୍ମିନାଲ ଅନୁରୋଧ କରୁଛି"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"ପୋର୍ଟ ପାଇଁ ଅନୁରୋଧ କରାଯାଇଛି: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"ପୋର୍ଟ ପାଇଁ ଅନୁରୋଧ କରାଯାଇଛି: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ଗ୍ରହଣ କରନ୍ତୁ"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"ରିକଭରି"</string>
diff --git a/android/TerminalApp/res/values-pa/strings.xml b/android/TerminalApp/res/values-pa/strings.xml
index 3639329..b6af472 100644
--- a/android/TerminalApp/res/values-pa/strings.xml
+++ b/android/TerminalApp/res/values-pa/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"ਪੋਰਟ ਕੰਟਰੋਲ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"ਲਿਸਨਿੰਗ ਪੋਰਟਾਂ ਨੂੰ ਆਗਿਆ ਦਿਓ/ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"ਲਿਸਨਿੰਗ ਪੋਰਟ"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"ਮਨਜ਼ੂਰਸ਼ੁਦਾ ਪੋਰਟ ਰੱਖਿਅਤ ਕੀਤੇ ਗਏ"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> ਨੂੰ ਮਿਟਾਓ"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"ਅਵੈਧ ਪੋਰਟ ਨੰਬਰ"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"ਪੋਰਟ ਪਹਿਲਾਂ ਤੋਂ ਹੀ ਮੌਜੂਦ ਹੈ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ਟਰਮੀਨਲ ਇੱਕ ਨਵੇਂ ਪੋਰਟ ਨੂੰ ਖੋਲ੍ਹਣ ਦੀ ਬੇਨਤੀ ਕਰ ਰਿਹਾ ਹੈ"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"ਪੋਰਟ ਸੰਬੰਧੀ ਬੇਨਤੀ ਕੀਤੀ ਗਈ: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"ਪੋਰਟ ਸੰਬੰਧੀ ਬੇਨਤੀ ਕੀਤੀ ਗਈ: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"ਰਿਕਵਰੀ"</string>
diff --git a/android/TerminalApp/res/values-pl/strings.xml b/android/TerminalApp/res/values-pl/strings.xml
index 485f7bb..92a6dea 100644
--- a/android/TerminalApp/res/values-pl/strings.xml
+++ b/android/TerminalApp/res/values-pl/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Kontrola portów"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Zezwalaj/odrzucaj porty nasłuchujące"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Porty nasłuchujące"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Zapisane dozwolone porty"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Dodaj"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Usuń port <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Nieprawidłowy numer portu"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port już istnieje"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal wysłał żądanie otwarcia nowego portu"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Żądany port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Żądany port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Zaakceptuj"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Odrzuć"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Odzyskiwanie"</string>
diff --git a/android/TerminalApp/res/values-pt-rPT/strings.xml b/android/TerminalApp/res/values-pt-rPT/strings.xml
index f98fa0d..337e355 100644
--- a/android/TerminalApp/res/values-pt-rPT/strings.xml
+++ b/android/TerminalApp/res/values-pt-rPT/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Controlo de portas"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Permitir/negar portas de audição"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Portas de audição"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Portas permitidas guardadas"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Adicionar"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Eliminar <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Número de porta inválido"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"A porta já existe"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"O terminal está a pedir para abrir uma nova porta"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Porta pedida: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Porta pedida: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Aceitar"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Recusar"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recuperação"</string>
diff --git a/android/TerminalApp/res/values-pt/strings.xml b/android/TerminalApp/res/values-pt/strings.xml
index 9365db7..b223c9f 100644
--- a/android/TerminalApp/res/values-pt/strings.xml
+++ b/android/TerminalApp/res/values-pt/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Controle de portas"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Permitir/negar portas de detecção"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Portas de detecção"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"As portas permitidas foram salvas"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Adicionar"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Excluir <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Número de porta inválido"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"A porta já existe"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"O terminal está pedindo para abrir uma nova porta"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Porta solicitada: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Porta solicitada: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Aceitar"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Negar"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recuperação"</string>
diff --git a/android/TerminalApp/res/values-ro/strings.xml b/android/TerminalApp/res/values-ro/strings.xml
index 2931361..9cfa4bc 100644
--- a/android/TerminalApp/res/values-ro/strings.xml
+++ b/android/TerminalApp/res/values-ro/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Controlul porturilor"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Permite / refuză porturile active"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Porturi active"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Porturi permise salvate"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Adaugă"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Șterge <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Număr de port nevalid"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Portul există deja"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminalul solicită să deschidă un nou port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Portul solicitat: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Portul solicitat: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Acceptă"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Refuză"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Recuperare"</string>
diff --git a/android/TerminalApp/res/values-ru/strings.xml b/android/TerminalApp/res/values-ru/strings.xml
index e1cc4b4..c3dfec3 100644
--- a/android/TerminalApp/res/values-ru/strings.xml
+++ b/android/TerminalApp/res/values-ru/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Управление портами"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Открыть/закрыть доступ к портам прослушивания"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Порты прослушивания"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Сохраненные порты с открытым доступом"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Добавить"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Удалить <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Неверный номер порта."</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Порт уже существует."</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Терминал просит открыть новый порт"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Запрашиваемый порт: <xliff:g id="PORT_NUMBER">%d</xliff:g>."</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Запрашиваемый порт: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Разрешить"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Не разрешать"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Восста­но­вле­ние"</string>
diff --git a/android/TerminalApp/res/values-si/strings.xml b/android/TerminalApp/res/values-si/strings.xml
index d1bbd82..1b4ffc3 100644
--- a/android/TerminalApp/res/values-si/strings.xml
+++ b/android/TerminalApp/res/values-si/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"පෝටය පාලනය"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"සවන්දීමේ පෝටයන්ට ඉඩ දෙන්න/ප්‍රතික්ෂේප කරන්න"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"සවන්දීමේ පෝටයන්"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> <xliff:g id="PROCESS_NAME">%2$s</xliff:g>"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"සුරකින ලද ඉඩ දුන් පෝටයන්"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"එක් කරන්න"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> මකන්න"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"වලංගු නොවන පෝට අංකය"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"පෝටය දැනටමත් පවතී"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ටර්මිනලය නව පෝටයක් විවෘත කිරීමට ඉල්ලීම් කරයි"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"පෝටය ඉල්ලා ඇත: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"පෝටය ඉල්ලා ඇත: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"පිළිගන්න"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"ප්‍රතික්ෂේප කරන්න"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"ප්‍රතිසාධනය"</string>
diff --git a/android/TerminalApp/res/values-sk/strings.xml b/android/TerminalApp/res/values-sk/strings.xml
index 11d762c..d77433e 100644
--- a/android/TerminalApp/res/values-sk/strings.xml
+++ b/android/TerminalApp/res/values-sk/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Ovládanie portov"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Povoliť alebo zakázať porty počúvania"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Porty počúvania"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Uložené povolené porty"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Pridať"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Odstrániť <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Neplatné číslo portu"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port už existuje"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminál požaduje otvoriť nový port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Požadovaný port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Požadovaný port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Prijať"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Zamietnuť"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Obnovenie"</string>
diff --git a/android/TerminalApp/res/values-sl/strings.xml b/android/TerminalApp/res/values-sl/strings.xml
index ce1389f..0583a0f 100644
--- a/android/TerminalApp/res/values-sl/strings.xml
+++ b/android/TerminalApp/res/values-sl/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Nadzor vrat"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Dovoli/zavrni vrata za poslušanje"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Vrata za poslušanje"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Shranjena dovoljena vrata"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Dodaj"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Izbriši <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Neveljavna številka vrat"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Vrata že obstajajo"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal zahteva odpiranje novih vrat"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Zahtevana vrata: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Zahtevana vrata: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Sprejmi"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Zavrni"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Obnovitev"</string>
diff --git a/android/TerminalApp/res/values-sq/strings.xml b/android/TerminalApp/res/values-sq/strings.xml
index c687f2d..3bac355 100644
--- a/android/TerminalApp/res/values-sq/strings.xml
+++ b/android/TerminalApp/res/values-sq/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Kontrolli i portës"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Lejo/refuzo portat e dëgjimit"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Portat e dëgjimit"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Portat e lejuara të ruajtura"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Shto"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Fshi <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Numër i pavlefshëm i portës"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Porta ekziston tashmë"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminali po përpiqet të hapë një portë të re"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Porta e kërkuar: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Porta e kërkuar: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Prano"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Refuzo"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Rikuperimi"</string>
diff --git a/android/TerminalApp/res/values-sr/strings.xml b/android/TerminalApp/res/values-sr/strings.xml
index 37da000..97a2e4b 100644
--- a/android/TerminalApp/res/values-sr/strings.xml
+++ b/android/TerminalApp/res/values-sr/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Контрола порта"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Дозволите или забраните портове за слушање"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Портови за слушање"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Сачувани дозвољени портови"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Додај"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Избриши <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Неважећи број порта"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Порт већ постоји"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Терминал тражи да отвори нови порт"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Обавезан порт: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Обавезан порт: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Прихвати"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Одбиј"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Опоравак"</string>
diff --git a/android/TerminalApp/res/values-sv/strings.xml b/android/TerminalApp/res/values-sv/strings.xml
index 9edc1b6..3b1b4f0 100644
--- a/android/TerminalApp/res/values-sv/strings.xml
+++ b/android/TerminalApp/res/values-sv/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Portkontroll"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Tillåt/neka lyssningsportar"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Lyssningsportar"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Sparade tillåtna portar"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Lägg till"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Radera <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Ogiltigt portnummer"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Porten finns redan"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminalen begär att öppna en ny port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Port som begärs: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Port som begärs: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Godkänn"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Neka"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Återställning"</string>
diff --git a/android/TerminalApp/res/values-sw/strings.xml b/android/TerminalApp/res/values-sw/strings.xml
index 6d17d8d..c8ffd12 100644
--- a/android/TerminalApp/res/values-sw/strings.xml
+++ b/android/TerminalApp/res/values-sw/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Udhibiti wa mlango"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Ruhusu au kataa milango ya usikilizaji"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Milango ya usikilizaji"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Umehifadhi milango inayoruhusiwa"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Weka"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Futa <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Namba ya mlango si sahihi"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Tayari mlango upo"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Temino inatuma ombi la kufungua mlango mpya"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Ombi la mlango: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Ombi la mlango: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Kubali"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Kataa"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Kurejesha"</string>
diff --git a/android/TerminalApp/res/values-ta/strings.xml b/android/TerminalApp/res/values-ta/strings.xml
index 4b3d3f1..44d0fad 100644
--- a/android/TerminalApp/res/values-ta/strings.xml
+++ b/android/TerminalApp/res/values-ta/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"போர்ட் கட்டுப்பாடு"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"லிஸனிங் போர்ட்டுகளை அனுமதித்தல்/நிராகரித்தல்"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"லிஸனிங் போர்ட்டுகள்"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"சேமித்த அனுமதிக்கப்பட்ட போர்ட்டுகள்"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"சேர்க்கும்"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> ஐ நீக்கும்"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"தவறான போர்ட் எண்"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"போர்ட் ஏற்கெனவே உள்ளது"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"டெர்மினல் புதிய போர்ட்டைத் திறக்குமாறு கேட்கிறது"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"போர்ட் கேட்கப்பட்டுள்ளது: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"போர்ட் கேட்கப்பட்டுள்ளது: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ஏற்கிறேன்"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"நிராகரி"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"மீட்டெடுத்தல்"</string>
diff --git a/android/TerminalApp/res/values-te/strings.xml b/android/TerminalApp/res/values-te/strings.xml
index da156e2..6a3d646 100644
--- a/android/TerminalApp/res/values-te/strings.xml
+++ b/android/TerminalApp/res/values-te/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"పోర్ట్ కంట్రోల్"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"వినే పోర్ట్‌లకు అనుమతినివ్వండి/తిరస్కరించండి"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"వినే పోర్ట్‌లు"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"సేవ్ చేసిన, అనుమతి ఉన్న పోర్ట్‌లు"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"జోడించండి"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g>‌ను తొలగించండి"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"చెల్లుబాటు కాని పోర్ట్ నంబర్"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"పోర్ట్ ఇప్పటికే ఉంది"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"టెర్మినల్ ఒక కొత్త పోర్ట్‌ను తెరవడానికి రిక్వెస్ట్ చేస్తోంది"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"పోర్ట్ రిక్వెస్ట్ చేయబడింది: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"రిక్వెస్ట్ చేయబడిన పోర్ట్: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ఆమోదించండి"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"తిరస్కరించండి"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"రికవరీ"</string>
diff --git a/android/TerminalApp/res/values-th/strings.xml b/android/TerminalApp/res/values-th/strings.xml
index 4f52c3b..66716ec 100644
--- a/android/TerminalApp/res/values-th/strings.xml
+++ b/android/TerminalApp/res/values-th/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"การควบคุมพอร์ต"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"อนุญาต/ปฏิเสธพอร์ตที่กำลังรอการเชื่อมต่อ"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"พอร์ตที่กำลังรอการเชื่อมต่อ"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"บันทึกพอร์ตที่อนุญาตแล้ว"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"เพิ่ม"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"ลบ <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"หมายเลขพอร์ตไม่ถูกต้อง"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"มีพอร์ตอยู่แล้ว"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"เทอร์มินัลกำลังส่งคำขอเปิดพอร์ตใหม่"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"พอร์ตที่ขอ: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"พอร์ตที่ขอ: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"ยอมรับ"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"ปฏิเสธ"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"การกู้คืน"</string>
diff --git a/android/TerminalApp/res/values-tl/strings.xml b/android/TerminalApp/res/values-tl/strings.xml
index f51582c..56b2679 100644
--- a/android/TerminalApp/res/values-tl/strings.xml
+++ b/android/TerminalApp/res/values-tl/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Kontrol ng port"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Payagan/tanggihan ang mga port ng pakikinig"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Mga port sa pakikinig"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"I-save ang mga pinayagang port"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Magdagdag"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"I-delete ang <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Invalid na numero ng port"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Mayroon na ng port na ito"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Nag-request ang terminal na magbukas ng bagong port"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Ni-request na port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Ni-request na port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Tanggapin"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Tanggihan"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Pag-recover"</string>
diff --git a/android/TerminalApp/res/values-tr/strings.xml b/android/TerminalApp/res/values-tr/strings.xml
index c2abca0..4374923 100644
--- a/android/TerminalApp/res/values-tr/strings.xml
+++ b/android/TerminalApp/res/values-tr/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Bağlantı noktası kontrolü"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Dinelenen bağlantı noktalarına izin ver/izin verme"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Dinlenen bağlantı noktaları"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"İzin verilen kayıtlı bağlantı noktaları"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Ekle"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Sil: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Bağlantı noktası numarası geçersiz"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Bağlantı noktası zaten mevcut"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal yeni bir bağlantı noktası açmak istiyor"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"İstenilen bağlantı noktası: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"İstenilen bağlantı noktası: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Kabul et"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Reddet"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Kurtarma"</string>
diff --git a/android/TerminalApp/res/values-uk/strings.xml b/android/TerminalApp/res/values-uk/strings.xml
index 015704c..bd2d574 100644
--- a/android/TerminalApp/res/values-uk/strings.xml
+++ b/android/TerminalApp/res/values-uk/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Керування портами"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Дозволити/заборонити порти прослуховування"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Порти прослуховування"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Збережені дозволені порти"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Додати"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Видалити <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Недійсний номер порту"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Порт уже існує"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Термінал просить відкрити новий порт"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Порт, указаний у запиті: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Порт, указаний у запиті: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Прийняти"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Відхилити"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Відновлення"</string>
diff --git a/android/TerminalApp/res/values-ur/strings.xml b/android/TerminalApp/res/values-ur/strings.xml
index 89e3c86..3ad7c39 100644
--- a/android/TerminalApp/res/values-ur/strings.xml
+++ b/android/TerminalApp/res/values-ur/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"پورٹ کنٹرول"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"لسننگ پورٹس کو اجازت دیں/مسترد کریں"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"لسننگ پورٹس"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"اجازت یافتہ پورٹس کو محفوظ کیا گیا"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"شامل کریں"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> حذف کریں"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"غلط پورٹ نمبر"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"پورٹ پہلے سے موجود ہے"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"ٹرمینل ایک نیا پورٹ کھولنے کی درخواست کر رہا ہے"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"پورٹ کی درخواست کی گئی: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"پورٹ کی درخواست کی گئی: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"قبول کریں"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"مسترد کریں"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"بازیابی"</string>
diff --git a/android/TerminalApp/res/values-uz/strings.xml b/android/TerminalApp/res/values-uz/strings.xml
index 35d274e..159d04c 100644
--- a/android/TerminalApp/res/values-uz/strings.xml
+++ b/android/TerminalApp/res/values-uz/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Portlar boshqaruvi"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Uzatish portlariga ruxsat berish/ularni taqiqlash"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Uzatish postlari"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Ruxsat etilgan portlar saqlandi"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Qoʻshish"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"<xliff:g id="PORT_NUMBER">%d</xliff:g> hisobini oʻchirish"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Port raqami yaroqsiz"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Port allaqachon mavjud"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Terminal yangi port ochishni talab qilmoqda"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Talab qilingan port: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Talab qilingan port: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Qabul qilish"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Rad etish"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Tiklash"</string>
diff --git a/android/TerminalApp/res/values-vi/strings.xml b/android/TerminalApp/res/values-vi/strings.xml
index da15be5..d7d6c93 100644
--- a/android/TerminalApp/res/values-vi/strings.xml
+++ b/android/TerminalApp/res/values-vi/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Kiểm soát cổng"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Cho phép/từ chối cổng nghe"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Cổng nghe"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Đã lưu các cổng được cho phép"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Thêm"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Xoá <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Số cổng không hợp lệ"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Cổng đã tồn tại"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Ứng dụng Terminal đang yêu cầu mở một cổng mới"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Cổng được yêu cầu: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Cổng được yêu cầu: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Chấp nhận"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Từ chối"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Khôi phục"</string>
diff --git a/android/TerminalApp/res/values-zh-rCN/strings.xml b/android/TerminalApp/res/values-zh-rCN/strings.xml
index 3da5f28..31cf746 100644
--- a/android/TerminalApp/res/values-zh-rCN/strings.xml
+++ b/android/TerminalApp/res/values-zh-rCN/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"端口控制"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"允许/拒绝使用监听端口"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"监听端口"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g>(<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"已保存的获准端口"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"添加"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"删除“<xliff:g id="PORT_NUMBER">%d</xliff:g>”"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"端口号无效"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"端口已存在"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"终端正在请求打开新端口"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"请求的端口:<xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"请求的端口:<xliff:g id="PORT_NUMBER">%1$d</xliff:g>(<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"接受"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"拒绝"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"恢复"</string>
diff --git a/android/TerminalApp/res/values-zh-rHK/strings.xml b/android/TerminalApp/res/values-zh-rHK/strings.xml
index 5de6319..1284ecc 100644
--- a/android/TerminalApp/res/values-zh-rHK/strings.xml
+++ b/android/TerminalApp/res/values-zh-rHK/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"連接埠控制項"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"允許/拒絕聆聽連接埠"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"聆聽連接埠"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"已儲存許可的連接埠"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"新增"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"刪除 <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"連接埠號碼無效"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"連接埠已存在"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"終端機正在要求開啟新的連接埠"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"已要求連接埠:<xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"已要求連接埠:<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"接受"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"拒絕"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"復原"</string>
diff --git a/android/TerminalApp/res/values-zh-rTW/strings.xml b/android/TerminalApp/res/values-zh-rTW/strings.xml
index 28a0ce2..7391300 100644
--- a/android/TerminalApp/res/values-zh-rTW/strings.xml
+++ b/android/TerminalApp/res/values-zh-rTW/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"通訊埠控制"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"允許/拒絕監聽通訊埠"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"監聽通訊埠"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"已儲存允許的通訊埠"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"新增"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"刪除 <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"通訊埠號碼無效"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"已有這個通訊埠"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"終端機正在要求開啟新的通訊埠"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"要求的通訊埠:<xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"要求的通訊埠:<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"接受"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"拒絕"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"復原"</string>
diff --git a/android/TerminalApp/res/values-zu/strings.xml b/android/TerminalApp/res/values-zu/strings.xml
index 7f9a958..4036ec1 100644
--- a/android/TerminalApp/res/values-zu/strings.xml
+++ b/android/TerminalApp/res/values-zu/strings.xml
@@ -48,6 +48,7 @@
     <string name="settings_port_forwarding_title" msgid="4971368519093858377">"Ulawulo lwembobo"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6547942778715654953">"Vumela/nqabela izimbobo zokulalela"</string>
     <string name="settings_port_forwarding_active_ports_title" msgid="1841436780635889858">"Izimbobo zokulalela"</string>
+    <string name="settings_port_forwarding_active_ports_content" msgid="1818090784030797758">"<xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_other_enabled_ports_title" msgid="2644381842623436676">"Izimbobo ezivunyelwe ezilondoloziwe"</string>
     <string name="settings_port_forwarding_other_enabled_port_add_button" msgid="4402301203801949152">"Engeza"</string>
     <string name="settings_port_forwarding_other_enabled_port_close_button" msgid="8475029060852721339">"Sula i-<xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -59,7 +60,7 @@
     <string name="settings_port_forwarding_dialog_error_invalid_port_range" msgid="6682935312557379651">"Inombolo engasebenzi yembobo"</string>
     <string name="settings_port_forwarding_dialog_error_existing_port" msgid="768426750758769928">"Imbobo isikhona"</string>
     <string name="settings_port_forwarding_notification_title" msgid="6950621555592547524">"Itheminali icela ukuvula imbobo entsha"</string>
-    <string name="settings_port_forwarding_notification_content" msgid="5072621159244211971">"Imbobo iceliwe: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
+    <string name="settings_port_forwarding_notification_content" msgid="779450349212040908">"Imbobo iceliwe: <xliff:g id="PORT_NUMBER">%1$d</xliff:g> (<xliff:g id="PROCESS_NAME">%2$s</xliff:g>)"</string>
     <string name="settings_port_forwarding_notification_accept" msgid="3571520986524038185">"Yamukela"</string>
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Yenqaba"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Ukuthola"</string>
diff --git a/android/TerminalApp/res/values/strings.xml b/android/TerminalApp/res/values/strings.xml
index d3440d3..bdebb83 100644
--- a/android/TerminalApp/res/values/strings.xml
+++ b/android/TerminalApp/res/values/strings.xml
@@ -172,4 +172,10 @@
 
     <!-- This string is for toast message to notify that VirGL is enabled. [CHAR LIMIT=40] -->
     <string name="virgl_enabled"><xliff:g>VirGL</xliff:g> is enabled</string>
+
+    <!-- This is the name of the notification channel for long-runnint tasks [CHAR LIMIT=none] -->
+    <string name="notification_channel_long_running_name">Long running tasks</string>
+
+    <!-- This is the name of the notification channel for system events [CHAR LIMIT=none] -->
+    <string name="notification_channel_system_events_name">System events</string>
 </resources>
diff --git a/android/virtmgr/Android.bp b/android/virtmgr/Android.bp
index ad63995..c2d67cf 100644
--- a/android/virtmgr/Android.bp
+++ b/android/virtmgr/Android.bp
@@ -38,7 +38,6 @@
         "libcfg_if",
         "libclap",
         "libcrosvm_control_static",
-        "libcstr",
         "libcommand_fds",
         "libdisk",
         "libglob",
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index c71b5c5..57779bf 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -68,7 +68,6 @@
     self, wait_for_interface, Accessor, BinderFeatures, ConnectionInfo, ExceptionCode, Interface, ParcelFileDescriptor,
     SpIBinder, Status, StatusCode, Strong, IntoBinderResult,
 };
-use cstr::cstr;
 use glob::glob;
 use libc::{AF_VSOCK, sa_family_t, sockaddr_vm};
 use log::{debug, error, info, warn};
@@ -820,6 +819,8 @@
             .unwrap_or(Ok(UsbConfig { controller: false }))
             .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?;
 
+        let detect_hangup = is_app_config && gdb_port.is_none();
+
         // Actually start the VM.
         let crosvm_config = CrosvmConfig {
             cid,
@@ -847,7 +848,7 @@
             ramdump,
             indirect_files,
             platform_version: parse_platform_version_req(&config.platformVersion)?,
-            detect_hangup: is_app_config,
+            detect_hangup,
             gdb_port,
             vfio_devices,
             dtbo,
@@ -976,7 +977,7 @@
             "Passing vendor hashtree digest to pvmfw. This will be rejected if it doesn't \
                 match the trusted digest in the pvmfw config, causing the VM to fail to start."
         );
-        vec![(cstr!("vendor_hashtree_descriptor_root_digest"), vendor_hashtree_digest.as_slice())]
+        vec![(c"vendor_hashtree_descriptor_root_digest", vendor_hashtree_digest.as_slice())]
     } else {
         vec![]
     };
@@ -984,18 +985,18 @@
     let key_material;
     let mut untrusted_props = Vec::with_capacity(2);
     if cfg!(llpvm_changes) {
-        untrusted_props.push((cstr!("instance-id"), &instance_id[..]));
+        untrusted_props.push((c"instance-id", &instance_id[..]));
         let want_updatable = extract_want_updatable(config);
         if want_updatable && is_secretkeeper_supported() {
             // Let guest know that it can defer rollback protection to Secretkeeper by setting
             // an empty property in untrusted node in DT. This enables Updatable VMs.
-            untrusted_props.push((cstr!("defer-rollback-protection"), &[]));
+            untrusted_props.push((c"defer-rollback-protection", &[]));
             let sk: Strong<dyn ISecretkeeper> =
                 binder::wait_for_interface(SECRETKEEPER_IDENTIFIER)?;
             if sk.getInterfaceVersion()? >= 2 {
                 let PublicKey { keyMaterial } = sk.getSecretkeeperIdentity()?;
                 key_material = keyMaterial;
-                trusted_props.push((cstr!("secretkeeper_public_key"), key_material.as_slice()));
+                trusted_props.push((c"secretkeeper_public_key", key_material.as_slice()));
             }
         }
     }
diff --git a/android/virtmgr/src/dt_overlay.rs b/android/virtmgr/src/dt_overlay.rs
index 108ed61..fe2a419 100644
--- a/android/virtmgr/src/dt_overlay.rs
+++ b/android/virtmgr/src/dt_overlay.rs
@@ -15,14 +15,13 @@
 //! This module support creating AFV related overlays, that can then be appended to DT by VM.
 
 use anyhow::{anyhow, Result};
-use cstr::cstr;
 use fsfdt::FsFdt;
 use libfdt::Fdt;
 use std::ffi::CStr;
 use std::path::Path;
 
-pub(crate) const AVF_NODE_NAME: &CStr = cstr!("avf");
-pub(crate) const UNTRUSTED_NODE_NAME: &CStr = cstr!("untrusted");
+pub(crate) const AVF_NODE_NAME: &CStr = c"avf";
+pub(crate) const UNTRUSTED_NODE_NAME: &CStr = c"untrusted";
 pub(crate) const VM_DT_OVERLAY_PATH: &str = "vm_dt_overlay.dtbo";
 pub(crate) const VM_DT_OVERLAY_MAX_SIZE: usize = 2000;
 
@@ -63,13 +62,13 @@
         Fdt::create_empty_tree(buffer).map_err(|e| anyhow!("Failed to create empty Fdt: {e:?}"))?;
     let mut fragment = fdt
         .root_mut()
-        .add_subnode(cstr!("fragment@0"))
+        .add_subnode(c"fragment@0")
         .map_err(|e| anyhow!("Failed to add fragment node: {e:?}"))?;
     fragment
-        .setprop(cstr!("target-path"), b"/\0")
+        .setprop(c"target-path", b"/\0")
         .map_err(|e| anyhow!("Failed to set target-path property: {e:?}"))?;
     let overlay = fragment
-        .add_subnode(cstr!("__overlay__"))
+        .add_subnode(c"__overlay__")
         .map_err(|e| anyhow!("Failed to add __overlay__ node: {e:?}"))?;
     let avf =
         overlay.add_subnode(AVF_NODE_NAME).map_err(|e| anyhow!("Failed to add avf node: {e:?}"))?;
@@ -87,12 +86,12 @@
 
     // Read dt_path from host DT and overlay onto fdt.
     if let Some(path) = dt_path {
-        fdt.overlay_onto(cstr!("/fragment@0/__overlay__"), path)?;
+        fdt.overlay_onto(c"/fragment@0/__overlay__", path)?;
     }
 
     if !trusted_props.is_empty() {
         let mut avf = fdt
-            .node_mut(cstr!("/fragment@0/__overlay__/avf"))
+            .node_mut(c"/fragment@0/__overlay__/avf")
             .map_err(|e| anyhow!("Failed to search avf node: {e:?}"))?
             .ok_or(anyhow!("Failed to get avf node"))?;
         for (name, value) in trusted_props {
@@ -120,14 +119,14 @@
     #[test]
     fn untrusted_prop_test() {
         let mut buffer = vec![0_u8; VM_DT_OVERLAY_MAX_SIZE];
-        let prop_name = cstr!("XOXO");
+        let prop_name = c"XOXO";
         let prop_val_input = b"OXOX";
         let fdt =
             create_device_tree_overlay(&mut buffer, None, &[(prop_name, prop_val_input)], &[])
                 .unwrap();
 
         let prop_value_dt = fdt
-            .node(cstr!("/fragment@0/__overlay__/avf/untrusted"))
+            .node(c"/fragment@0/__overlay__/avf/untrusted")
             .unwrap()
             .expect("/avf/untrusted node doesn't exist")
             .getprop(prop_name)
@@ -139,14 +138,14 @@
     #[test]
     fn trusted_prop_test() {
         let mut buffer = vec![0_u8; VM_DT_OVERLAY_MAX_SIZE];
-        let prop_name = cstr!("XOXOXO");
+        let prop_name = c"XOXOXO";
         let prop_val_input = b"OXOXOX";
         let fdt =
             create_device_tree_overlay(&mut buffer, None, &[], &[(prop_name, prop_val_input)])
                 .unwrap();
 
         let prop_value_dt = fdt
-            .node(cstr!("/fragment@0/__overlay__/avf"))
+            .node(c"/fragment@0/__overlay__/avf")
             .unwrap()
             .expect("/avf node doesn't exist")
             .getprop(prop_name)
diff --git a/build/avf_flags.aconfig b/build/avf_flags.aconfig
index 9815c60..921c374 100644
--- a/build/avf_flags.aconfig
+++ b/build/avf_flags.aconfig
@@ -9,3 +9,11 @@
   bug: "383347947"
   is_fixed_read_only: true
 }
+
+flag {
+  name: "terminal_gui_support"
+  is_exported: true
+  namespace: "virtualization"
+  description: "Flag for GUI support in terminal"
+  bug: "386296118"
+}
\ No newline at end of file
diff --git a/build/debian/build.sh b/build/debian/build.sh
index 3f33ec8..a426d22 100755
--- a/build/debian/build.sh
+++ b/build/debian/build.sh
@@ -156,6 +156,7 @@
 	source "$HOME"/.cargo/env
 	rustup target add "${arch}"-unknown-linux-gnu
 	cargo install cargo-license
+	cargo install cargo-deb
 }
 
 download_debian_cloud_image() {
@@ -168,23 +169,11 @@
 	wget -O - "${url}" | tar xz -C "${outdir}" --strip-components=1
 }
 
-build_rust_binary_and_copy() {
+build_rust_as_deb() {
 	pushd "$(dirname "$0")/../../guest/$1" > /dev/null
-	local release_flag=
-	local artifact_mode=debug
-	if [[ "$mode" == "release" ]]; then
-		release_flag="--release"
-		artifact_mode=release
-	fi
-	RUSTFLAGS="-C linker=${arch}-linux-gnu-gcc" cargo build \
+	cargo deb \
 		--target "${arch}-unknown-linux-gnu" \
-		--target-dir "${workdir}/$1" ${release_flag}
-	mkdir -p "${dst}/files/usr/local/bin/$1"
-	cp "${workdir}/$1/${arch}-unknown-linux-gnu/${artifact_mode}/$1" "${dst}/files/usr/local/bin/$1/AVF"
-	chmod 777 "${dst}/files/usr/local/bin/$1/AVF"
-
-	mkdir -p "${dst}/files/usr/share/doc/$1"
-	cargo license > "${dst}/files/usr/share/doc/$1/copyright"
+		--output "${debian_cloud_image}/localdebs"
 	popd > /dev/null
 }
 
@@ -218,9 +207,9 @@
 
 	cp -R "$(dirname "$0")/localdebs/" "${debian_cloud_image}/"
 	build_ttyd
-	build_rust_binary_and_copy forwarder_guest
-	build_rust_binary_and_copy forwarder_guest_launcher
-	build_rust_binary_and_copy shutdown_runner
+	build_rust_as_deb forwarder_guest
+	build_rust_as_deb forwarder_guest_launcher
+	build_rust_as_deb shutdown_runner
 }
 
 package_custom_kernel() {
diff --git a/build/debian/fai_config/files/etc/avahi/services/ttyd.service/AVF b/build/debian/fai_config/files/etc/avahi/services/ttyd.service/AVF
deleted file mode 100644
index 64f9d0a..0000000
--- a/build/debian/fai_config/files/etc/avahi/services/ttyd.service/AVF
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
-<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
-
-<service-group>
-
-  <name>ttyd</name>
-
-  <service protocol="ipv4">
-    <type>_http._tcp</type>
-    <port>7681</port>
-  </service>
-
-</service-group>
diff --git a/build/debian/fai_config/files/etc/systemd/system/shutdown_runner.service/AVF b/build/debian/fai_config/files/etc/systemd/system/shutdown_runner.service/AVF
deleted file mode 100644
index bfb8afb..0000000
--- a/build/debian/fai_config/files/etc/systemd/system/shutdown_runner.service/AVF
+++ /dev/null
@@ -1,11 +0,0 @@
-[Unit]
-After=syslog.target
-After=network.target
-After=virtiofs_internal.service
-[Service]
-ExecStart=/usr/bin/bash -c '/usr/local/bin/shutdown_runner --grpc_port $(cat /mnt/internal/debian_service_port)'
-Type=simple
-User=root
-Group=root
-[Install]
-WantedBy=multi-user.target
diff --git a/build/debian/fai_config/files/etc/systemd/system/ttyd.service/AVF b/build/debian/fai_config/files/etc/systemd/system/ttyd.service/AVF
index 4a32f2b..d86bab0 100644
--- a/build/debian/fai_config/files/etc/systemd/system/ttyd.service/AVF
+++ b/build/debian/fai_config/files/etc/systemd/system/ttyd.service/AVF
@@ -3,11 +3,14 @@
 After=syslog.target
 After=network.target
 After=virtiofs_internal.service
+
 [Service]
 ExecStart=/usr/local/bin/ttyd --ssl --ssl-cert /etc/ttyd/server.crt --ssl-key /etc/ttyd/server.key --ssl-ca /mnt/internal/ca.crt -t disableLeaveAlert=true -W login -f droid
+ExecStartPost=/usr/bin/avahi-publish-service ttyd _http._tcp 7681
 Type=simple
 Restart=always
 User=root
 Group=root
+
 [Install]
 WantedBy=multi-user.target
diff --git a/build/debian/fai_config/package_config/AVF b/build/debian/fai_config/package_config/AVF
index c779021..98b558b 100644
--- a/build/debian/fai_config/package_config/AVF
+++ b/build/debian/fai_config/package_config/AVF
@@ -5,3 +5,6 @@
 bpfcc-tools
 libnss-mdns
 procps
+forwarder-guest
+forwarder-guest-launcher
+shutdown-runner
diff --git a/build/debian/fai_config/scripts/AVF/10-systemd b/build/debian/fai_config/scripts/AVF/10-systemd
index 998cbfd..121acc5 100755
--- a/build/debian/fai_config/scripts/AVF/10-systemd
+++ b/build/debian/fai_config/scripts/AVF/10-systemd
@@ -1,14 +1,9 @@
 #!/bin/bash
 
-chmod +x $target/usr/local/bin/forwarder_guest
-chmod +x $target/usr/local/bin/forwarder_guest_launcher
-chmod +x $target/usr/local/bin/shutdown_runner
 chmod +x $target/usr/local/bin/ttyd
 ln -s /etc/systemd/system/ttyd.service $target/etc/systemd/system/multi-user.target.wants/ttyd.service
 ln -s /etc/systemd/system/virtiofs.service $target/etc/systemd/system/multi-user.target.wants/virtiofs.service
-ln -s /etc/systemd/system/forwarder_guest_launcher.service $target/etc/systemd/system/multi-user.target.wants/forwarder_guest_launcher.service
 ln -s /etc/systemd/system/virtiofs_internal.service $target/etc/systemd/system/multi-user.target.wants/virtiofs_internal.service
 ln -s /etc/systemd/system/backup_mount.service $target/etc/systemd/system/multi-user.target.wants/backup_mount.service
-ln -s /etc/systemd/system/shutdown_runner.service $target/etc/systemd/system/multi-user.target.wants/shutdown_runner.service
 
 sed -i 's/#LLMNR=yes/LLMNR=no/' $target/etc/systemd/resolved.conf
diff --git a/guest/derive_microdroid_vendor_dice_node/Android.bp b/guest/derive_microdroid_vendor_dice_node/Android.bp
index 8b79aad..7a3ccbe 100644
--- a/guest/derive_microdroid_vendor_dice_node/Android.bp
+++ b/guest/derive_microdroid_vendor_dice_node/Android.bp
@@ -10,7 +10,6 @@
     rustlibs: [
         "libanyhow",
         "libclap",
-        "libcstr",
         "libdice_driver",
         "libdiced_open_dice",
         "libdm_rust",
diff --git a/guest/derive_microdroid_vendor_dice_node/src/main.rs b/guest/derive_microdroid_vendor_dice_node/src/main.rs
index 0f0631e..4ec91ad 100644
--- a/guest/derive_microdroid_vendor_dice_node/src/main.rs
+++ b/guest/derive_microdroid_vendor_dice_node/src/main.rs
@@ -16,7 +16,6 @@
 
 use anyhow::{bail, Context, Result};
 use clap::Parser;
-use cstr::cstr;
 use dice_driver::DiceDriver;
 use diced_open_dice::{
     hash, retry_bcc_format_config_descriptor, DiceConfigValues, OwnedDiceArtifacts, HIDDEN_SIZE,
@@ -50,7 +49,7 @@
 // See dice_for_avf_guest.cddl for CDDL of Configuration Descriptor of VM components.
 fn build_descriptor(vbmeta: &VbMetaImage) -> Result<Vec<u8>> {
     let values = DiceConfigValues {
-        component_name: Some(cstr!("Microdroid vendor")),
+        component_name: Some(c"Microdroid vendor"),
         security_version: Some(vbmeta.rollback_index()),
         ..Default::default()
     };
diff --git a/guest/forwarder_guest/.cargo/config.toml b/guest/forwarder_guest/.cargo/config.toml
new file mode 100644
index 0000000..a451cda
--- /dev/null
+++ b/guest/forwarder_guest/.cargo/config.toml
@@ -0,0 +1,6 @@
+[target.aarch64-unknown-linux-gnu]
+linker = "aarch64-linux-gnu-gcc"
+rustflags = ["-C", "target-feature=+crt-static"]
+
+[target.x86_64-unknown-linux-gnu]
+rustflags = ["-C", "target-feature=+crt-static"]
diff --git a/guest/forwarder_guest/Cargo.toml b/guest/forwarder_guest/Cargo.toml
index ce50e4c..bb9b826 100644
--- a/guest/forwarder_guest/Cargo.toml
+++ b/guest/forwarder_guest/Cargo.toml
@@ -10,3 +10,8 @@
 poll_token_derive = "0.1.0"
 remain = "0.2.14"
 vmm-sys-util = "0.12.1"
+
+[package.metadata.deb]
+maintainer = "ferrochrome-dev@google.com"
+copyright = "2024, The Android Open Source Project"
+depends = "$auto"
diff --git a/guest/forwarder_guest_launcher/.cargo/config.toml b/guest/forwarder_guest_launcher/.cargo/config.toml
new file mode 100644
index 0000000..a451cda
--- /dev/null
+++ b/guest/forwarder_guest_launcher/.cargo/config.toml
@@ -0,0 +1,6 @@
+[target.aarch64-unknown-linux-gnu]
+linker = "aarch64-linux-gnu-gcc"
+rustflags = ["-C", "target-feature=+crt-static"]
+
+[target.x86_64-unknown-linux-gnu]
+rustflags = ["-C", "target-feature=+crt-static"]
diff --git a/guest/forwarder_guest_launcher/Cargo.toml b/guest/forwarder_guest_launcher/Cargo.toml
index aef27f9..9c4d7e3 100644
--- a/guest/forwarder_guest_launcher/Cargo.toml
+++ b/guest/forwarder_guest_launcher/Cargo.toml
@@ -21,3 +21,10 @@
 
 [build-dependencies]
 tonic-build = "0.12.3"
+
+[package.metadata.deb]
+maintainer = "ferrochrome-dev@google.com"
+copyright = "2024, The Android Open Source Project"
+depends = "$auto"
+maintainer-scripts = "debian/"
+systemd-units = { }
diff --git a/build/debian/fai_config/files/etc/systemd/system/forwarder_guest_launcher.service/AVF b/guest/forwarder_guest_launcher/debian/service
similarity index 65%
rename from build/debian/fai_config/files/etc/systemd/system/forwarder_guest_launcher.service/AVF
rename to guest/forwarder_guest_launcher/debian/service
index 129fdad..6824c70 100644
--- a/build/debian/fai_config/files/etc/systemd/system/forwarder_guest_launcher.service/AVF
+++ b/guest/forwarder_guest_launcher/debian/service
@@ -3,12 +3,14 @@
 After=syslog.target
 After=network.target
 After=virtiofs_internal.service
+
 [Service]
-ExecStart=/usr/bin/bash -c '/usr/local/bin/forwarder_guest_launcher --grpc_port $(cat /mnt/internal/debian_service_port)'
+ExecStart=/usr/bin/bash -c '/usr/bin/forwarder_guest_launcher --grpc_port $(cat /mnt/internal/debian_service_port)'
 Type=simple
 Restart=on-failure
 RestartSec=1
 User=root
 Group=root
+
 [Install]
 WantedBy=multi-user.target
diff --git a/guest/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl b/guest/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
index b7a539b..8d02d97 100644
--- a/guest/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
+++ b/guest/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
@@ -78,6 +78,20 @@
     byte[] getVmInstanceSecret(in byte[] identifier, int size);
 
     /**
+     * Write `data`, on behalf of the client, to Secretkeeper.
+     * This is confidential to the pVM and protected via appropriate DICE policy
+     * on the payload's DICE chain.
+     */
+    void writePayloadRpData(in byte[32] data);
+
+    /**
+     * Read payload's `data` written on behalf of the payload in Secretkeeper.
+     * The returned value can be null either due to no value written or because
+     * Android maliciously deleted the value - Secretkeeper deletion are not authenticated.
+     */
+    @nullable byte[32] readPayloadRpData();
+
+    /**
      * Gets the DICE attestation chain for the VM.
      *
      * The DICE chain must not be made available to all VMs as it contains privacy breaking
@@ -116,4 +130,13 @@
      *         certification chain.
      */
     AttestationResult requestAttestation(in byte[] challenge, in boolean testMode);
+
+    /**
+     * Checks whether the VM instance is new - i.e., if this is the first run of an instance.
+     * This is an indication of fresh new VM secrets. Payload can use this to setup the fresh
+     * instance if needed.
+     *
+     * @return true on the first boot of the instance & false on subsequent boot.
+     */
+    boolean isNewInstance();
 }
diff --git a/guest/microdroid_manager/src/dice.rs b/guest/microdroid_manager/src/dice.rs
index edc4d63..bf89358 100644
--- a/guest/microdroid_manager/src/dice.rs
+++ b/guest/microdroid_manager/src/dice.rs
@@ -153,7 +153,8 @@
             subcomponents.into_iter().map(Subcomponent::into_value).collect::<Result<Vec<_>>>()?;
         map.push((cbor!(-71002)?, cbor!(values)?));
     }
-
+    // Add a placeholder security version as it is required by the open-dice profile "Android.16"
+    map.push((cbor!(-70005)?, cbor!(0)?));
     Ok(Value::Map(map).to_vec()?)
 }
 
@@ -180,10 +181,10 @@
         let config_descriptor =
             format_payload_config_descriptor(&payload_metadata, NO_SUBCOMPONENTS)?;
         static EXPECTED_CONFIG_DESCRIPTOR: &[u8] = &[
-            0xa2, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x72, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x64, 0x72,
+            0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x72, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x64, 0x72,
             0x6f, 0x69, 0x64, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x3a, 0x00, 0x01,
             0x15, 0x57, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74,
-            0x68,
+            0x68, 0x3a, 0x00, 0x01, 0x11, 0x74, 0x00,
         ];
         assert_eq_bytes(EXPECTED_CONFIG_DESCRIPTOR, &config_descriptor);
         Ok(())
@@ -199,10 +200,10 @@
         let config_descriptor =
             format_payload_config_descriptor(&payload_metadata, NO_SUBCOMPONENTS)?;
         static EXPECTED_CONFIG_DESCRIPTOR: &[u8] = &[
-            0xa2, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x72, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x64, 0x72,
+            0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x72, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x64, 0x72,
             0x6f, 0x69, 0x64, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x3a, 0x00, 0x01,
             0x15, 0x58, 0xa1, 0x01, 0x6e, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62,
-            0x69, 0x6e, 0x61, 0x72, 0x79,
+            0x69, 0x6e, 0x61, 0x72, 0x79, 0x3a, 0x00, 0x01, 0x11, 0x74, 0x00,
         ];
         assert_eq_bytes(EXPECTED_CONFIG_DESCRIPTOR, &config_descriptor);
         Ok(())
@@ -228,13 +229,13 @@
         let config_descriptor = format_payload_config_descriptor(&payload_metadata, subcomponents)?;
         // Verified using cbor.me.
         static EXPECTED_CONFIG_DESCRIPTOR: &[u8] = &[
-            0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x72, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x64, 0x72,
+            0xa4, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x72, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x64, 0x72,
             0x6f, 0x69, 0x64, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x3a, 0x00, 0x01,
             0x15, 0x57, 0x6c, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x61, 0x74,
             0x68, 0x3a, 0x00, 0x01, 0x15, 0x59, 0x82, 0xa4, 0x01, 0x64, 0x61, 0x70, 0x6b, 0x31,
             0x02, 0x01, 0x03, 0x42, 0x2a, 0x2b, 0x04, 0x41, 0x11, 0xa4, 0x01, 0x64, 0x61, 0x70,
             0x6b, 0x32, 0x02, 0x1b, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x41,
-            0x2b, 0x04, 0x42, 0x13, 0x14,
+            0x2b, 0x04, 0x42, 0x13, 0x14, 0x3a, 0x00, 0x01, 0x11, 0x74, 0x00,
         ];
         assert_eq_bytes(EXPECTED_CONFIG_DESCRIPTOR, &config_descriptor);
         Ok(())
diff --git a/guest/microdroid_manager/src/main.rs b/guest/microdroid_manager/src/main.rs
index 451c3c8..57ad35d 100644
--- a/guest/microdroid_manager/src/main.rs
+++ b/guest/microdroid_manager/src/main.rs
@@ -250,7 +250,7 @@
 
     if is_strict_boot() {
         // Provisioning must happen on the first boot and never again.
-        if is_new_instance() {
+        if is_new_instance_legacy() {
             ensure!(
                 saved_data.is_none(),
                 MicrodroidError::PayloadInvalidConfig(
@@ -297,6 +297,17 @@
     Ok(instance_data)
 }
 
+// The VM instance run can be
+// 1. Either Newly created - which can happen if this is really a new VM instance (or a malicious
+//    Android has deleted relevant secrets)
+// 2. Or Re-run from an already seen VM instance.
+#[derive(PartialEq, Eq)]
+enum VmInstanceState {
+    Unknown,
+    NewlyCreated,
+    PreviouslySeen,
+}
+
 fn try_run_payload(
     service: &Strong<dyn IVirtualMachineService>,
     vm_payload_service_fd: OwnedFd,
@@ -326,8 +337,25 @@
     // 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 vm_secret =
-        VmSecret::new(dice_artifacts, service).context("Failed to create VM secrets")?;
+    let mut state = VmInstanceState::Unknown;
+    let vm_secret = VmSecret::new(dice_artifacts, service, &mut state)
+        .context("Failed to create VM secrets")?;
+
+    let is_new_instance = match state {
+        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()
+        }
+    };
 
     if cfg!(dice_changes) {
         // Now that the DICE derivation is done, it's ok to allow payload code to run.
@@ -387,6 +415,7 @@
         service.clone(),
         vm_secret,
         vm_payload_service_fd,
+        is_new_instance,
     )?;
 
     // Set export_tombstones if enabled
@@ -488,7 +517,7 @@
     Path::new(AVF_STRICT_BOOT).exists()
 }
 
-fn is_new_instance() -> bool {
+fn is_new_instance_legacy() -> bool {
     Path::new(AVF_NEW_INSTANCE).exists()
 }
 
diff --git a/guest/microdroid_manager/src/vm_payload_service.rs b/guest/microdroid_manager/src/vm_payload_service.rs
index 7f4317b..fb57812 100644
--- a/guest/microdroid_manager/src/vm_payload_service.rs
+++ b/guest/microdroid_manager/src/vm_payload_service.rs
@@ -33,6 +33,7 @@
     allow_restricted_apis: bool,
     virtual_machine_service: Strong<dyn IVirtualMachineService>,
     secret: VmSecret,
+    is_new_instance: bool,
 }
 
 impl IVmPayloadService for VmPayloadService {
@@ -97,6 +98,29 @@
             certificateChain: cert_chain,
         })
     }
+
+    fn readPayloadRpData(&self) -> binder::Result<Option<[u8; 32]>> {
+        let data = self
+            .secret
+            .read_payload_data_rp()
+            .context("Failed to read payload's rollback protected data")
+            .with_log()
+            .or_service_specific_exception(-1)?;
+        Ok(data)
+    }
+
+    fn writePayloadRpData(&self, data: &[u8; 32]) -> binder::Result<()> {
+        self.secret
+            .write_payload_data_rp(data)
+            .context("Failed to write payload's rollback protected data")
+            .with_log()
+            .or_service_specific_exception(-1)?;
+        Ok(())
+    }
+
+    fn isNewInstance(&self) -> binder::Result<bool> {
+        Ok(self.is_new_instance)
+    }
 }
 
 impl Interface for VmPayloadService {}
@@ -107,8 +131,9 @@
         allow_restricted_apis: bool,
         vm_service: Strong<dyn IVirtualMachineService>,
         secret: VmSecret,
+        is_new_instance: bool,
     ) -> VmPayloadService {
-        Self { allow_restricted_apis, virtual_machine_service: vm_service, secret }
+        Self { allow_restricted_apis, virtual_machine_service: vm_service, secret, is_new_instance }
     }
 
     fn check_restricted_apis_allowed(&self) -> binder::Result<()> {
@@ -128,9 +153,10 @@
     vm_service: Strong<dyn IVirtualMachineService>,
     secret: VmSecret,
     vm_payload_service_fd: OwnedFd,
+    is_new_instance: bool,
 ) -> Result<()> {
     let vm_payload_binder = BnVmPayloadService::new_binder(
-        VmPayloadService::new(allow_restricted_apis, vm_service, secret),
+        VmPayloadService::new(allow_restricted_apis, vm_service, secret, is_new_instance),
         BinderFeatures::default(),
     );
 
diff --git a/guest/microdroid_manager/src/vm_secret.rs b/guest/microdroid_manager/src/vm_secret.rs
index 5cc90ff..56b3482 100644
--- a/guest/microdroid_manager/src/vm_secret.rs
+++ b/guest/microdroid_manager/src/vm_secret.rs
@@ -38,6 +38,7 @@
 use zeroize::Zeroizing;
 use std::sync::Mutex;
 use std::sync::Arc;
+use crate::VmInstanceState;
 
 const ENCRYPTEDSTORE_KEY_IDENTIFIER: &str = "encryptedstore_key";
 const AUTHORITY_HASH: i64 = -4670549;
@@ -71,13 +72,20 @@
     // with downgraded images will not have access to VM's secret.
     // V2 secrets require hardware support - Secretkeeper HAL, which (among other things)
     // is backed by tamper-evident storage, providing rollback protection to these secrets.
-    V2 { dice_artifacts: OwnedDiceArtifactsWithExplicitKey, skp_secret: ZVec },
+    V2 {
+        instance_id: [u8; ID_SIZE],
+        dice_artifacts: OwnedDiceArtifactsWithExplicitKey,
+        skp_secret: ZVec,
+        secretkeeper_session: SkVmSession,
+    },
     // V1 secrets are not protected against rollback of boot images.
     // They are reliable only if rollback of images was prevented by verified boot ie,
     // each stage (including pvmfw/Microdroid/Microdroid Manager) prevents downgrade of next
     // stage. These are now legacy secrets & used only when Secretkeeper HAL is not supported
     // by device.
-    V1 { dice_artifacts: OwnedDiceArtifacts },
+    V1 {
+        dice_artifacts: OwnedDiceArtifacts,
+    },
 }
 
 // For supporting V2 secrets, guest expects the public key to be present in the Linux device tree.
@@ -92,6 +100,7 @@
     pub fn new(
         dice_artifacts: OwnedDiceArtifacts,
         vm_service: &Strong<dyn IVirtualMachineService>,
+        state: &mut VmInstanceState,
     ) -> Result<Self> {
         ensure!(dice_artifacts.bcc().is_some(), "Dice chain missing");
         if !crate::should_defer_rollback_protection() {
@@ -100,24 +109,28 @@
 
         let explicit_dice = OwnedDiceArtifactsWithExplicitKey::from_owned_artifacts(dice_artifacts)
             .context("Failed to get Dice artifacts in explicit key format")?;
-        let session = SkVmSession::new(vm_service, &explicit_dice)?;
         let id = super::get_instance_id()?.ok_or(anyhow!("Missing instance_id"))?;
         let explicit_dice_chain = explicit_dice
             .explicit_key_dice_chain()
             .ok_or(anyhow!("Missing explicit dice chain, this is unusual"))?;
         let policy = sealing_policy(explicit_dice_chain)
             .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, Some(policy.clone()))? {
-            *skp_secret = secret
+        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(), policy)?;
+            session.store_secret(id, skp_secret.clone())?;
+            *state = VmInstanceState::NewlyCreated;
         }
         Ok(Self::V2 {
+            instance_id: id,
             dice_artifacts: explicit_dice,
             skp_secret: ZVec::try_from(skp_secret.to_vec())?,
+            secretkeeper_session: session,
         })
     }
 
@@ -130,7 +143,7 @@
 
     fn get_vm_secret(&self, salt: &[u8], identifier: &[u8], key: &mut [u8]) -> Result<()> {
         match self {
-            Self::V2 { dice_artifacts, skp_secret } => {
+            Self::V2 { dice_artifacts, skp_secret, .. } => {
                 let mut hasher = sha::Sha256::new();
                 hasher.update(dice_artifacts.cdi_seal());
                 hasher.update(skp_secret);
@@ -152,6 +165,23 @@
     pub fn derive_encryptedstore_key(&self, key: &mut [u8]) -> Result<()> {
         self.get_vm_secret(SALT_ENCRYPTED_STORE, ENCRYPTEDSTORE_KEY_IDENTIFIER.as_bytes(), key)
     }
+
+    pub fn read_payload_data_rp(&self) -> Result<Option<[u8; SECRET_SIZE]>> {
+        let Self::V2 { instance_id, secretkeeper_session, .. } = self else {
+            return Err(anyhow!("Rollback protected data is not available with V1 secrets"));
+        };
+        let payload_id = sha::sha512(instance_id);
+        secretkeeper_session.get_secret(payload_id)
+    }
+
+    pub fn write_payload_data_rp(&self, data: &[u8; SECRET_SIZE]) -> Result<()> {
+        let data = Zeroizing::new(*data);
+        let Self::V2 { instance_id, secretkeeper_session, .. } = self else {
+            return Err(anyhow!("Rollback protected data is not available with V1 secrets"));
+        };
+        let payload_id = sha::sha512(instance_id);
+        secretkeeper_session.store_secret(payload_id, data)
+    }
 }
 
 // Construct a sealing policy on the dice chain. VMs uses the following set of constraint for
@@ -227,31 +257,35 @@
 }
 
 // The secure session between VM & Secretkeeper
-struct SkVmSession(Arc<Mutex<SkSession>>);
+pub(crate) struct SkVmSession {
+    session: Arc<Mutex<SkSession>>,
+    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>,
         dice: &OwnedDiceArtifactsWithExplicitKey,
+        sealing_policy: Vec<u8>,
     ) -> Result<Self> {
         let secretkeeper_proxy = get_secretkeeper_service(vm_service)?;
-        let secure_session =
-            SkSession::new(secretkeeper_proxy, dice, Some(get_secretkeeper_identity()?))?;
-        let secure_session = Arc::new(Mutex::new(secure_session));
-        Ok(Self(secure_session))
+        let session = SkSession::new(secretkeeper_proxy, dice, Some(get_secretkeeper_identity()?))?;
+        let session = Arc::new(Mutex::new(session));
+        Ok(Self { session, sealing_policy })
     }
 
-    fn store_secret(
-        &self,
-        id: [u8; ID_SIZE],
-        secret: Zeroizing<[u8; SECRET_SIZE]>,
-        sealing_policy: Vec<u8>,
-    ) -> Result<()> {
-        let store_request =
-            StoreSecretRequest { id: Id(id), secret: Secret(*secret), sealing_policy };
+    fn store_secret(&self, id: [u8; ID_SIZE], secret: Zeroizing<[u8; SECRET_SIZE]>) -> Result<()> {
+        let store_request = StoreSecretRequest {
+            id: Id(id),
+            secret: Secret(*secret),
+            sealing_policy: self.sealing_policy.clone(),
+        };
         log::info!("Secretkeeper operation: {:?}", store_request);
 
         let store_request = store_request.serialize_to_packet().to_vec().map_err(anyhow_err)?;
-        let session = &mut *self.0.lock().unwrap();
+        let session = &mut *self.session.lock().unwrap();
         let store_response = session.secret_management_request(&store_request)?;
         let store_response = ResponsePacket::from_slice(&store_response).map_err(anyhow_err)?;
         let response_type = store_response.response_type().map_err(anyhow_err)?;
@@ -263,15 +297,14 @@
         Ok(())
     }
 
-    fn get_secret(
-        &self,
-        id: [u8; ID_SIZE],
-        updated_sealing_policy: Option<Vec<u8>>,
-    ) -> Result<Option<[u8; SECRET_SIZE]>> {
-        let get_request = GetSecretRequest { id: Id(id), updated_sealing_policy };
+    fn get_secret(&self, id: [u8; ID_SIZE]) -> Result<Option<[u8; SECRET_SIZE]>> {
+        let get_request = GetSecretRequest {
+            id: Id(id),
+            updated_sealing_policy: Some(self.sealing_policy.clone()),
+        };
         log::info!("Secretkeeper operation: {:?}", get_request);
         let get_request = get_request.serialize_to_packet().to_vec().map_err(anyhow_err)?;
-        let session = &mut *self.0.lock().unwrap();
+        let session = &mut *self.session.lock().unwrap();
         let get_response = session.secret_management_request(&get_request)?;
         let get_response = ResponsePacket::from_slice(&get_response).map_err(anyhow_err)?;
         let response_type = get_response.response_type().map_err(anyhow_err)?;
diff --git a/guest/pvmfw/Android.bp b/guest/pvmfw/Android.bp
index 793204d..4ef57a6 100644
--- a/guest/pvmfw/Android.bp
+++ b/guest/pvmfw/Android.bp
@@ -17,7 +17,6 @@
         "libciborium_nostd",
         "libciborium_io_nostd",
         "libcoset_nostd",
-        "libcstr",
         "libdiced_open_dice_nostd",
         "libhypervisor_backends",
         "liblibfdt_nostd",
@@ -52,9 +51,6 @@
         unit_test: true,
     },
     prefer_rlib: true,
-    rustlibs: [
-        "libcstr",
-    ],
 }
 
 rust_test {
@@ -117,6 +113,7 @@
         "libcbor_util",
         "libciborium",
         "libdiced_open_dice_nostd",
+        "libhwtrust",
         "libpvmfw_avb_nostd",
         "libdiced_sample_inputs_nostd",
         "libzerocopy_nostd",
diff --git a/guest/pvmfw/avb/tests/utils.rs b/guest/pvmfw/avb/tests/utils.rs
index 79552b5..e8590ac 100644
--- a/guest/pvmfw/avb/tests/utils.rs
+++ b/guest/pvmfw/avb/tests/utils.rs
@@ -124,8 +124,7 @@
     let footer = extract_avb_footer(&kernel)?;
     let kernel_digest =
         hash(&[&hash(&[b"bootloader"]), &kernel[..usize::try_from(footer.original_image_size)?]]);
-    let capabilities =
-        if cfg!(llpvm_changes) { vec![Capability::SecretkeeperProtection] } else { vec![] };
+    let capabilities = vec![Capability::SecretkeeperProtection];
     let initrd_digest = Some(hash(&[&hash(&[initrd_salt]), initrd]));
     let expected_boot_data = VerifiedBootData {
         debug_level: expected_debug_level,
@@ -133,7 +132,7 @@
         initrd_digest,
         public_key: &public_key,
         capabilities,
-        rollback_index: if cfg!(llpvm_changes) { 1 } else { 0 },
+        rollback_index: 1,
         page_size,
     };
     assert_eq!(expected_boot_data, verified_boot_data);
diff --git a/guest/pvmfw/src/bootargs.rs b/guest/pvmfw/src/bootargs.rs
index aacd8e0..0a5697f 100644
--- a/guest/pvmfw/src/bootargs.rs
+++ b/guest/pvmfw/src/bootargs.rs
@@ -108,7 +108,6 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use cstr::cstr;
 
     fn check(raw: &CStr, expected: Result<&[(&str, Option<&str>)], ()>) {
         let actual = BootArgsIterator::new(raw);
@@ -136,35 +135,35 @@
 
     #[test]
     fn empty() {
-        check(cstr!(""), Ok(&[]));
-        check(cstr!("    "), Ok(&[]));
-        check(cstr!("  \n  "), Ok(&[]));
+        check(c"", Ok(&[]));
+        check(c"    ", Ok(&[]));
+        check(c"  \n  ", Ok(&[]));
     }
 
     #[test]
     fn single() {
-        check(cstr!("foo"), Ok(&[("foo", None)]));
-        check(cstr!("   foo"), Ok(&[("foo", None)]));
-        check(cstr!("foo   "), Ok(&[("foo", None)]));
-        check(cstr!("   foo   "), Ok(&[("foo", None)]));
+        check(c"foo", Ok(&[("foo", None)]));
+        check(c"   foo", Ok(&[("foo", None)]));
+        check(c"foo   ", Ok(&[("foo", None)]));
+        check(c"   foo   ", Ok(&[("foo", None)]));
     }
 
     #[test]
     fn single_with_value() {
-        check(cstr!("foo=bar"), Ok(&[("foo", Some("=bar"))]));
-        check(cstr!("   foo=bar"), Ok(&[("foo", Some("=bar"))]));
-        check(cstr!("foo=bar   "), Ok(&[("foo", Some("=bar"))]));
-        check(cstr!("   foo=bar   "), Ok(&[("foo", Some("=bar"))]));
+        check(c"foo=bar", Ok(&[("foo", Some("=bar"))]));
+        check(c"   foo=bar", Ok(&[("foo", Some("=bar"))]));
+        check(c"foo=bar   ", Ok(&[("foo", Some("=bar"))]));
+        check(c"   foo=bar   ", Ok(&[("foo", Some("=bar"))]));
 
-        check(cstr!("foo="), Ok(&[("foo", Some("="))]));
-        check(cstr!("   foo="), Ok(&[("foo", Some("="))]));
-        check(cstr!("foo=   "), Ok(&[("foo", Some("="))]));
-        check(cstr!("   foo=   "), Ok(&[("foo", Some("="))]));
+        check(c"foo=", Ok(&[("foo", Some("="))]));
+        check(c"   foo=", Ok(&[("foo", Some("="))]));
+        check(c"foo=   ", Ok(&[("foo", Some("="))]));
+        check(c"   foo=   ", Ok(&[("foo", Some("="))]));
     }
 
     #[test]
     fn single_with_quote() {
-        check(cstr!("foo=hello\" \"world"), Ok(&[("foo", Some("=hello\" \"world"))]));
+        check(c"foo=hello\" \"world", Ok(&[("foo", Some("=hello\" \"world"))]));
     }
 
     #[test]
@@ -175,32 +174,32 @@
     #[test]
     fn multiple() {
         check(
-            cstr!(" a=b   c=d   e=  f g  "),
+            c" a=b   c=d   e=  f g  ",
             Ok(&[("a", Some("=b")), ("c", Some("=d")), ("e", Some("=")), ("f", None), ("g", None)]),
         );
         check(
-            cstr!("   a=b  \n c=d      e=  f g"),
+            c"   a=b  \n c=d      e=  f g",
             Ok(&[("a", Some("=b")), ("c", Some("=d")), ("e", Some("=")), ("f", None), ("g", None)]),
         );
     }
 
     #[test]
     fn incomplete_quote() {
-        check(
-            cstr!("foo=incomplete\" quote bar=y"),
-            Ok(&[("foo", Some("=incomplete\" quote bar=y"))]),
-        );
+        check(c"foo=incomplete\" quote bar=y", Ok(&[("foo", Some("=incomplete\" quote bar=y"))]));
     }
 
     #[test]
     fn complex() {
-        check(cstr!("  a  a1=  b=c d=e,f,g x=\"value with quote\" y=val\"ue with \"multiple\" quo\"te  "), Ok(&[
-            ("a", None),
-            ("a1", Some("=")),
-            ("b", Some("=c")),
-            ("d", Some("=e,f,g")),
-            ("x", Some("=\"value with quote\"")),
-            ("y", Some("=val\"ue with \"multiple\" quo\"te")),
-        ]));
+        check(
+            c"  a  a1=  b=c d=e,f,g x=\"value with quote\" y=val\"ue with \"multiple\" quo\"te  ",
+            Ok(&[
+                ("a", None),
+                ("a1", Some("=")),
+                ("b", Some("=c")),
+                ("d", Some("=e,f,g")),
+                ("x", Some("=\"value with quote\"")),
+                ("y", Some("=val\"ue with \"multiple\" quo\"te")),
+            ]),
+        );
     }
 }
diff --git a/guest/pvmfw/src/device_assignment.rs b/guest/pvmfw/src/device_assignment.rs
index f37f443..bb2e6ce 100644
--- a/guest/pvmfw/src/device_assignment.rs
+++ b/guest/pvmfw/src/device_assignment.rs
@@ -37,18 +37,6 @@
 use zerocopy::byteorder::big_endian::U32;
 use zerocopy::FromBytes as _;
 
-// TODO(b/308694211): Use cstr! from vmbase instead.
-macro_rules! cstr {
-    ($str:literal) => {{
-        const S: &str = concat!($str, "\0");
-        const C: &::core::ffi::CStr = match ::core::ffi::CStr::from_bytes_with_nul(S.as_bytes()) {
-            Ok(v) => v,
-            Err(_) => panic!("string contains interior NUL"),
-        };
-        C
-    }};
-}
-
 // TODO(b/277993056): Keep constants derived from platform.dts in one place.
 const CELLS_PER_INTERRUPT: usize = 3; // from /intc node in platform.dts
 
@@ -332,7 +320,7 @@
     //       };
     //    };
     //
-    // Then locate_overlay_target_path(cstr!("/fragment@rng/__overlay__/rng")) is Ok("/rng")
+    // Then locate_overlay_target_path(c"/fragment@rng/__overlay__/rng") is Ok("/rng")
     //
     // Contrary to fdt_overlay_target_offset(), this API enforces overlay target property
     // 'target-path = "/"', so the overlay doesn't modify and/or append platform DT's existing
@@ -343,10 +331,9 @@
         dtbo_node: &FdtNode,
     ) -> Result<CString> {
         let fragment_node = dtbo_node.supernode_at_depth(1)?;
-        let target_path = fragment_node
-            .getprop_str(cstr!("target-path"))?
-            .ok_or(DeviceAssignmentError::InvalidDtbo)?;
-        if target_path != cstr!("/") {
+        let target_path =
+            fragment_node.getprop_str(c"target-path")?.ok_or(DeviceAssignmentError::InvalidDtbo)?;
+        if target_path != c"/" {
             return Err(DeviceAssignmentError::UnsupportedOverlayTarget);
         }
 
@@ -415,7 +402,7 @@
 
     /// Parses Physical devices in VM DTBO
     fn parse_physical_devices(&self) -> Result<BTreeMap<Phandle, PhysicalDeviceInfo>> {
-        let Some(physical_node) = self.as_ref().node(cstr!("/host"))? else {
+        let Some(physical_node) = self.as_ref().node(c"/host")? else {
             return Ok(BTreeMap::new());
         };
 
@@ -459,7 +446,7 @@
         let vm_dtbo = self.as_ref();
 
         let mut phandle_map = BTreeMap::new();
-        let Some(local_fixups) = vm_dtbo.node(cstr!("/__local_fixups__"))? else {
+        let Some(local_fixups) = vm_dtbo.node(c"/__local_fixups__")? else {
             return Ok(phandle_map);
         };
 
@@ -615,15 +602,14 @@
 
 impl PvIommu {
     fn parse(node: &FdtNode) -> Result<Self> {
-        let iommu_cells = node
-            .getprop_u32(cstr!("#iommu-cells"))?
-            .ok_or(DeviceAssignmentError::InvalidPvIommu)?;
+        let iommu_cells =
+            node.getprop_u32(c"#iommu-cells")?.ok_or(DeviceAssignmentError::InvalidPvIommu)?;
         // Ensures #iommu-cells = <1>. It means that `<iommus>` entry contains pair of
         // (pvIOMMU ID, vSID)
         if iommu_cells != 1 {
             return Err(DeviceAssignmentError::InvalidPvIommu);
         }
-        let id = node.getprop_u32(cstr!("id"))?.ok_or(DeviceAssignmentError::InvalidPvIommu)?;
+        let id = node.getprop_u32(c"id")?.ok_or(DeviceAssignmentError::InvalidPvIommu)?;
         Ok(Self { id })
     }
 }
@@ -687,10 +673,10 @@
 
 impl PhysIommu {
     fn parse(node: &FdtNode) -> Result<Option<Self>> {
-        let Some(token) = node.getprop_u64(cstr!("android,pvmfw,token"))? else {
+        let Some(token) = node.getprop_u64(c"android,pvmfw,token")? else {
             return Ok(None);
         };
-        let Some(iommu_cells) = node.getprop_u32(cstr!("#iommu-cells"))? else {
+        let Some(iommu_cells) = node.getprop_u32(c"#iommu-cells")? else {
             return Err(DeviceAssignmentError::InvalidPhysIommu);
         };
         // Currently only supports #iommu-cells = <1>.
@@ -715,7 +701,7 @@
         phys_iommus: &BTreeMap<Phandle, PhysIommu>,
     ) -> Result<Vec<(PhysIommu, Sid)>> {
         let mut iommus = vec![];
-        let Some(mut cells) = node.getprop_cells(cstr!("iommus"))? else {
+        let Some(mut cells) = node.getprop_cells(c"iommus")? else {
             return Ok(iommus);
         };
         while let Some(cell) = cells.next() {
@@ -735,7 +721,7 @@
     }
 
     fn parse(node: &FdtNode, phys_iommus: &BTreeMap<Phandle, PhysIommu>) -> Result<Option<Self>> {
-        let Some(phandle) = node.getprop_u32(cstr!("android,pvmfw,target"))? else {
+        let Some(phandle) = node.getprop_u32(c"android,pvmfw,target")? else {
             return Ok(None);
         };
         let target = Phandle::try_from(phandle)?;
@@ -812,7 +798,7 @@
         // Validation: Validate if interrupts cell numbers are multiple of #interrupt-cells.
         // We can't know how many interrupts would exist.
         let interrupts_cells = node
-            .getprop_cells(cstr!("interrupts"))?
+            .getprop_cells(c"interrupts")?
             .ok_or(DeviceAssignmentError::InvalidInterrupts)?
             .count();
         if interrupts_cells % CELLS_PER_INTERRUPT != 0 {
@@ -820,7 +806,7 @@
         }
 
         // Once validated, keep the raw bytes so patch can be done with setprop()
-        Ok(node.getprop(cstr!("interrupts")).unwrap().unwrap().into())
+        Ok(node.getprop(c"interrupts").unwrap().unwrap().into())
     }
 
     // TODO(b/277993056): Also validate /__local_fixups__ to ensure that <iommus> has phandle.
@@ -829,7 +815,7 @@
         pviommus: &BTreeMap<Phandle, PvIommu>,
     ) -> Result<Vec<(PvIommu, Vsid)>> {
         let mut iommus = vec![];
-        let Some(mut cells) = node.getprop_cells(cstr!("iommus"))? else {
+        let Some(mut cells) = node.getprop_cells(c"iommus")? else {
             return Ok(iommus);
         };
         while let Some(cell) = cells.next() {
@@ -917,15 +903,15 @@
 
     fn patch(&self, fdt: &mut Fdt, pviommu_phandles: &BTreeMap<PvIommu, Phandle>) -> Result<()> {
         let mut dst = fdt.node_mut(&self.node_path)?.unwrap();
-        dst.setprop(cstr!("reg"), &to_be_bytes(&self.reg))?;
-        dst.setprop(cstr!("interrupts"), &self.interrupts)?;
+        dst.setprop(c"reg", &to_be_bytes(&self.reg))?;
+        dst.setprop(c"interrupts", &self.interrupts)?;
         let mut iommus = Vec::with_capacity(8 * self.iommus.len());
         for (pviommu, vsid) in &self.iommus {
             let phandle = pviommu_phandles.get(pviommu).unwrap();
             iommus.extend_from_slice(&u32::from(*phandle).to_be_bytes());
             iommus.extend_from_slice(&vsid.0.to_be_bytes());
         }
-        dst.setprop(cstr!("iommus"), &iommus)?;
+        dst.setprop(c"iommus", &iommus)?;
 
         Ok(())
     }
@@ -939,7 +925,7 @@
 }
 
 impl DeviceAssignmentInfo {
-    const PVIOMMU_COMPATIBLE: &'static CStr = cstr!("pkvm,pviommu");
+    const PVIOMMU_COMPATIBLE: &'static CStr = c"pkvm,pviommu";
 
     /// Parses pvIOMMUs in fdt
     // Note: This will validate pvIOMMU ids' uniqueness, even when unassigned.
@@ -1046,8 +1032,8 @@
         Self::validate_pviommu_topology(&assigned_devices)?;
 
         let mut vm_dtbo_mask = vm_dtbo.build_mask(assigned_device_paths)?;
-        vm_dtbo_mask.mask_all(&DtPathTokens::new(cstr!("/__local_fixups__"))?);
-        vm_dtbo_mask.mask_all(&DtPathTokens::new(cstr!("/__symbols__"))?);
+        vm_dtbo_mask.mask_all(&DtPathTokens::new(c"/__local_fixups__")?);
+        vm_dtbo_mask.mask_all(&DtPathTokens::new(c"/__symbols__")?);
 
         // Note: Any node without __overlay__ will be ignored by fdt_apply_overlay,
         // so doesn't need to be filtered.
@@ -1060,7 +1046,7 @@
         let vm_dtbo = vm_dtbo.as_mut();
 
         // Filter unused references in /__local_fixups__
-        if let Some(local_fixups) = vm_dtbo.node_mut(cstr!("/__local_fixups__"))? {
+        if let Some(local_fixups) = vm_dtbo.node_mut(c"/__local_fixups__")? {
             filter_with_mask(local_fixups, &self.vm_dtbo_mask)?;
         }
 
@@ -1078,7 +1064,7 @@
         for pviommu in &self.pviommus {
             let mut node = compatible.ok_or(DeviceAssignmentError::TooManyPvIommu)?;
             let phandle = node.as_node().get_phandle()?.ok_or(DeviceAssignmentError::Internal)?;
-            node.setprop_inplace(cstr!("id"), &pviommu.id.to_be_bytes())?;
+            node.setprop_inplace(c"id", &pviommu.id.to_be_bytes())?;
             if pviommu_phandles.insert(*pviommu, phandle).is_some() {
                 return Err(DeviceAssignmentError::Internal);
             }
@@ -1108,10 +1094,10 @@
 
 /// Cleans device trees not to contain any pre-populated nodes/props for device assignment.
 pub fn clean(fdt: &mut Fdt) -> Result<()> {
-    let mut compatible = fdt.root_mut().next_compatible(cstr!("pkvm,pviommu"))?;
+    let mut compatible = fdt.root_mut().next_compatible(c"pkvm,pviommu")?;
     // Filters pre-populated
     while let Some(filtered_pviommu) = compatible {
-        compatible = filtered_pviommu.delete_and_next_compatible(cstr!("pkvm,pviommu"))?;
+        compatible = filtered_pviommu.delete_and_next_compatible(c"pkvm,pviommu")?;
     }
 
     // Removes any dangling references in __symbols__ (e.g. removed pvIOMMUs)
@@ -1239,24 +1225,23 @@
                 return Err(FdtError::NotFound.into());
             };
 
-            let reg = node.getprop(cstr!("reg"))?.ok_or(DeviceAssignmentError::MalformedReg)?;
-            let interrupts = node
-                .getprop(cstr!("interrupts"))?
-                .ok_or(DeviceAssignmentError::InvalidInterrupts)?;
+            let reg = node.getprop(c"reg")?.ok_or(DeviceAssignmentError::MalformedReg)?;
+            let interrupts =
+                node.getprop(c"interrupts")?.ok_or(DeviceAssignmentError::InvalidInterrupts)?;
             let mut iommus = vec![];
-            if let Some(mut cells) = node.getprop_cells(cstr!("iommus"))? {
+            if let Some(mut cells) = node.getprop_cells(c"iommus")? {
                 while let Some(pviommu_id) = cells.next() {
                     // pvIOMMU id
                     let phandle = Phandle::try_from(pviommu_id)?;
                     let pviommu = fdt
                         .node_with_phandle(phandle)?
                         .ok_or(DeviceAssignmentError::MalformedIommus)?;
-                    let compatible = pviommu.getprop_str(cstr!("compatible"));
-                    if compatible != Ok(Some(cstr!("pkvm,pviommu"))) {
+                    let compatible = pviommu.getprop_str(c"compatible");
+                    if compatible != Ok(Some(c"pkvm,pviommu")) {
                         return Err(DeviceAssignmentError::MalformedIommus);
                     }
                     let id = pviommu
-                        .getprop_u32(cstr!("id"))?
+                        .getprop_u32(c"id")?
                         .ok_or(DeviceAssignmentError::MalformedIommus)?;
                     iommus.push(id);
 
@@ -1273,8 +1258,8 @@
 
     fn collect_pviommus(fdt: &Fdt) -> Result<Vec<u32>> {
         let mut pviommus = BTreeSet::new();
-        for pviommu in fdt.compatible_nodes(cstr!("pkvm,pviommu"))? {
-            if let Ok(Some(id)) = pviommu.getprop_u32(cstr!("id")) {
+        for pviommu in fdt.compatible_nodes(c"pkvm,pviommu")? {
+            if let Ok(Some(id)) = pviommu.getprop_u32(c"id") {
                 pviommus.insert(id);
             }
         }
@@ -1395,24 +1380,24 @@
 
         let symbols = vm_dtbo.symbols().unwrap().unwrap();
 
-        let rng = vm_dtbo.node(cstr!("/fragment@0/__overlay__/rng")).unwrap();
+        let rng = vm_dtbo.node(c"/fragment@0/__overlay__/rng").unwrap();
         assert_ne!(rng, None);
-        let rng_symbol = symbols.getprop_str(cstr!("rng")).unwrap();
-        assert_eq!(Some(cstr!("/fragment@0/__overlay__/rng")), rng_symbol);
+        let rng_symbol = symbols.getprop_str(c"rng").unwrap();
+        assert_eq!(Some(c"/fragment@0/__overlay__/rng"), rng_symbol);
 
-        let light = vm_dtbo.node(cstr!("/fragment@0/__overlay__/light")).unwrap();
+        let light = vm_dtbo.node(c"/fragment@0/__overlay__/light").unwrap();
         assert_eq!(light, None);
-        let light_symbol = symbols.getprop_str(cstr!("light")).unwrap();
+        let light_symbol = symbols.getprop_str(c"light").unwrap();
         assert_eq!(None, light_symbol);
 
-        let led = vm_dtbo.node(cstr!("/fragment@0/__overlay__/led")).unwrap();
+        let led = vm_dtbo.node(c"/fragment@0/__overlay__/led").unwrap();
         assert_eq!(led, None);
-        let led_symbol = symbols.getprop_str(cstr!("led")).unwrap();
+        let led_symbol = symbols.getprop_str(c"led").unwrap();
         assert_eq!(None, led_symbol);
 
-        let backlight = vm_dtbo.node(cstr!("/fragment@0/__overlay__/bus0/backlight")).unwrap();
+        let backlight = vm_dtbo.node(c"/fragment@0/__overlay__/bus0/backlight").unwrap();
         assert_eq!(backlight, None);
-        let backlight_symbol = symbols.getprop_str(cstr!("backlight")).unwrap();
+        let backlight_symbol = symbols.getprop_str(c"backlight").unwrap();
         assert_eq!(None, backlight_symbol);
     }
 
@@ -1440,19 +1425,19 @@
         }
         device_info.patch(platform_dt).unwrap();
 
-        let rng_node = platform_dt.node(cstr!("/bus0/backlight")).unwrap().unwrap();
-        let phandle = rng_node.getprop_u32(cstr!("phandle")).unwrap();
+        let rng_node = platform_dt.node(c"/bus0/backlight").unwrap().unwrap();
+        let phandle = rng_node.getprop_u32(c"phandle").unwrap();
         assert_ne!(None, phandle);
 
         // Note: Intentionally not using AssignedDeviceNode for matching all props.
         type FdtResult<T> = libfdt::Result<T>;
         let expected: Vec<(FdtResult<&CStr>, FdtResult<Vec<u8>>)> = vec![
-            (Ok(cstr!("android,backlight,ignore-gctrl-reset")), Ok(Vec::new())),
-            (Ok(cstr!("compatible")), Ok(Vec::from(*b"android,backlight\0"))),
-            (Ok(cstr!("interrupts")), Ok(into_fdt_prop(vec![0x0, 0xF, 0x4]))),
-            (Ok(cstr!("iommus")), Ok(Vec::new())),
-            (Ok(cstr!("phandle")), Ok(into_fdt_prop(vec![phandle.unwrap()]))),
-            (Ok(cstr!("reg")), Ok(into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]))),
+            (Ok(c"android,backlight,ignore-gctrl-reset"), Ok(Vec::new())),
+            (Ok(c"compatible"), Ok(Vec::from(*b"android,backlight\0"))),
+            (Ok(c"interrupts"), Ok(into_fdt_prop(vec![0x0, 0xF, 0x4]))),
+            (Ok(c"iommus"), Ok(Vec::new())),
+            (Ok(c"phandle"), Ok(into_fdt_prop(vec![phandle.unwrap()]))),
+            (Ok(c"reg"), Ok(into_fdt_prop(vec![0x0, 0x9, 0x0, 0xFF]))),
         ];
 
         let mut properties: Vec<_> = rng_node
@@ -1493,7 +1478,7 @@
         }
         device_info.patch(platform_dt).unwrap();
 
-        let compatible = platform_dt.root().next_compatible(cstr!("pkvm,pviommu")).unwrap();
+        let compatible = platform_dt.root().next_compatible(c"pkvm,pviommu").unwrap();
         assert_eq!(None, compatible);
 
         if let Some(symbols) = platform_dt.symbols().unwrap() {
@@ -1794,12 +1779,12 @@
         let mut platform_dt_data = pvmfw_fdt_template::RAW.to_vec();
         let platform_dt = Fdt::from_mut_slice(&mut platform_dt_data).unwrap();
 
-        let compatible = platform_dt.root().next_compatible(cstr!("pkvm,pviommu"));
+        let compatible = platform_dt.root().next_compatible(c"pkvm,pviommu");
         assert_ne!(None, compatible.unwrap());
 
         clean(platform_dt).unwrap();
 
-        let compatible = platform_dt.root().next_compatible(cstr!("pkvm,pviommu"));
+        let compatible = platform_dt.root().next_compatible(c"pkvm,pviommu");
         assert_eq!(Ok(None), compatible);
     }
 
diff --git a/guest/pvmfw/src/dice.rs b/guest/pvmfw/src/dice.rs
index a72c1fc..78bd6b8 100644
--- a/guest/pvmfw/src/dice.rs
+++ b/guest/pvmfw/src/dice.rs
@@ -185,6 +185,7 @@
     use diced_open_dice::KeyAlgorithm;
     use diced_open_dice::HIDDEN_SIZE;
     use diced_sample_inputs::make_sample_bcc_and_cdis;
+    use hwtrust::{dice, session::Session};
     use pvmfw_avb::Capability;
     use pvmfw_avb::DebugLevel;
     use pvmfw_avb::Digest;
@@ -426,14 +427,11 @@
                 },
             )
             .expect("Failed to derive EcdsaP384 -> Ed25519 BCC");
-        let _bcc_handover3 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
+        let bcc_handover3 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
 
-        // TODO(b/378813154): Check the DICE chain with `hwtrust` once the profile version
-        // is updated.
-        // The check cannot be done now because parsing the chain causes the following error:
-        // Invalid payload at index 3. Caused by:
-        // 0: opendice.example.p256
-        // 1: unknown profile version
+        let mut session = Session::default();
+        session.set_allow_any_mode(true);
+        let _chain = dice::Chain::from_cbor(&session, bcc_handover3.bcc().unwrap()).unwrap();
     }
 
     fn to_bcc_handover(dice_artifacts: &dyn DiceArtifacts) -> Vec<u8> {
diff --git a/guest/pvmfw/src/fdt.rs b/guest/pvmfw/src/fdt.rs
index 4370675..29212f9 100644
--- a/guest/pvmfw/src/fdt.rs
+++ b/guest/pvmfw/src/fdt.rs
@@ -28,7 +28,6 @@
 use core::fmt;
 use core::mem::size_of;
 use core::ops::Range;
-use cstr::cstr;
 use hypervisor_backends::get_device_assigner;
 use hypervisor_backends::get_mem_sharer;
 use libfdt::AddressRange;
@@ -83,10 +82,10 @@
 /// Extract from /config the address range containing the pre-loaded kernel. Absence of /config is
 /// not an error.
 pub fn read_kernel_range_from(fdt: &Fdt) -> libfdt::Result<Option<Range<usize>>> {
-    let addr = cstr!("kernel-address");
-    let size = cstr!("kernel-size");
+    let addr = c"kernel-address";
+    let size = c"kernel-size";
 
-    if let Some(config) = fdt.node(cstr!("/config"))? {
+    if let Some(config) = fdt.node(c"/config")? {
         if let (Some(addr), Some(size)) = (config.getprop_u32(addr)?, config.getprop_u32(size)?) {
             let addr = addr as usize;
             let size = size as usize;
@@ -101,8 +100,8 @@
 /// Extract from /chosen the address range containing the pre-loaded ramdisk. Absence is not an
 /// error as there can be initrd-less VM.
 pub fn read_initrd_range_from(fdt: &Fdt) -> libfdt::Result<Option<Range<usize>>> {
-    let start = cstr!("linux,initrd-start");
-    let end = cstr!("linux,initrd-end");
+    let start = c"linux,initrd-start";
+    let end = c"linux,initrd-end";
 
     if let Some(chosen) = fdt.chosen()? {
         if let (Some(start), Some(end)) = (chosen.getprop_u32(start)?, chosen.getprop_u32(end)?) {
@@ -118,14 +117,14 @@
     let end = u32::try_from(initrd_range.end).unwrap();
 
     let mut node = fdt.chosen_mut()?.ok_or(FdtError::NotFound)?;
-    node.setprop(cstr!("linux,initrd-start"), &start.to_be_bytes())?;
-    node.setprop(cstr!("linux,initrd-end"), &end.to_be_bytes())?;
+    node.setprop(c"linux,initrd-start", &start.to_be_bytes())?;
+    node.setprop(c"linux,initrd-end", &end.to_be_bytes())?;
     Ok(())
 }
 
 fn read_bootargs_from(fdt: &Fdt) -> libfdt::Result<Option<CString>> {
     if let Some(chosen) = fdt.chosen()? {
-        if let Some(bootargs) = chosen.getprop_str(cstr!("bootargs"))? {
+        if let Some(bootargs) = chosen.getprop_str(c"bootargs")? {
             // We need to copy the string to heap because the original fdt will be invalidated
             // by the templated DT
             let copy = CString::new(bootargs.to_bytes()).map_err(|_| FdtError::BadValue)?;
@@ -140,7 +139,7 @@
     // This function is called before the verification is done. So, we just copy the bootargs to
     // the new FDT unmodified. This will be filtered again in the modify_for_next_stage function
     // if the VM is not debuggable.
-    node.setprop(cstr!("bootargs"), bootargs.to_bytes_with_nul())
+    node.setprop(c"bootargs", bootargs.to_bytes_with_nul())
 }
 
 /// Reads and validates the memory range in the DT.
@@ -186,9 +185,9 @@
 fn patch_memory_range(fdt: &mut Fdt, memory_range: &Range<usize>) -> libfdt::Result<()> {
     let addr = u64::try_from(MEM_START).unwrap();
     let size = u64::try_from(memory_range.len()).unwrap();
-    fdt.node_mut(cstr!("/memory"))?
+    fdt.node_mut(c"/memory")?
         .ok_or(FdtError::NotFound)?
-        .setprop_inplace(cstr!("reg"), [addr.to_be(), size.to_be()].as_bytes())
+        .setprop_inplace(c"reg", [addr.to_be(), size.to_be()].as_bytes())
 }
 
 #[derive(Debug, Default)]
@@ -207,7 +206,7 @@
     let mut table = ArrayVec::new();
     let mut opp_nodes = opp_node.subnodes()?;
     for subnode in opp_nodes.by_ref().take(table.capacity()) {
-        let prop = subnode.getprop_u64(cstr!("opp-hz"))?.ok_or(FdtError::NotFound)?;
+        let prop = subnode.getprop_u64(c"opp-hz")?.ok_or(FdtError::NotFound)?;
         table.push(prop);
     }
 
@@ -239,7 +238,7 @@
 }
 
 fn read_cpu_map_from(fdt: &Fdt) -> libfdt::Result<Option<BTreeMap<Phandle, (usize, usize)>>> {
-    let Some(cpu_map) = fdt.node(cstr!("/cpus/cpu-map"))? else {
+    let Some(cpu_map) = fdt.node(c"/cpus/cpu-map")? else {
         return Ok(None);
     };
 
@@ -254,7 +253,7 @@
             let Some(core) = cluster.subnode(&name)? else {
                 break;
             };
-            let cpu = core.getprop_u32(cstr!("cpu"))?.ok_or(FdtError::NotFound)?;
+            let cpu = core.getprop_u32(c"cpu")?.ok_or(FdtError::NotFound)?;
             let prev = topology.insert(cpu.try_into()?, (n, m));
             if prev.is_some() {
                 return Err(FdtError::BadValue);
@@ -273,10 +272,10 @@
     let cpu_map = read_cpu_map_from(fdt)?;
     let mut topology: CpuTopology = Default::default();
 
-    let mut cpu_nodes = fdt.compatible_nodes(cstr!("arm,armv8"))?;
+    let mut cpu_nodes = fdt.compatible_nodes(c"arm,armv8")?;
     for (idx, cpu) in cpu_nodes.by_ref().take(cpus.capacity()).enumerate() {
-        let cpu_capacity = cpu.getprop_u32(cstr!("capacity-dmips-mhz"))?;
-        let opp_phandle = cpu.getprop_u32(cstr!("operating-points-v2"))?;
+        let cpu_capacity = cpu.getprop_u32(c"capacity-dmips-mhz")?;
+        let opp_phandle = cpu.getprop_u32(c"operating-points-v2")?;
         let opptable_info = if let Some(phandle) = opp_phandle {
             let phandle = phandle.try_into()?;
             let node = fdt.node_with_phandle(phandle)?.ok_or(FdtError::NotFound)?;
@@ -313,7 +312,7 @@
 }
 
 fn read_vcpufreq_info(fdt: &Fdt) -> libfdt::Result<Option<VcpufreqInfo>> {
-    let mut nodes = fdt.compatible_nodes(cstr!("virtual,android-v-only-cpufreq"))?;
+    let mut nodes = fdt.compatible_nodes(c"virtual,android-v-only-cpufreq")?;
     let Some(node) = nodes.next() else {
         return Ok(None);
     };
@@ -351,7 +350,7 @@
     node: FdtNodeMut,
     opptable: Option<ArrayVec<[u64; CpuInfo::MAX_OPPTABLES]>>,
 ) -> libfdt::Result<()> {
-    let oppcompat = cstr!("operating-points-v2");
+    let oppcompat = c"operating-points-v2";
     let next = node.next_compatible(oppcompat)?.ok_or(FdtError::NoSpace)?;
 
     let Some(opptable) = opptable else {
@@ -362,7 +361,7 @@
 
     for entry in opptable {
         let mut subnode = next_subnode.ok_or(FdtError::NoSpace)?;
-        subnode.setprop_inplace(cstr!("opp-hz"), &entry.to_be_bytes())?;
+        subnode.setprop_inplace(c"opp-hz", &entry.to_be_bytes())?;
         next_subnode = subnode.next_subnode()?;
     }
 
@@ -391,14 +390,14 @@
     cpus: &[CpuInfo],
     topology: &Option<CpuTopology>,
 ) -> libfdt::Result<()> {
-    const COMPAT: &CStr = cstr!("arm,armv8");
+    const COMPAT: &CStr = c"arm,armv8";
     let mut cpu_phandles = Vec::new();
     for (idx, cpu) in cpus.iter().enumerate() {
         let mut cur = get_nth_compatible(fdt, idx, COMPAT)?.ok_or(FdtError::NoSpace)?;
         let phandle = cur.as_node().get_phandle()?.unwrap();
         cpu_phandles.push(phandle);
         if let Some(cpu_capacity) = cpu.cpu_capacity {
-            cur.setprop_inplace(cstr!("capacity-dmips-mhz"), &cpu_capacity.to_be_bytes())?;
+            cur.setprop_inplace(c"capacity-dmips-mhz", &cpu_capacity.to_be_bytes())?;
         }
         patch_opptable(cur, cpu.opptable_info)?;
     }
@@ -418,7 +417,7 @@
                     iter = if let Some(core_idx) = core {
                         let phandle = *cpu_phandles.get(core_idx).unwrap();
                         let value = u32::from(phandle).to_be_bytes();
-                        core_node.setprop_inplace(cstr!("cpu"), &value)?;
+                        core_node.setprop_inplace(c"cpu", &value)?;
                         core_node.next_subnode()?
                     } else {
                         core_node.delete_and_next_subnode()?
@@ -430,7 +429,7 @@
             }
         }
     } else {
-        fdt.node_mut(cstr!("/cpus/cpu-map"))?.unwrap().nop()?;
+        fdt.node_mut(c"/cpus/cpu-map")?.unwrap().nop()?;
     }
 
     Ok(())
@@ -440,7 +439,7 @@
 /// the guest that don't require being validated by pvmfw.
 fn parse_untrusted_props(fdt: &Fdt) -> libfdt::Result<BTreeMap<CString, Vec<u8>>> {
     let mut props = BTreeMap::new();
-    if let Some(node) = fdt.node(cstr!("/avf/untrusted"))? {
+    if let Some(node) = fdt.node(c"/avf/untrusted")? {
         for property in node.properties()? {
             let name = property.name()?;
             let value = property.value()?;
@@ -457,7 +456,7 @@
 /// Read candidate properties' names from DT which could be overlaid
 fn parse_vm_ref_dt(fdt: &Fdt) -> libfdt::Result<BTreeMap<CString, Vec<u8>>> {
     let mut property_map = BTreeMap::new();
-    if let Some(avf_node) = fdt.node(cstr!("/avf"))? {
+    if let Some(avf_node) = fdt.node(c"/avf")? {
         for property in avf_node.properties()? {
             let name = property.name()?;
             let value = property.value()?;
@@ -471,8 +470,7 @@
 }
 
 fn validate_untrusted_props(props: &BTreeMap<CString, Vec<u8>>) -> Result<(), FdtValidationError> {
-    const FORBIDDEN_PROPS: &[&CStr] =
-        &[cstr!("compatible"), cstr!("linux,phandle"), cstr!("phandle")];
+    const FORBIDDEN_PROPS: &[&CStr] = &[c"compatible", c"linux,phandle", c"phandle"];
 
     for name in FORBIDDEN_PROPS {
         if props.contains_key(*name) {
@@ -491,9 +489,9 @@
     props_info: &BTreeMap<CString, Vec<u8>>,
 ) -> libfdt::Result<()> {
     let root_vm_dt = vm_dt.root_mut();
-    let mut avf_vm_dt = root_vm_dt.add_subnode(cstr!("avf"))?;
+    let mut avf_vm_dt = root_vm_dt.add_subnode(c"avf")?;
     // TODO(b/318431677): Validate nodes beyond /avf.
-    let avf_node = vm_ref_dt.node(cstr!("/avf"))?.ok_or(FdtError::NotFound)?;
+    let avf_node = vm_ref_dt.node(c"/avf")?.ok_or(FdtError::NotFound)?;
     for (name, value) in props_info.iter() {
         if let Some(ref_value) = avf_node.getprop(name)? {
             if value != ref_value {
@@ -551,14 +549,13 @@
 
 /// Read pci host controller ranges, irq maps, and irq map masks from DT
 fn read_pci_info_from(fdt: &Fdt) -> libfdt::Result<PciInfo> {
-    let node =
-        fdt.compatible_nodes(cstr!("pci-host-cam-generic"))?.next().ok_or(FdtError::NotFound)?;
+    let node = fdt.compatible_nodes(c"pci-host-cam-generic")?.next().ok_or(FdtError::NotFound)?;
 
     let mut ranges = node.ranges::<(u32, u64), u64, u64>()?.ok_or(FdtError::NotFound)?;
     let range0 = ranges.next().ok_or(FdtError::NotFound)?;
     let range1 = ranges.next().ok_or(FdtError::NotFound)?;
 
-    let irq_masks = node.getprop_cells(cstr!("interrupt-map-mask"))?.ok_or(FdtError::NotFound)?;
+    let irq_masks = node.getprop_cells(c"interrupt-map-mask")?.ok_or(FdtError::NotFound)?;
     let mut chunks = CellChunkIterator::<{ PciInfo::IRQ_MASK_CELLS }>::new(irq_masks);
     let irq_masks = (&mut chunks).take(PciInfo::MAX_IRQS).collect();
 
@@ -567,7 +564,7 @@
         return Err(FdtError::NoSpace);
     }
 
-    let irq_maps = node.getprop_cells(cstr!("interrupt-map"))?.ok_or(FdtError::NotFound)?;
+    let irq_maps = node.getprop_cells(c"interrupt-map")?.ok_or(FdtError::NotFound)?;
     let mut chunks = CellChunkIterator::<{ PciInfo::IRQ_MAP_CELLS }>::new(irq_maps);
     let irq_maps = (&mut chunks).take(PciInfo::MAX_IRQS).collect();
 
@@ -721,16 +718,16 @@
 
 fn patch_pci_info(fdt: &mut Fdt, pci_info: &PciInfo) -> libfdt::Result<()> {
     let mut node =
-        fdt.root_mut().next_compatible(cstr!("pci-host-cam-generic"))?.ok_or(FdtError::NotFound)?;
+        fdt.root_mut().next_compatible(c"pci-host-cam-generic")?.ok_or(FdtError::NotFound)?;
 
     let irq_masks_size = pci_info.irq_masks.len() * size_of::<PciIrqMask>();
-    node.trimprop(cstr!("interrupt-map-mask"), irq_masks_size)?;
+    node.trimprop(c"interrupt-map-mask", irq_masks_size)?;
 
     let irq_maps_size = pci_info.irq_maps.len() * size_of::<PciIrqMap>();
-    node.trimprop(cstr!("interrupt-map"), irq_maps_size)?;
+    node.trimprop(c"interrupt-map", irq_maps_size)?;
 
     node.setprop_inplace(
-        cstr!("ranges"),
+        c"ranges",
         [pci_info.ranges[0].to_cells(), pci_info.ranges[1].to_cells()].as_flattened(),
     )
 }
@@ -747,7 +744,7 @@
 fn read_serial_info_from(fdt: &Fdt) -> libfdt::Result<SerialInfo> {
     let mut addrs = ArrayVec::new();
 
-    let mut serial_nodes = fdt.compatible_nodes(cstr!("ns16550a"))?;
+    let mut serial_nodes = fdt.compatible_nodes(c"ns16550a")?;
     for node in serial_nodes.by_ref().take(addrs.capacity()) {
         let reg = node.first_reg()?;
         addrs.push(reg.addr);
@@ -793,7 +790,7 @@
 }
 
 fn read_wdt_info_from(fdt: &Fdt) -> libfdt::Result<WdtInfo> {
-    let mut node_iter = fdt.compatible_nodes(cstr!("qemu,vcpu-stall-detector"))?;
+    let mut node_iter = fdt.compatible_nodes(c"qemu,vcpu-stall-detector")?;
     let node = node_iter.next().ok_or(FdtError::NotFound)?;
     let mut ranges = node.reg()?.ok_or(FdtError::NotFound)?;
 
@@ -803,7 +800,7 @@
         warn!("Discarding extra vmwdt <reg> entries.");
     }
 
-    let interrupts = node.getprop_cells(cstr!("interrupts"))?.ok_or(FdtError::NotFound)?;
+    let interrupts = node.getprop_cells(c"interrupts")?.ok_or(FdtError::NotFound)?;
     let mut chunks = CellChunkIterator::<{ WdtInfo::IRQ_CELLS }>::new(interrupts);
     let irq = chunks.next().ok_or(FdtError::NotFound)?;
 
@@ -831,15 +828,15 @@
 
     let mut node = fdt
         .root_mut()
-        .next_compatible(cstr!("qemu,vcpu-stall-detector"))?
+        .next_compatible(c"qemu,vcpu-stall-detector")?
         .ok_or(libfdt::FdtError::NotFound)?;
-    node.setprop_inplace(cstr!("interrupts"), interrupts.as_bytes())?;
+    node.setprop_inplace(c"interrupts", interrupts.as_bytes())?;
     Ok(())
 }
 
 /// Patch the DT by deleting the ns16550a compatible nodes whose address are unknown
 fn patch_serial_info(fdt: &mut Fdt, serial_info: &SerialInfo) -> libfdt::Result<()> {
-    let name = cstr!("ns16550a");
+    let name = c"ns16550a";
     let mut next = fdt.root_mut().next_compatible(name);
     while let Some(current) = next? {
         let reg =
@@ -889,27 +886,27 @@
 
 fn patch_swiotlb_info(fdt: &mut Fdt, swiotlb_info: &SwiotlbInfo) -> libfdt::Result<()> {
     let mut node =
-        fdt.root_mut().next_compatible(cstr!("restricted-dma-pool"))?.ok_or(FdtError::NotFound)?;
+        fdt.root_mut().next_compatible(c"restricted-dma-pool")?.ok_or(FdtError::NotFound)?;
 
     if let Some(range) = swiotlb_info.fixed_range() {
         node.setprop_addrrange_inplace(
-            cstr!("reg"),
+            c"reg",
             range.start.try_into().unwrap(),
             range.len().try_into().unwrap(),
         )?;
-        node.nop_property(cstr!("size"))?;
-        node.nop_property(cstr!("alignment"))?;
+        node.nop_property(c"size")?;
+        node.nop_property(c"alignment")?;
     } else {
-        node.nop_property(cstr!("reg"))?;
-        node.setprop_inplace(cstr!("size"), &swiotlb_info.size.to_be_bytes())?;
-        node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.unwrap().to_be_bytes())?;
+        node.nop_property(c"reg")?;
+        node.setprop_inplace(c"size", &swiotlb_info.size.to_be_bytes())?;
+        node.setprop_inplace(c"alignment", &swiotlb_info.align.unwrap().to_be_bytes())?;
     }
 
     Ok(())
 }
 
 fn patch_gic(fdt: &mut Fdt, num_cpus: usize) -> libfdt::Result<()> {
-    let node = fdt.compatible_nodes(cstr!("arm,gic-v3"))?.next().ok_or(FdtError::NotFound)?;
+    let node = fdt.compatible_nodes(c"arm,gic-v3")?.next().ok_or(FdtError::NotFound)?;
     let mut ranges = node.reg()?.ok_or(FdtError::NotFound)?;
     let range0 = ranges.next().ok_or(FdtError::NotFound)?;
     let mut range1 = ranges.next().ok_or(FdtError::NotFound)?;
@@ -927,16 +924,15 @@
     let (addr1, size1) = range1.to_cells();
     let value = [addr0, size0.unwrap(), addr1, size1.unwrap()];
 
-    let mut node =
-        fdt.root_mut().next_compatible(cstr!("arm,gic-v3"))?.ok_or(FdtError::NotFound)?;
-    node.setprop_inplace(cstr!("reg"), value.as_flattened())
+    let mut node = fdt.root_mut().next_compatible(c"arm,gic-v3")?.ok_or(FdtError::NotFound)?;
+    node.setprop_inplace(c"reg", value.as_flattened())
 }
 
 fn patch_timer(fdt: &mut Fdt, num_cpus: usize) -> libfdt::Result<()> {
     const NUM_INTERRUPTS: usize = 4;
     const CELLS_PER_INTERRUPT: usize = 3;
-    let node = fdt.compatible_nodes(cstr!("arm,armv8-timer"))?.next().ok_or(FdtError::NotFound)?;
-    let interrupts = node.getprop_cells(cstr!("interrupts"))?.ok_or(FdtError::NotFound)?;
+    let node = fdt.compatible_nodes(c"arm,armv8-timer")?.next().ok_or(FdtError::NotFound)?;
+    let interrupts = node.getprop_cells(c"interrupts")?.ok_or(FdtError::NotFound)?;
     let mut value: ArrayVec<[u32; NUM_INTERRUPTS * CELLS_PER_INTERRUPT]> =
         interrupts.take(NUM_INTERRUPTS * CELLS_PER_INTERRUPT).collect();
 
@@ -953,20 +949,19 @@
 
     let value = value.into_inner();
 
-    let mut node =
-        fdt.root_mut().next_compatible(cstr!("arm,armv8-timer"))?.ok_or(FdtError::NotFound)?;
-    node.setprop_inplace(cstr!("interrupts"), value.as_bytes())
+    let mut node = fdt.root_mut().next_compatible(c"arm,armv8-timer")?.ok_or(FdtError::NotFound)?;
+    node.setprop_inplace(c"interrupts", value.as_bytes())
 }
 
 fn patch_untrusted_props(fdt: &mut Fdt, props: &BTreeMap<CString, Vec<u8>>) -> libfdt::Result<()> {
-    let avf_node = if let Some(node) = fdt.node_mut(cstr!("/avf"))? {
+    let avf_node = if let Some(node) = fdt.node_mut(c"/avf")? {
         node
     } else {
-        fdt.root_mut().add_subnode(cstr!("avf"))?
+        fdt.root_mut().add_subnode(c"avf")?
     };
 
     // The node shouldn't already be present; if it is, return the error.
-    let mut node = avf_node.add_subnode(cstr!("untrusted"))?;
+    let mut node = avf_node.add_subnode(c"untrusted")?;
 
     for (name, value) in props {
         node.setprop(name, value)?;
@@ -982,9 +977,9 @@
 }
 
 fn patch_vcpufreq(fdt: &mut Fdt, vcpufreq_info: &Option<VcpufreqInfo>) -> libfdt::Result<()> {
-    let mut node = fdt.node_mut(cstr!("/cpufreq"))?.unwrap();
+    let mut node = fdt.node_mut(c"/cpufreq")?.unwrap();
     if let Some(info) = vcpufreq_info {
-        node.setprop_addrrange_inplace(cstr!("reg"), info.addr, info.size)
+        node.setprop_addrrange_inplace(c"reg", info.addr, info.size)
     } else {
         node.nop()
     }
@@ -1304,9 +1299,9 @@
     patch_dice_node(fdt, bcc.as_ptr() as usize, bcc.len())?;
 
     if let Some(mut chosen) = fdt.chosen_mut()? {
-        empty_or_delete_prop(&mut chosen, cstr!("avf,strict-boot"), strict_boot)?;
-        empty_or_delete_prop(&mut chosen, cstr!("avf,new-instance"), new_instance)?;
-        chosen.setprop_inplace(cstr!("kaslr-seed"), &kaslr_seed.to_be_bytes())?;
+        empty_or_delete_prop(&mut chosen, c"avf,strict-boot", strict_boot)?;
+        empty_or_delete_prop(&mut chosen, c"avf,new-instance", new_instance)?;
+        chosen.setprop_inplace(c"kaslr-seed", &kaslr_seed.to_be_bytes())?;
     };
     if !debuggable {
         if let Some(bootargs) = read_bootargs_from(fdt)? {
@@ -1323,13 +1318,13 @@
 fn patch_dice_node(fdt: &mut Fdt, addr: usize, size: usize) -> libfdt::Result<()> {
     // We reject DTs with missing reserved-memory node as validation should have checked that the
     // "swiotlb" subnode (compatible = "restricted-dma-pool") was present.
-    let node = fdt.node_mut(cstr!("/reserved-memory"))?.ok_or(libfdt::FdtError::NotFound)?;
+    let node = fdt.node_mut(c"/reserved-memory")?.ok_or(libfdt::FdtError::NotFound)?;
 
-    let mut node = node.next_compatible(cstr!("google,open-dice"))?.ok_or(FdtError::NotFound)?;
+    let mut node = node.next_compatible(c"google,open-dice")?.ok_or(FdtError::NotFound)?;
 
     let addr: u64 = addr.try_into().unwrap();
     let size: u64 = size.try_into().unwrap();
-    node.setprop_inplace(cstr!("reg"), [addr.to_be_bytes(), size.to_be_bytes()].as_flattened())
+    node.setprop_inplace(c"reg", [addr.to_be_bytes(), size.to_be_bytes()].as_flattened())
 }
 
 fn empty_or_delete_prop(
@@ -1376,7 +1371,7 @@
 }
 
 fn has_common_debug_policy(fdt: &Fdt, debug_feature_name: &CStr) -> libfdt::Result<bool> {
-    if let Some(node) = fdt.node(cstr!("/avf/guest/common"))? {
+    if let Some(node) = fdt.node(c"/avf/guest/common")? {
         if let Some(value) = node.getprop_u32(debug_feature_name)? {
             return Ok(value == 1);
         }
@@ -1385,8 +1380,8 @@
 }
 
 fn filter_out_dangerous_bootargs(fdt: &mut Fdt, bootargs: &CStr) -> libfdt::Result<()> {
-    let has_crashkernel = has_common_debug_policy(fdt, cstr!("ramdump"))?;
-    let has_console = has_common_debug_policy(fdt, cstr!("log"))?;
+    let has_crashkernel = has_common_debug_policy(fdt, c"ramdump")?;
+    let has_console = has_common_debug_policy(fdt, c"log")?;
 
     let accepted: &[(&str, Box<dyn Fn(Option<&str>) -> bool>)] = &[
         ("panic", Box::new(|v| if let Some(v) = v { v == "=-1" } else { false })),
@@ -1417,5 +1412,5 @@
     new_bootargs.push(b'\0');
 
     let mut node = fdt.chosen_mut()?.ok_or(FdtError::NotFound)?;
-    node.setprop(cstr!("bootargs"), new_bootargs.as_slice())
+    node.setprop(c"bootargs", new_bootargs.as_slice())
 }
diff --git a/guest/pvmfw/src/main.rs b/guest/pvmfw/src/main.rs
index a28a039..0a3dca6 100644
--- a/guest/pvmfw/src/main.rs
+++ b/guest/pvmfw/src/main.rs
@@ -40,7 +40,6 @@
 use alloc::borrow::Cow;
 use alloc::boxed::Box;
 use bssl_avf::Digester;
-use cstr::cstr;
 use diced_open_dice::{bcc_handover_parse, DiceArtifacts, DiceContext, Hidden, VM_KEY_ALGORITHM};
 use libfdt::{Fdt, FdtNode};
 use log::{debug, error, info, trace, warn};
@@ -130,7 +129,7 @@
         RebootReason::InternalError
     })?;
 
-    let instance_hash = if cfg!(llpvm_changes) { Some(salt_from_instance_id(fdt)?) } else { None };
+    let instance_hash = Some(salt_from_instance_id(fdt)?);
     let (new_instance, salt, defer_rollback_protection) = perform_rollback_protection(
         fdt,
         &verified_boot_data,
@@ -220,7 +219,7 @@
 
 fn instance_id(fdt: &Fdt) -> Result<&[u8], RebootReason> {
     let node = avf_untrusted_node(fdt)?;
-    let id = node.getprop(cstr!("instance-id")).map_err(|e| {
+    let id = node.getprop(c"instance-id").map_err(|e| {
         error!("Failed to get instance-id in DT: {e}");
         RebootReason::InvalidFdt
     })?;
@@ -231,7 +230,7 @@
 }
 
 fn avf_untrusted_node(fdt: &Fdt) -> Result<FdtNode, RebootReason> {
-    let node = fdt.node(cstr!("/avf/untrusted")).map_err(|e| {
+    let node = fdt.node(c"/avf/untrusted").map_err(|e| {
         error!("Failed to get /avf/untrusted node: {e}");
         RebootReason::InvalidFdt
     })?;
diff --git a/guest/pvmfw/src/rollback.rs b/guest/pvmfw/src/rollback.rs
index bc16332..f7723d7 100644
--- a/guest/pvmfw/src/rollback.rs
+++ b/guest/pvmfw/src/rollback.rs
@@ -19,7 +19,6 @@
 use crate::instance::EntryBody;
 use crate::instance::Error as InstanceError;
 use crate::instance::{get_recorded_entry, record_instance_entry};
-use cstr::cstr;
 use diced_open_dice::Hidden;
 use libfdt::{Fdt, FdtNode};
 use log::{error, info};
@@ -31,7 +30,7 @@
 /// Performs RBP based on the input payload, current DICE chain, and host-controlled platform.
 ///
 /// On success, returns a tuple containing:
-/// - `new_instance`: true if a new entry was created using the legacy instance.img solution;
+/// - `new_instance`: true if the legacy instance.img solution was used and a new entry created;
 /// - `salt`: the salt representing the instance, to be used during DICE derivation;
 /// - `defer_rollback_protection`: if RBP is being deferred.
 pub fn perform_rollback_protection(
@@ -42,67 +41,87 @@
     cdi_seal: &[u8],
     instance_hash: Option<Hidden>,
 ) -> Result<(bool, Hidden, bool), RebootReason> {
-    let defer_rollback_protection = should_defer_rollback_protection(fdt)?
-        && verified_boot_data.has_capability(Capability::SecretkeeperProtection);
-    let (new_instance, salt) = if defer_rollback_protection {
-        info!("Guest OS is capable of Secretkeeper protection, deferring rollback protection");
-        // rollback_index of the image is used as security_version and is expected to be > 0 to
-        // discourage implicit allocation.
-        if verified_boot_data.rollback_index == 0 {
-            error!("Expected positive rollback_index, found 0");
-            return Err(RebootReason::InvalidPayload);
-        };
-        (false, instance_hash.unwrap())
+    if should_defer_rollback_protection(fdt)?
+        && verified_boot_data.has_capability(Capability::SecretkeeperProtection)
+    {
+        perform_deferred_rollback_protection(verified_boot_data)?;
+        Ok((false, instance_hash.unwrap(), true))
     } else if verified_boot_data.has_capability(Capability::RemoteAttest) {
-        info!("Service VM capable of remote attestation detected, performing version checks");
-        if service_vm_version::VERSION != verified_boot_data.rollback_index {
-            // For RKP VM, we only boot if the version in the AVB footer of its kernel matches
-            // the one embedded in pvmfw at build time.
-            // This prevents the pvmfw from booting a roll backed RKP VM.
-            error!(
-                "Service VM version mismatch: expected {}, found {}",
-                service_vm_version::VERSION,
-                verified_boot_data.rollback_index
-            );
-            return Err(RebootReason::InvalidPayload);
-        }
-        (false, instance_hash.unwrap())
+        perform_fixed_index_rollback_protection(verified_boot_data)?;
+        Ok((false, instance_hash.unwrap(), false))
     } else if verified_boot_data.has_capability(Capability::TrustySecurityVm) {
-        // The rollback protection of Trusty VMs are handled by AuthMgr, so we don't need to
-        // handle it here.
-        info!("Trusty Security VM detected");
-        (false, instance_hash.unwrap())
+        skip_rollback_protection()?;
+        Ok((false, instance_hash.unwrap(), false))
     } else {
-        info!("Fallback to instance.img based rollback checks");
-        let (recorded_entry, mut instance_img, header_index) =
-            get_recorded_entry(pci_root, cdi_seal).map_err(|e| {
-                error!("Failed to get entry from instance.img: {e}");
-                RebootReason::InternalError
-            })?;
-        let (new_instance, salt) = if let Some(entry) = recorded_entry {
-            check_dice_measurements_match_entry(dice_inputs, &entry)?;
-            let salt = instance_hash.unwrap_or(entry.salt);
-            (false, salt)
-        } else {
-            // New instance!
-            let salt = instance_hash.map_or_else(rand::random_array, Ok).map_err(|e| {
-                error!("Failed to generated instance.img salt: {e}");
-                RebootReason::InternalError
-            })?;
+        perform_legacy_rollback_protection(dice_inputs, pci_root, cdi_seal, instance_hash)
+    }
+}
 
-            let entry = EntryBody::new(dice_inputs, &salt);
-            record_instance_entry(&entry, cdi_seal, &mut instance_img, header_index).map_err(
-                |e| {
-                    error!("Failed to get recorded entry in instance.img: {e}");
-                    RebootReason::InternalError
-                },
-            )?;
-            (true, salt)
-        };
-        (new_instance, salt)
+fn perform_deferred_rollback_protection(
+    verified_boot_data: &VerifiedBootData,
+) -> Result<(), RebootReason> {
+    info!("Deferring rollback protection");
+    // rollback_index of the image is used as security_version and is expected to be > 0 to
+    // discourage implicit allocation.
+    if verified_boot_data.rollback_index == 0 {
+        error!("Expected positive rollback_index, found 0");
+        Err(RebootReason::InvalidPayload)
+    } else {
+        Ok(())
+    }
+}
+
+fn perform_fixed_index_rollback_protection(
+    verified_boot_data: &VerifiedBootData,
+) -> Result<(), RebootReason> {
+    info!("Performing fixed-index rollback protection");
+    let fixed_index = service_vm_version::VERSION;
+    let index = verified_boot_data.rollback_index;
+    if index != fixed_index {
+        error!("Rollback index mismatch: expected {fixed_index}, found {index}");
+        Err(RebootReason::InvalidPayload)
+    } else {
+        Ok(())
+    }
+}
+
+fn skip_rollback_protection() -> Result<(), RebootReason> {
+    info!("Skipping rollback protection");
+    Ok(())
+}
+
+/// Performs RBP using instance.img where updates require clearing old entries, causing new CDIs.
+fn perform_legacy_rollback_protection(
+    dice_inputs: &PartialInputs,
+    pci_root: &mut PciRoot,
+    cdi_seal: &[u8],
+    instance_hash: Option<Hidden>,
+) -> Result<(bool, Hidden, bool), RebootReason> {
+    info!("Fallback to instance.img based rollback checks");
+    let (recorded_entry, mut instance_img, header_index) = get_recorded_entry(pci_root, cdi_seal)
+        .map_err(|e| {
+        error!("Failed to get entry from instance.img: {e}");
+        RebootReason::InternalError
+    })?;
+    let (new_instance, salt) = if let Some(entry) = recorded_entry {
+        check_dice_measurements_match_entry(dice_inputs, &entry)?;
+        let salt = instance_hash.unwrap_or(entry.salt);
+        (false, salt)
+    } else {
+        // New instance!
+        let salt = instance_hash.map_or_else(rand::random_array, Ok).map_err(|e| {
+            error!("Failed to generated instance.img salt: {e}");
+            RebootReason::InternalError
+        })?;
+
+        let entry = EntryBody::new(dice_inputs, &salt);
+        record_instance_entry(&entry, cdi_seal, &mut instance_img, header_index).map_err(|e| {
+            error!("Failed to get recorded entry in instance.img: {e}");
+            RebootReason::InternalError
+        })?;
+        (true, salt)
     };
-
-    Ok((new_instance, salt, defer_rollback_protection))
+    Ok((new_instance, salt, false))
 }
 
 fn check_dice_measurements_match_entry(
@@ -138,7 +157,7 @@
 fn should_defer_rollback_protection(fdt: &Fdt) -> Result<bool, RebootReason> {
     let node = avf_untrusted_node(fdt)?;
     let defer_rbp = node
-        .getprop(cstr!("defer-rollback-protection"))
+        .getprop(c"defer-rollback-protection")
         .map_err(|e| {
             error!("Failed to get defer-rollback-protection property in DT: {e}");
             RebootReason::InvalidFdt
@@ -148,7 +167,7 @@
 }
 
 fn avf_untrusted_node(fdt: &Fdt) -> Result<FdtNode, RebootReason> {
-    let node = fdt.node(cstr!("/avf/untrusted")).map_err(|e| {
+    let node = fdt.node(c"/avf/untrusted").map_err(|e| {
         error!("Failed to get /avf/untrusted node: {e}");
         RebootReason::InvalidFdt
     })?;
diff --git a/guest/rialto/Android.bp b/guest/rialto/Android.bp
index a525168..35ede7a 100644
--- a/guest/rialto/Android.bp
+++ b/guest/rialto/Android.bp
@@ -12,7 +12,6 @@
         "libbssl_avf_nostd",
         "libciborium_io_nostd",
         "libciborium_nostd",
-        "libcstr",
         "libdiced_open_dice_nostd",
         "libhypervisor_backends",
         "liblibfdt_nostd",
diff --git a/guest/rialto/src/fdt.rs b/guest/rialto/src/fdt.rs
index e97a262..06879d0 100644
--- a/guest/rialto/src/fdt.rs
+++ b/guest/rialto/src/fdt.rs
@@ -15,24 +15,23 @@
 //! High-level FDT functions.
 
 use core::ops::Range;
-use cstr::cstr;
 use libfdt::{Fdt, FdtError};
 
 /// Reads the DICE data range from the given `fdt`.
 pub fn read_dice_range_from(fdt: &Fdt) -> libfdt::Result<Range<usize>> {
-    let node = fdt.node(cstr!("/reserved-memory"))?.ok_or(FdtError::NotFound)?;
-    let node = node.next_compatible(cstr!("google,open-dice"))?.ok_or(FdtError::NotFound)?;
+    let node = fdt.node(c"/reserved-memory")?.ok_or(FdtError::NotFound)?;
+    let node = node.next_compatible(c"google,open-dice")?.ok_or(FdtError::NotFound)?;
     node.first_reg()?.try_into()
 }
 
 pub(crate) fn read_vendor_hashtree_root_digest(fdt: &Fdt) -> libfdt::Result<Option<&[u8]>> {
-    let node = fdt.node(cstr!("/avf"))?.ok_or(FdtError::NotFound)?;
-    node.getprop(cstr!("vendor_hashtree_descriptor_root_digest"))
+    let node = fdt.node(c"/avf")?.ok_or(FdtError::NotFound)?;
+    node.getprop(c"vendor_hashtree_descriptor_root_digest")
 }
 
 pub(crate) fn read_is_strict_boot(fdt: &Fdt) -> libfdt::Result<bool> {
     match fdt.chosen()? {
-        Some(node) => Ok(node.getprop(cstr!("avf,strict-boot"))?.is_some()),
+        Some(node) => Ok(node.getprop(c"avf,strict-boot")?.is_some()),
         None => Ok(false),
     }
 }
diff --git a/guest/shutdown_runner/.cargo/config.toml b/guest/shutdown_runner/.cargo/config.toml
new file mode 100644
index 0000000..a451cda
--- /dev/null
+++ b/guest/shutdown_runner/.cargo/config.toml
@@ -0,0 +1,6 @@
+[target.aarch64-unknown-linux-gnu]
+linker = "aarch64-linux-gnu-gcc"
+rustflags = ["-C", "target-feature=+crt-static"]
+
+[target.x86_64-unknown-linux-gnu]
+rustflags = ["-C", "target-feature=+crt-static"]
diff --git a/guest/shutdown_runner/Cargo.toml b/guest/shutdown_runner/Cargo.toml
index b74e7ee..0b44baa 100644
--- a/guest/shutdown_runner/Cargo.toml
+++ b/guest/shutdown_runner/Cargo.toml
@@ -15,3 +15,10 @@
 
 [build-dependencies]
 tonic-build = "0.12.3"
+
+[package.metadata.deb]
+maintainer = "ferrochrome-dev@google.com"
+copyright = "2024, The Android Open Source Project"
+depends = "$auto"
+maintainer-scripts = "debian/"
+systemd-units = { }
diff --git a/guest/shutdown_runner/debian/service b/guest/shutdown_runner/debian/service
new file mode 100644
index 0000000..d19ff25
--- /dev/null
+++ b/guest/shutdown_runner/debian/service
@@ -0,0 +1,13 @@
+[Unit]
+After=syslog.target
+After=network.target
+After=virtiofs_internal.service
+
+[Service]
+ExecStart=/usr/bin/bash -c '/usr/bin/shutdown_runner --grpc_port $(cat /mnt/internal/debian_service_port)'
+Type=simple
+User=root
+Group=root
+
+[Install]
+WantedBy=multi-user.target
diff --git a/guest/vmbase_example/Android.bp b/guest/vmbase_example/Android.bp
index 09bd77c..ab21191 100644
--- a/guest/vmbase_example/Android.bp
+++ b/guest/vmbase_example/Android.bp
@@ -9,7 +9,6 @@
     srcs: ["src/main.rs"],
     rustlibs: [
         "libaarch64_paging",
-        "libcstr",
         "libdiced_open_dice_nostd",
         "liblibfdt_nostd",
         "liblog_rust_nostd",
diff --git a/guest/vmbase_example/src/main.rs b/guest/vmbase_example/src/main.rs
index 4c5e880..f5b41bd 100644
--- a/guest/vmbase_example/src/main.rs
+++ b/guest/vmbase_example/src/main.rs
@@ -27,7 +27,6 @@
 use crate::pci::check_pci;
 use alloc::{vec, vec::Vec};
 use core::ptr::addr_of_mut;
-use cstr::cstr;
 use libfdt::Fdt;
 use log::{debug, error, info, trace, warn, LevelFilter};
 use vmbase::{
@@ -147,7 +146,7 @@
         info!("memory @ {reg:#x?}");
     }
 
-    let compatible = cstr!("ns16550a");
+    let compatible = c"ns16550a";
 
     for c in reader.compatible_nodes(compatible).unwrap() {
         let reg = c.reg().unwrap().unwrap().next().unwrap();
@@ -159,17 +158,17 @@
     writer.unpack().unwrap();
     info!("FDT successfully unpacked.");
 
-    let path = cstr!("/memory");
+    let path = c"/memory";
     let node = writer.node_mut(path).unwrap().unwrap();
-    let name = cstr!("child");
+    let name = c"child";
     let mut child = node.add_subnode(name).unwrap();
     info!("Created subnode '{}/{}'.", path.to_str().unwrap(), name.to_str().unwrap());
 
-    let name = cstr!("str-property");
+    let name = c"str-property";
     child.appendprop(name, b"property-value\0").unwrap();
     info!("Appended property '{}'.", name.to_str().unwrap());
 
-    let name = cstr!("pair-property");
+    let name = c"pair-property";
     let addr = 0x0123_4567u64;
     let size = 0x89ab_cdefu64;
     child.appendprop_addrrange(name, addr, size).unwrap();
diff --git a/libs/cstr/Android.bp b/libs/cstr/Android.bp
deleted file mode 100644
index 4ea87df..0000000
--- a/libs/cstr/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-rust_library_rlib {
-    name: "libcstr",
-    crate_name: "cstr",
-    defaults: ["avf_build_flags_rust"],
-    srcs: ["src/lib.rs"],
-    edition: "2021",
-    host_supported: true,
-    prefer_rlib: true,
-    target: {
-        android: {
-            no_stdlibs: true,
-            stdlibs: [
-                "libcompiler_builtins.rust_sysroot",
-                "libcore.rust_sysroot",
-            ],
-        },
-    },
-    apex_available: [
-        "//apex_available:platform",
-        "//apex_available:anyapex",
-    ],
-}
-
-rust_test {
-    name: "libcstr.tests",
-    crate_name: "libcstr_test",
-    defaults: ["avf_build_flags_rust"],
-    srcs: ["src/lib.rs"],
-    test_suites: ["general-tests"],
-    prefer_rlib: true,
-    rustlibs: ["libcstr"],
-}
diff --git a/libs/cstr/src/lib.rs b/libs/cstr/src/lib.rs
deleted file mode 100644
index ddf20fc..0000000
--- a/libs/cstr/src/lib.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2023, 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.
-
-//! Provide a safe const-compatible no_std macro for readable &'static CStr.
-
-#![no_std]
-
-/// Create &CStr out of &str literal
-#[macro_export]
-macro_rules! cstr {
-    ($str:literal) => {{
-        const S: &str = concat!($str, "\0");
-        const C: &::core::ffi::CStr = match ::core::ffi::CStr::from_bytes_with_nul(S.as_bytes()) {
-            Ok(v) => v,
-            Err(_) => panic!("string contains interior NUL"),
-        };
-        C
-    }};
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use std::ffi::CString;
-
-    #[test]
-    fn valid_input_string() {
-        let expected = CString::new("aaa").unwrap();
-        assert_eq!(cstr!("aaa"), expected.as_c_str());
-    }
-
-    #[test]
-    fn valid_empty_string() {
-        let expected = CString::new("").unwrap();
-        assert_eq!(cstr!(""), expected.as_c_str());
-    }
-
-    // As cstr!() panics at compile time, tests covering invalid inputs fail to compile!
-}
diff --git a/libs/devicemapper/src/loopdevice.rs b/libs/devicemapper/src/loopdevice.rs
index 113a946..130c1c4 100644
--- a/libs/devicemapper/src/loopdevice.rs
+++ b/libs/devicemapper/src/loopdevice.rs
@@ -159,6 +159,7 @@
 #[cfg(test)]
 mod tests {
     use super::*;
+    use rdroidtest::rdroidtest;
     use std::fs;
     use std::path::Path;
 
@@ -178,7 +179,7 @@
         "0" == fs::read_to_string(ro).unwrap().trim()
     }
 
-    #[test]
+    #[rdroidtest]
     fn attach_loop_device_with_dio() {
         let a_dir = tempfile::TempDir::new().unwrap();
         let a_file = a_dir.path().join("test");
@@ -191,7 +192,7 @@
         assert!(is_direct_io(&dev));
     }
 
-    #[test]
+    #[rdroidtest]
     fn attach_loop_device_without_dio() {
         let a_dir = tempfile::TempDir::new().unwrap();
         let a_file = a_dir.path().join("test");
@@ -204,7 +205,7 @@
         assert!(!is_direct_io(&dev));
     }
 
-    #[test]
+    #[rdroidtest]
     fn attach_loop_device_with_dio_writable() {
         let a_dir = tempfile::TempDir::new().unwrap();
         let a_file = a_dir.path().join("test");
diff --git a/libs/dice/open_dice/Android.bp b/libs/dice/open_dice/Android.bp
index f799fb1..1870ab6 100644
--- a/libs/dice/open_dice/Android.bp
+++ b/libs/dice/open_dice/Android.bp
@@ -128,7 +128,7 @@
 
 rust_defaults {
     name: "libopen_dice_cbor_bindgen.rust_defaults",
-    wrapper_src: "bindgen/dice.h",
+    wrapper_src: "bindgen/dice/dice.h",
     crate_name: "open_dice_cbor_bindgen",
     source_stem: "bindings",
     bindgen_flags: [
@@ -184,7 +184,7 @@
 
 rust_defaults {
     name: "libopen_dice_android_bindgen.rust_defaults",
-    wrapper_src: "bindgen/android.h",
+    wrapper_src: "bindgen/android/android.h",
     crate_name: "open_dice_android_bindgen",
     source_stem: "bindings",
     bindgen_flags: [
@@ -264,3 +264,9 @@
     clippy_lints: "none",
     lints: "none",
 }
+
+dirgroup {
+    name: "trusty_dirgroup_packages_modules_virtualization_libs_open_dice",
+    visibility: ["//trusty/vendor/google/aosp/scripts"],
+    dirs: ["."],
+}
diff --git a/libs/dice/open_dice/bindgen/android.h b/libs/dice/open_dice/bindgen/android/android.h
similarity index 100%
rename from libs/dice/open_dice/bindgen/android.h
rename to libs/dice/open_dice/bindgen/android/android.h
diff --git a/libs/dice/open_dice/bindgen/android/lib.rs b/libs/dice/open_dice/bindgen/android/lib.rs
new file mode 100644
index 0000000..7c300de
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/android/lib.rs
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+// Get the bindgen definitions.
+// The trusty build system doesn't have support for packaging generated
+// bindgen sources as a crate automatically. In the Android tree, this
+// entire file is not used.
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(unused)]
+
+include!(env!("BINDGEN_INC_FILE"));
diff --git a/libs/dice/open_dice/bindgen/android/rules.mk b/libs/dice/open_dice/bindgen/android/rules.mk
new file mode 100644
index 0000000..200ec52
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/android/rules.mk
@@ -0,0 +1,54 @@
+# 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)/lib.rs
+
+MODULE_CRATE_NAME := open_dice_android_bindgen
+
+MODULE_LIBRARY_DEPS += \
+	external/open-dice \
+	$(LOCAL_DIR)/../dice \
+	trusty/user/base/lib/trusty-sys \
+
+MODULE_BINDGEN_ALLOW_FUNCTIONS := \
+	DiceAndroidFormatConfigDescriptor \
+	DiceAndroidMainFlow \
+	DiceAndroidHandoverParse \
+
+MODULE_BINDGEN_ALLOW_VARS := \
+	DICE_ANDROID_CONFIG_.* \
+
+# Prevent DiceInputValues from being generated a second time and
+# import it instead from open_dice_cbor_bindgen.
+MODULE_BINDGEN_FLAGS += \
+	--blocklist-type="DiceInputValues_" \
+	--blocklist-type="DiceInputValues" \
+	--raw-line \
+	"pub use open_dice_cbor_bindgen::DiceInputValues;" \
+
+# Prevent DiceResult from being generated a second time and
+# import it instead from open_dice_cbor_bindgen.
+MODULE_BINDGEN_FLAGS += \
+	--blocklist-type="DiceResult" \
+	--raw-line \
+	"pub use open_dice_cbor_bindgen::DiceResult;" \
+
+MODULE_BINDGEN_SRC_HEADER := $(LOCAL_DIR)/android.h
+
+include make/library.mk
diff --git a/libs/dice/open_dice/bindgen/dice.h b/libs/dice/open_dice/bindgen/dice/dice.h
similarity index 100%
rename from libs/dice/open_dice/bindgen/dice.h
rename to libs/dice/open_dice/bindgen/dice/dice.h
diff --git a/libs/dice/open_dice/bindgen/dice/lib.rs b/libs/dice/open_dice/bindgen/dice/lib.rs
new file mode 100644
index 0000000..ed2fd23
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/dice/lib.rs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+// Get the bindgen definitions.
+// The trusty build system doesn't have support for packaging generated
+// bindgen sources as a crate automatically. In the Android tree, this
+// entire file is not used.
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(unused)]
+
+include!(env!("BINDGEN_INC_FILE"));
diff --git a/libs/dice/open_dice/bindgen/dice/rules.mk b/libs/dice/open_dice/bindgen/dice/rules.mk
new file mode 100644
index 0000000..0ea5c7c
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/dice/rules.mk
@@ -0,0 +1,56 @@
+# 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)/lib.rs
+
+MODULE_CRATE_NAME := open_dice_cbor_bindgen
+
+MODULE_LIBRARY_DEPS += \
+	external/open-dice \
+	trusty/user/base/lib/trusty-sys \
+
+MODULE_BINDGEN_FLAGS += \
+	--rustified-enum DiceConfigType \
+	--rustified-enum DiceMode \
+	--rustified-enum DiceResult \
+	--rustified-enum DicePrincipal \
+
+MODULE_BINDGEN_ALLOW_FUNCTIONS := \
+	DiceDeriveCdiPrivateKeySeed \
+	DiceDeriveCdiCertificateId \
+	DiceMainFlow \
+	DiceHash \
+	DiceKdf \
+	DiceKeypairFromSeed \
+	DiceSign \
+	DiceVerify \
+	DiceGenerateCertificate \
+
+MODULE_BINDGEN_ALLOW_VARS := \
+	DICE_CDI_SIZE \
+	DICE_HASH_SIZE \
+	DICE_HIDDEN_SIZE \
+	DICE_INLINE_CONFIG_SIZE \
+	DICE_PRIVATE_KEY_SEED_SIZE \
+	DICE_ID_SIZE \
+	DICE_PRIVATE_KEY_BUFFER_SIZE \
+
+MODULE_BINDGEN_SRC_HEADER := $(LOCAL_DIR)/dice.h
+
+include make/library.mk
diff --git a/libs/cstr/rules.mk b/libs/dice/open_dice/rules.mk
similarity index 75%
rename from libs/cstr/rules.mk
rename to libs/dice/open_dice/rules.mk
index 2309c30..d84468d 100644
--- a/libs/cstr/rules.mk
+++ b/libs/dice/open_dice/rules.mk
@@ -17,12 +17,14 @@
 
 MODULE := $(LOCAL_DIR)
 
-SRC_DIR := packages/modules/Virtualization/libs/cstr
+MODULE_SRCS := $(LOCAL_DIR)/src/lib.rs
 
-MODULE_SRCS := $(SRC_DIR)/src/lib.rs
+MODULE_CRATE_NAME := diced_open_dice
 
-MODULE_CRATE_NAME := cstr
-
-MODULE_RUST_EDITION := 2021
+MODULE_LIBRARY_DEPS += \
+	$(call FIND_CRATE,coset) \
+	$(call FIND_CRATE,zeroize) \
+	$(LOCAL_DIR)/bindgen/android \
+	$(LOCAL_DIR)/bindgen/dice \
 
 include make/library.mk
diff --git a/libs/dice/open_dice/src/bcc.rs b/libs/dice/open_dice/src/bcc.rs
index fabd7c7..a3ddd76 100644
--- a/libs/dice/open_dice/src/bcc.rs
+++ b/libs/dice/open_dice/src/bcc.rs
@@ -41,7 +41,7 @@
 }
 
 /// Formats a configuration descriptor following the Android Profile for DICE specification.
-/// See https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md.
+/// See <https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md>.
 pub fn bcc_format_config_descriptor(values: &DiceConfigValues, buffer: &mut [u8]) -> Result<usize> {
     let mut configs = 0;
 
diff --git a/libs/dice/open_dice/tests/api_test.rs b/libs/dice/open_dice/tests/api_test.rs
index a47265b..d3a91ff 100644
--- a/libs/dice/open_dice/tests/api_test.rs
+++ b/libs/dice/open_dice/tests/api_test.rs
@@ -14,94 +14,108 @@
  * limitations under the License.
  */
 
-use diced_open_dice::{
-    derive_cdi_certificate_id, derive_cdi_private_key_seed, hash, kdf, keypair_from_seed, sign,
-    verify, CDI_SIZE, HASH_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
-};
+#[cfg(test)]
+mod tests {
+    use diced_open_dice::{
+        derive_cdi_certificate_id, derive_cdi_private_key_seed, hash, kdf, keypair_from_seed, sign,
+        verify, CDI_SIZE, HASH_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
+    };
 
-#[test]
-fn hash_succeeds() {
-    const EXPECTED_HASH: [u8; HASH_SIZE] = [
-        0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02, 0xf2,
-        0xb4, 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, 0x9b, 0xcd, 0x3c, 0xa8, 0x6d, 0x4c,
-        0xd8, 0x6f, 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, 0x70, 0xda, 0x34, 0x25, 0x5b,
-        0x45, 0xb0, 0xcf, 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d, 0xc5, 0x54, 0x2e, 0x93,
-        0xae, 0x9c, 0xd7, 0x6f,
+    // This test initialization is only required for the trusty test harness.
+    #[cfg(feature = "trusty")]
+    test::init!();
+
+    #[test]
+    fn hash_succeeds() {
+        const EXPECTED_HASH: [u8; HASH_SIZE] = [
+            0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02,
+            0xf2, 0xb4, 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, 0x9b, 0xcd, 0x3c, 0xa8,
+            0x6d, 0x4c, 0xd8, 0x6f, 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, 0x70, 0xda,
+            0x34, 0x25, 0x5b, 0x45, 0xb0, 0xcf, 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d,
+            0xc5, 0x54, 0x2e, 0x93, 0xae, 0x9c, 0xd7, 0x6f,
+        ];
+        assert_eq!(EXPECTED_HASH, hash(b"hello world").expect("hash failed"));
+    }
+
+    #[test]
+    fn kdf_succeeds() {
+        let mut derived_key = [0u8; PRIVATE_KEY_SEED_SIZE];
+        kdf(b"myInitialKeyMaterial", b"mySalt", b"myInfo", &mut derived_key).unwrap();
+        const EXPECTED_DERIVED_KEY: [u8; PRIVATE_KEY_SEED_SIZE] = [
+            0x91, 0x9b, 0x8d, 0x29, 0xc4, 0x1b, 0x93, 0xd7, 0xeb, 0x09, 0xfa, 0xd7, 0xc9, 0x87,
+            0xb0, 0xd1, 0xcc, 0x26, 0xef, 0x07, 0x83, 0x42, 0xcf, 0xa3, 0x45, 0x0a, 0x57, 0xe9,
+            0x19, 0x86, 0xef, 0x48,
+        ];
+        assert_eq!(EXPECTED_DERIVED_KEY, derived_key);
+    }
+
+    #[test]
+    fn derive_cdi_certificate_id_succeeds() {
+        const EXPECTED_ID: [u8; ID_SIZE] = [
+            0x7a, 0x36, 0x45, 0x2c, 0x02, 0xf6, 0x2b, 0xec, 0xf9, 0x80, 0x06, 0x75, 0x87, 0xa5,
+            0xc1, 0x44, 0x0c, 0xd3, 0xc0, 0x6d,
+        ];
+        assert_eq!(EXPECTED_ID, derive_cdi_certificate_id(b"MyPubKey").unwrap());
+    }
+
+    const EXPECTED_SEED: &[u8] = &[
+        0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
+        0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
+        0x3a, 0x08, 0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28,
+        0xd6, 0x06, 0xa7, 0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41,
+        0x94, 0xd8, 0x8c, 0xa8,
     ];
-    assert_eq!(EXPECTED_HASH, hash(b"hello world").expect("hash failed"));
-}
 
-#[test]
-fn kdf_succeeds() {
-    let mut derived_key = [0u8; PRIVATE_KEY_SEED_SIZE];
-    kdf(b"myInitialKeyMaterial", b"mySalt", b"myInfo", &mut derived_key).unwrap();
-    const EXPECTED_DERIVED_KEY: [u8; PRIVATE_KEY_SEED_SIZE] = [
-        0x91, 0x9b, 0x8d, 0x29, 0xc4, 0x1b, 0x93, 0xd7, 0xeb, 0x09, 0xfa, 0xd7, 0xc9, 0x87, 0xb0,
-        0xd1, 0xcc, 0x26, 0xef, 0x07, 0x83, 0x42, 0xcf, 0xa3, 0x45, 0x0a, 0x57, 0xe9, 0x19, 0x86,
-        0xef, 0x48,
+    const EXPECTED_CDI_ATTEST: &[u8] = &[
+        0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
+        0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
+        0x3a, 0x08,
     ];
-    assert_eq!(EXPECTED_DERIVED_KEY, derived_key);
-}
 
-#[test]
-fn derive_cdi_certificate_id_succeeds() {
-    const EXPECTED_ID: [u8; ID_SIZE] = [
-        0x7a, 0x36, 0x45, 0x2c, 0x02, 0xf6, 0x2b, 0xec, 0xf9, 0x80, 0x06, 0x75, 0x87, 0xa5, 0xc1,
-        0x44, 0x0c, 0xd3, 0xc0, 0x6d,
+    const EXPECTED_CDI_PRIVATE_KEY_SEED: &[u8] = &[
+        0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
+        0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
+        0x02, 0x6e,
     ];
-    assert_eq!(EXPECTED_ID, derive_cdi_certificate_id(b"MyPubKey").unwrap());
-}
 
-const EXPECTED_SEED: &[u8] = &[
-    0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba, 0xaa,
-    0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5, 0x3a, 0x08,
-    0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28, 0xd6, 0x06, 0xa7,
-    0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41, 0x94, 0xd8, 0x8c, 0xa8,
-];
+    const EXPECTED_PUB_KEY: &[u8] = &[
+        0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23,
+        0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61,
+        0x06, 0x37,
+    ];
+    const EXPECTED_PRIV_KEY: &[u8] = &[
+        0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
+        0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
+        0x02, 0x6e, 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b,
+        0xfc, 0x23, 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52,
+        0xf1, 0x61, 0x06, 0x37,
+    ];
 
-const EXPECTED_CDI_ATTEST: &[u8] = &[
-    0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba, 0xaa,
-    0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5, 0x3a, 0x08,
-];
+    const EXPECTED_SIGNATURE: &[u8] = &[
+        0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2,
+        0x32, 0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29,
+        0x3c, 0x26, 0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd,
+        0x62, 0x8d, 0xf6, 0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc,
+        0xbb, 0xab, 0x4a, 0x0e,
+    ];
 
-const EXPECTED_CDI_PRIVATE_KEY_SEED: &[u8] = &[
-    0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe, 0x0d,
-    0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72, 0x02, 0x6e,
-];
-
-const EXPECTED_PUB_KEY: &[u8] = &[
-    0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23, 0xc9,
-    0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61, 0x06, 0x37,
-];
-const EXPECTED_PRIV_KEY: &[u8] = &[
-    0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe, 0x0d,
-    0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72, 0x02, 0x6e,
-    0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23, 0xc9,
-    0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61, 0x06, 0x37,
-];
-
-const EXPECTED_SIGNATURE: &[u8] = &[
-    0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2, 0x32,
-    0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29, 0x3c, 0x26,
-    0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd, 0x62, 0x8d, 0xf6,
-    0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc, 0xbb, 0xab, 0x4a, 0x0e,
-];
-
-#[test]
-fn hash_derive_sign_verify() {
-    let seed = hash(b"MySeedString").unwrap();
-    assert_eq!(seed, EXPECTED_SEED);
-    let cdi_attest = &seed[..CDI_SIZE];
-    assert_eq!(cdi_attest, EXPECTED_CDI_ATTEST);
-    let cdi_private_key_seed = derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
-    assert_eq!(cdi_private_key_seed.as_array(), EXPECTED_CDI_PRIVATE_KEY_SEED);
-    let (pub_key, priv_key) = keypair_from_seed(cdi_private_key_seed.as_array()).unwrap();
-    assert_eq!(&pub_key, EXPECTED_PUB_KEY);
-    assert_eq!(priv_key.as_array(), EXPECTED_PRIV_KEY);
-    let mut signature = sign(b"MyMessage", priv_key.as_array()).unwrap();
-    assert_eq!(&signature, EXPECTED_SIGNATURE);
-    assert!(verify(b"MyMessage", &signature, &pub_key).is_ok());
-    assert!(verify(b"MyMessage_fail", &signature, &pub_key).is_err());
-    signature[0] += 1;
-    assert!(verify(b"MyMessage", &signature, &pub_key).is_err());
+    #[test]
+    fn hash_derive_sign_verify() {
+        let seed = hash(b"MySeedString").unwrap();
+        assert_eq!(seed, EXPECTED_SEED);
+        let cdi_attest = &seed[..CDI_SIZE];
+        assert_eq!(cdi_attest, EXPECTED_CDI_ATTEST);
+        let cdi_private_key_seed =
+            derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
+        assert_eq!(cdi_private_key_seed.as_array(), EXPECTED_CDI_PRIVATE_KEY_SEED);
+        let (pub_key, priv_key) = keypair_from_seed(cdi_private_key_seed.as_array()).unwrap();
+        assert_eq!(&pub_key, EXPECTED_PUB_KEY);
+        assert_eq!(priv_key.as_array(), EXPECTED_PRIV_KEY);
+        let mut signature = sign(b"MyMessage", priv_key.as_array()).unwrap();
+        assert_eq!(&signature, EXPECTED_SIGNATURE);
+        assert!(verify(b"MyMessage", &signature, &pub_key).is_ok());
+        assert!(verify(b"MyMessage_fail", &signature, &pub_key).is_err());
+        signature[0] += 1;
+        assert!(verify(b"MyMessage", &signature, &pub_key).is_err());
+    }
 }
diff --git a/libs/dice/open_dice/tests/manifest.json b/libs/dice/open_dice/tests/manifest.json
new file mode 100644
index 0000000..28db874
--- /dev/null
+++ b/libs/dice/open_dice/tests/manifest.json
@@ -0,0 +1,9 @@
+{
+    "app_name": "diced_open_dice_tests",
+    "uuid": "0b772481-7c24-4b9b-9d7c-441ac10d969b",
+    "min_heap": 32768,
+    "min_stack": 32768,
+    "mgmt_flags": {
+        "non_critical_app": true
+    }
+}
diff --git a/libs/cstr/rules.mk b/libs/dice/open_dice/tests/rules.mk
similarity index 68%
copy from libs/cstr/rules.mk
copy to libs/dice/open_dice/tests/rules.mk
index 2309c30..a9d332c 100644
--- a/libs/cstr/rules.mk
+++ b/libs/dice/open_dice/tests/rules.mk
@@ -17,12 +17,19 @@
 
 MODULE := $(LOCAL_DIR)
 
-SRC_DIR := packages/modules/Virtualization/libs/cstr
+MODULE_SRCS := $(LOCAL_DIR)/api_test.rs
 
-MODULE_SRCS := $(SRC_DIR)/src/lib.rs
+MODULE_CRATE_NAME := diced_open_dice_tests
 
-MODULE_CRATE_NAME := cstr
+MODULE_LIBRARY_DEPS += \
+	packages/modules/Virtualization/libs/dice/open_dice \
 
-MODULE_RUST_EDITION := 2021
+MODULE_RUST_TESTS := true
+
+# Enables trusty test initialization
+MODULE_RUSTFLAGS += \
+	--cfg 'feature="trusty"' \
+
+MANIFEST := $(LOCAL_DIR)/manifest.json
 
 include make/library.mk
diff --git a/libs/dice/sample_inputs/src/sample_inputs.rs b/libs/dice/sample_inputs/src/sample_inputs.rs
index 54f551b..c323bc4 100644
--- a/libs/dice/sample_inputs/src/sample_inputs.rs
+++ b/libs/dice/sample_inputs/src/sample_inputs.rs
@@ -118,6 +118,7 @@
         component_name: Some(CStr::from_bytes_with_nul(b"ABL\0").unwrap()),
         component_version: Some(1),
         resettable: true,
+        security_version: Some(10),
         ..Default::default()
     };
     let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
@@ -150,6 +151,7 @@
         component_name: Some(CStr::from_bytes_with_nul(b"AVB\0").unwrap()),
         component_version: Some(1),
         resettable: true,
+        security_version: Some(11),
         ..Default::default()
     };
     let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
@@ -174,6 +176,7 @@
         component_name: Some(CStr::from_bytes_with_nul(b"Android\0").unwrap()),
         component_version: Some(12),
         resettable: true,
+        security_version: Some(12),
         ..Default::default()
     };
     let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
diff --git a/libs/dice/sample_inputs/tests/api_test.rs b/libs/dice/sample_inputs/tests/api_test.rs
index c627824..566d3c7 100644
--- a/libs/dice/sample_inputs/tests/api_test.rs
+++ b/libs/dice/sample_inputs/tests/api_test.rs
@@ -22,8 +22,8 @@
 use hwtrust::{dice, session::Session};
 
 const EXPECTED_SAMPLE_CDI_ATTEST: &[u8] = &[
-    0x3e, 0x57, 0x65, 0x5d, 0x48, 0x02, 0xbd, 0x5c, 0x66, 0xcc, 0x1f, 0x0f, 0xbe, 0x5e, 0x32, 0xb6,
-    0x9e, 0x3d, 0x04, 0xaf, 0x00, 0x15, 0xbc, 0xdd, 0x1f, 0xbc, 0x59, 0xe4, 0xc3, 0x87, 0x95, 0x5e,
+    0xb2, 0x13, 0xde, 0x86, 0xf7, 0x40, 0x7b, 0xd5, 0x20, 0x21, 0x74, 0x4e, 0x75, 0x78, 0x1a, 0xcb,
+    0x22, 0x57, 0x1c, 0x32, 0xa4, 0x1e, 0xc9, 0x23, 0x73, 0x5b, 0x9c, 0x6b, 0x5f, 0x6b, 0x2d, 0xc0,
 ];
 
 const EXPECTED_SAMPLE_CDI_SEAL: &[u8] = &[
@@ -35,95 +35,99 @@
     0x84, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x3e, 0x85,
     0xe5, 0x72, 0x75, 0x55, 0xe5, 0x1e, 0xe7, 0xf3, 0x35, 0x94, 0x8e, 0xbb, 0xbd, 0x74, 0x1e, 0x1d,
     0xca, 0x49, 0x9c, 0x97, 0x39, 0x77, 0x06, 0xd3, 0xc8, 0x6e, 0x8b, 0xd7, 0x33, 0xf9, 0x84, 0x43,
-    0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9, 0x01, 0x78, 0x28, 0x34, 0x32, 0x64, 0x38, 0x38,
+    0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0xa1, 0xaa, 0x01, 0x78, 0x28, 0x34, 0x32, 0x64, 0x38, 0x38,
     0x36, 0x34, 0x66, 0x39, 0x37, 0x62, 0x36, 0x35, 0x34, 0x37, 0x61, 0x35, 0x30, 0x63, 0x31, 0x65,
     0x30, 0x61, 0x37, 0x34, 0x39, 0x66, 0x38, 0x65, 0x66, 0x38, 0x62, 0x38, 0x31, 0x65, 0x63, 0x36,
-    0x32, 0x61, 0x66, 0x02, 0x78, 0x28, 0x31, 0x66, 0x36, 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35,
-    0x32, 0x66, 0x32, 0x39, 0x65, 0x39, 0x33, 0x66, 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65,
-    0x33, 0x32, 0x63, 0x64, 0x38, 0x31, 0x64, 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x3a, 0x00,
+    0x32, 0x61, 0x66, 0x02, 0x78, 0x28, 0x34, 0x61, 0x61, 0x66, 0x61, 0x38, 0x30, 0x62, 0x30, 0x62,
+    0x30, 0x63, 0x31, 0x33, 0x34, 0x64, 0x31, 0x36, 0x65, 0x36, 0x30, 0x35, 0x36, 0x66, 0x30, 0x35,
+    0x35, 0x32, 0x62, 0x65, 0x65, 0x33, 0x38, 0x61, 0x37, 0x37, 0x30, 0x65, 0x35, 0x62, 0x3a, 0x00,
     0x47, 0x44, 0x50, 0x58, 0x40, 0x16, 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38,
     0xc3, 0x64, 0x38, 0x63, 0x26, 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34,
     0x4c, 0x6d, 0xa2, 0xbe, 0x25, 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2,
     0xb3, 0x91, 0x4d, 0xd3, 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba,
-    0x30, 0xf7, 0x15, 0x98, 0x14, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a, 0x00, 0x01, 0x11,
-    0x71, 0x63, 0x41, 0x42, 0x4c, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01, 0x11, 0x73,
-    0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x47, 0xae, 0x42, 0x27, 0x4c, 0xcb, 0x65, 0x4d,
-    0xee, 0x74, 0x2d, 0x05, 0x78, 0x2a, 0x08, 0x2a, 0xa5, 0xf0, 0xcf, 0xea, 0x3e, 0x60, 0xee, 0x97,
-    0x11, 0x4b, 0x5b, 0xe6, 0x05, 0x0c, 0xe8, 0x90, 0xf5, 0x22, 0xc4, 0xc6, 0x67, 0x7a, 0x22, 0x27,
-    0x17, 0xb3, 0x79, 0xcc, 0x37, 0x64, 0x5e, 0x19, 0x4f, 0x96, 0x37, 0x67, 0x3c, 0xd0, 0xc5, 0xed,
-    0x0f, 0xdd, 0xe7, 0x2e, 0x4f, 0x70, 0x97, 0x30, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xf9,
-    0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c, 0xe7, 0x6b,
-    0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf, 0xfb,
-    0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd, 0xc1,
-    0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d, 0x3a,
-    0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01,
-    0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0xb1, 0x02, 0xcc, 0x2c, 0xb2, 0x6a,
-    0x3b, 0xe9, 0xc1, 0xd3, 0x95, 0x10, 0xa0, 0xe1, 0xff, 0x51, 0xde, 0x57, 0xd5, 0x65, 0x28, 0xfd,
-    0x7f, 0xeb, 0xd4, 0xca, 0x15, 0xf3, 0xca, 0xdf, 0x37, 0x88, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41,
-    0x20, 0x58, 0x40, 0x58, 0xd8, 0x03, 0x24, 0x53, 0x60, 0x57, 0xa9, 0x09, 0xfa, 0xab, 0xdc, 0x57,
-    0x1e, 0xf0, 0xe5, 0x1e, 0x51, 0x6f, 0x9e, 0xa3, 0x42, 0xe6, 0x6a, 0x8c, 0xaa, 0xad, 0x08, 0x48,
-    0xde, 0x7f, 0x4f, 0x6e, 0x2f, 0x7f, 0x39, 0x6c, 0xa1, 0xf8, 0x42, 0x71, 0xfe, 0x17, 0x3d, 0xca,
-    0x31, 0x83, 0x92, 0xed, 0xbb, 0x40, 0xb8, 0x10, 0xe0, 0xf2, 0x5a, 0x99, 0x53, 0x38, 0x46, 0x33,
-    0x97, 0x78, 0x05, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9, 0x01, 0x78, 0x28,
-    0x31, 0x66, 0x36, 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66, 0x32, 0x39, 0x65, 0x39,
-    0x33, 0x66, 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33, 0x32, 0x63, 0x64, 0x38, 0x31,
-    0x64, 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x02, 0x78, 0x28, 0x32, 0x35, 0x39, 0x34, 0x38,
-    0x39, 0x65, 0x36, 0x39, 0x37, 0x34, 0x38, 0x37, 0x30, 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66,
-    0x34, 0x34, 0x32, 0x36, 0x37, 0x65, 0x61, 0x34, 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35,
-    0x37, 0x32, 0x35, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa,
-    0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46, 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14,
-    0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf, 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4,
-    0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54,
-    0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56,
-    0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x63, 0x41, 0x56, 0x42, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01,
-    0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x93, 0x17, 0xe1,
-    0x11, 0x27, 0x59, 0xd0, 0xef, 0x75, 0x0b, 0x2b, 0x1c, 0x0f, 0x5f, 0x52, 0xc3, 0x29, 0x23, 0xb5,
-    0x2a, 0xe6, 0x12, 0x72, 0x6f, 0x39, 0x86, 0x65, 0x2d, 0xf2, 0xe4, 0xe7, 0xd0, 0xaf, 0x0e, 0xa7,
-    0x99, 0x16, 0x89, 0x97, 0x21, 0xf7, 0xdc, 0x89, 0xdc, 0xde, 0xbb, 0x94, 0x88, 0x1f, 0xda, 0xe2,
-    0xf3, 0xe0, 0x54, 0xf9, 0x0e, 0x29, 0xb1, 0xbd, 0xe1, 0x0c, 0x0b, 0xd7, 0xf6, 0x3a, 0x00, 0x47,
-    0x44, 0x54, 0x58, 0x40, 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9,
-    0x02, 0x35, 0x2b, 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9,
-    0x35, 0x7d, 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e,
-    0xf6, 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a,
-    0xef, 0xbc, 0x05, 0x98, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57,
-    0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x96,
-    0x6d, 0x96, 0x42, 0xda, 0x64, 0x51, 0xad, 0xfa, 0x00, 0xbc, 0xbc, 0x95, 0x8a, 0xb0, 0xb9, 0x76,
-    0x01, 0xe6, 0xbd, 0xc0, 0x26, 0x79, 0x26, 0xfc, 0x0f, 0x1d, 0x87, 0x65, 0xf1, 0xf3, 0x99, 0x3a,
-    0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0x10, 0x7f, 0x77, 0xad, 0x70, 0xbd, 0x52, 0x81,
-    0x28, 0x8d, 0x24, 0x81, 0xb4, 0x3f, 0x21, 0x68, 0x9f, 0xc3, 0x80, 0x68, 0x86, 0x55, 0xfb, 0x2e,
-    0x6d, 0x96, 0xe1, 0xe1, 0xb7, 0x28, 0x8d, 0x63, 0x85, 0xba, 0x2a, 0x01, 0x33, 0x87, 0x60, 0x63,
-    0xbb, 0x16, 0x3f, 0x2f, 0x3d, 0xf4, 0x2d, 0x48, 0x5b, 0x87, 0xed, 0xda, 0x34, 0xeb, 0x9c, 0x4d,
-    0x14, 0xac, 0x65, 0xf4, 0xfa, 0xef, 0x45, 0x0b, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01,
-    0x8f, 0xa9, 0x01, 0x78, 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36, 0x39, 0x37, 0x34,
-    0x38, 0x37, 0x30, 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34, 0x32, 0x36, 0x37, 0x65,
-    0x61, 0x34, 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37, 0x32, 0x35, 0x02, 0x78, 0x28,
-    0x35, 0x64, 0x34, 0x65, 0x64, 0x37, 0x66, 0x34, 0x31, 0x37, 0x61, 0x39, 0x35, 0x34, 0x61, 0x31,
-    0x38, 0x31, 0x34, 0x30, 0x37, 0x62, 0x35, 0x38, 0x38, 0x35, 0x61, 0x66, 0x64, 0x37, 0x32, 0x61,
-    0x35, 0x62, 0x66, 0x34, 0x30, 0x64, 0x61, 0x36, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00,
+    0x30, 0xf7, 0x15, 0x98, 0x14, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x58, 0x1c, 0xa4, 0x3a, 0x00, 0x01,
+    0x11, 0x71, 0x63, 0x41, 0x42, 0x4c, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01, 0x11,
+    0x73, 0xf6, 0x3a, 0x00, 0x01, 0x11, 0x74, 0x0a, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x27,
+    0xf2, 0x47, 0xaf, 0xcf, 0xd8, 0x6e, 0x5f, 0x68, 0x97, 0xa9, 0x22, 0x07, 0x81, 0xea, 0x56, 0x1f,
+    0x7b, 0x81, 0x51, 0x09, 0x8a, 0x0a, 0xab, 0x96, 0xc4, 0x4c, 0x8f, 0xf5, 0x46, 0xf4, 0xa5, 0x64,
+    0x4b, 0xed, 0x23, 0x5b, 0x9e, 0x36, 0x51, 0x1e, 0xf0, 0x1d, 0xb9, 0xcf, 0xb2, 0x4b, 0xcd, 0x52,
+    0xfa, 0x1a, 0x82, 0x11, 0x3d, 0x78, 0x1c, 0x9e, 0x0f, 0xff, 0x8a, 0x11, 0x6b, 0xdf, 0x7b, 0x3a,
+    0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd,
+    0xe3, 0x97, 0x4a, 0xcb, 0x3c, 0xe7, 0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59,
+    0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf, 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b,
+    0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd, 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b,
+    0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47,
+    0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58,
+    0x20, 0x7f, 0x1d, 0xd1, 0xf8, 0xd3, 0xcb, 0xfe, 0xc6, 0x88, 0xa3, 0xfc, 0xa7, 0xd5, 0x34, 0xc6,
+    0x29, 0x13, 0x57, 0xfa, 0x5d, 0xc9, 0xe2, 0x1b, 0x70, 0x21, 0x48, 0x74, 0x3e, 0xa0, 0x1c, 0xe7,
+    0x31, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x3a, 0x00, 0x47, 0x44, 0x59, 0x6a, 0x61, 0x6e,
+    0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0x21, 0x1f, 0xb5, 0x9b, 0x25, 0xab,
+    0xca, 0x24, 0x58, 0x7f, 0xd1, 0x9f, 0x10, 0x74, 0xbe, 0x8d, 0xbb, 0x46, 0x3e, 0xc2, 0x78, 0x2c,
+    0x28, 0x65, 0xe3, 0xd5, 0xc6, 0x11, 0x50, 0x36, 0x15, 0xfa, 0x43, 0xe5, 0xf7, 0xfd, 0x5c, 0xec,
+    0xb8, 0x96, 0xd7, 0x55, 0x51, 0x1f, 0x8e, 0xc2, 0x0b, 0x4a, 0x12, 0xe7, 0x5c, 0x3e, 0xe5, 0xaf,
+    0x19, 0xe4, 0x15, 0xf3, 0x8a, 0x58, 0x68, 0x25, 0x0e, 0x00, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0,
+    0x59, 0x01, 0xa1, 0xaa, 0x01, 0x78, 0x28, 0x34, 0x61, 0x61, 0x66, 0x61, 0x38, 0x30, 0x62, 0x30,
+    0x62, 0x30, 0x63, 0x31, 0x33, 0x34, 0x64, 0x31, 0x36, 0x65, 0x36, 0x30, 0x35, 0x36, 0x66, 0x30,
+    0x35, 0x35, 0x32, 0x62, 0x65, 0x65, 0x33, 0x38, 0x61, 0x37, 0x37, 0x30, 0x65, 0x35, 0x62, 0x02,
+    0x78, 0x28, 0x31, 0x61, 0x61, 0x32, 0x65, 0x64, 0x33, 0x63, 0x33, 0x61, 0x35, 0x36, 0x62, 0x36,
+    0x63, 0x61, 0x37, 0x35, 0x39, 0x63, 0x35, 0x32, 0x34, 0x65, 0x63, 0x38, 0x38, 0x61, 0x35, 0x37,
+    0x33, 0x30, 0x61, 0x33, 0x38, 0x61, 0x64, 0x31, 0x66, 0x36, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58,
+    0x40, 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46,
+    0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf, 0x2f,
+    0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29, 0x20, 0x49,
+    0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3,
+    0xc7, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x58, 0x1c, 0xa4, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x63, 0x41,
+    0x56, 0x42, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00,
+    0x01, 0x11, 0x74, 0x0b, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x69, 0x3d, 0x73, 0x63, 0x70,
+    0x20, 0x41, 0xc4, 0x2d, 0x04, 0x4a, 0x4c, 0x51, 0xa9, 0x89, 0x97, 0xe4, 0x3a, 0x0f, 0x7b, 0xe2,
+    0x23, 0x5f, 0x39, 0x7e, 0xd8, 0x6f, 0x8b, 0x17, 0x04, 0x16, 0xe1, 0xb2, 0x1b, 0x5a, 0x47, 0x84,
+    0x9c, 0x54, 0x19, 0xa3, 0xb2, 0x70, 0xd3, 0xc9, 0x09, 0xf9, 0xe3, 0x3f, 0x7e, 0x19, 0xff, 0xd7,
+    0xc6, 0xa9, 0x84, 0xf1, 0xcd, 0x44, 0xec, 0x33, 0x7a, 0xa7, 0x9a, 0x3a, 0x00, 0x47, 0x44, 0x54,
+    0x58, 0x40, 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35,
+    0x2b, 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d,
+    0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6, 0x66,
+    0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a, 0xef, 0xbc,
+    0x05, 0x98, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d,
+    0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x02, 0xcc, 0xfb,
+    0xac, 0x73, 0xee, 0xf7, 0x46, 0x04, 0xa2, 0x9e, 0x32, 0xac, 0xa1, 0xf8, 0x7a, 0x08, 0x83, 0xec,
+    0xfb, 0x82, 0x13, 0xce, 0x4a, 0xed, 0x55, 0x52, 0x24, 0x36, 0x67, 0xe8, 0x45, 0x3a, 0x00, 0x47,
+    0x44, 0x58, 0x41, 0x20, 0x3a, 0x00, 0x47, 0x44, 0x59, 0x6a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+    0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0xb8, 0x67, 0x7a, 0x4e, 0x89, 0xe4, 0x73, 0xc3, 0xa4, 0x5d,
+    0x30, 0xea, 0xd4, 0x53, 0x51, 0x15, 0xc2, 0x26, 0x4d, 0xae, 0xeb, 0x94, 0x00, 0x92, 0x9e, 0x05,
+    0x23, 0x8b, 0xde, 0x4b, 0x56, 0x72, 0x33, 0x2c, 0xf4, 0xf7, 0x81, 0x09, 0xce, 0xf4, 0x41, 0x7a,
+    0xa4, 0xc6, 0x4e, 0x3a, 0x0b, 0xb3, 0x5a, 0x70, 0x72, 0x9e, 0x41, 0xe3, 0x25, 0x41, 0x9e, 0x77,
+    0x6d, 0x44, 0x9a, 0x63, 0xc9, 0x0f, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0xa5, 0xaa,
+    0x01, 0x78, 0x28, 0x31, 0x61, 0x61, 0x32, 0x65, 0x64, 0x33, 0x63, 0x33, 0x61, 0x35, 0x36, 0x62,
+    0x36, 0x63, 0x61, 0x37, 0x35, 0x39, 0x63, 0x35, 0x32, 0x34, 0x65, 0x63, 0x38, 0x38, 0x61, 0x35,
+    0x37, 0x33, 0x30, 0x61, 0x33, 0x38, 0x61, 0x64, 0x31, 0x66, 0x36, 0x02, 0x78, 0x28, 0x36, 0x61,
+    0x38, 0x38, 0x61, 0x31, 0x62, 0x34, 0x31, 0x35, 0x39, 0x35, 0x66, 0x37, 0x66, 0x36, 0x31, 0x39,
+    0x35, 0x34, 0x31, 0x65, 0x39, 0x33, 0x39, 0x38, 0x31, 0x36, 0x64, 0x35, 0x39, 0x62, 0x32, 0x61,
+    0x37, 0x62, 0x61, 0x33, 0x31, 0x31, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a,
-    0x00, 0x47, 0x44, 0x53, 0x58, 0x1a, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x67, 0x41, 0x6e, 0x64,
-    0x72, 0x6f, 0x69, 0x64, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x0c, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6,
-    0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x26, 0x1a, 0xbd, 0x26, 0xd8, 0x37, 0x8f, 0x4a, 0xf2,
-    0x9e, 0x49, 0x4d, 0x93, 0x23, 0xc4, 0x6e, 0x02, 0xda, 0xe0, 0x00, 0x02, 0xe7, 0xed, 0x29, 0xdf,
-    0x2b, 0xb3, 0x69, 0xf3, 0x55, 0x0e, 0x4c, 0x22, 0xdc, 0xcf, 0xf5, 0x92, 0xc9, 0xfa, 0x78, 0x98,
-    0xf1, 0x0e, 0x55, 0x5f, 0xf4, 0x45, 0xed, 0xc0, 0x0a, 0x72, 0x2a, 0x7a, 0x3a, 0xd2, 0xb1, 0xf7,
-    0x76, 0xfe, 0x2a, 0x6b, 0x7b, 0x2a, 0x53, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0x04, 0x25,
-    0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03, 0xb8, 0xd6, 0xe1, 0x99,
-    0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e, 0x1d, 0xc0, 0x24, 0x74,
-    0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc, 0x12, 0x9e, 0x77, 0x0a, 0xde,
-    0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f, 0x3a, 0x00,
-    0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03,
-    0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0xdb, 0xe7, 0x5b, 0x3f, 0xa3, 0x42, 0xb0,
-    0x9c, 0xf8, 0x40, 0x8c, 0xb0, 0x9c, 0xf0, 0x0a, 0xaf, 0xdf, 0x6f, 0xe5, 0x09, 0x21, 0x11, 0x92,
-    0xe1, 0xf8, 0xc5, 0x09, 0x02, 0x3d, 0x1f, 0xb7, 0xc5, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
-    0x58, 0x40, 0xc4, 0xc1, 0xd7, 0x1c, 0x2d, 0x26, 0x89, 0x22, 0xcf, 0xa6, 0x99, 0x77, 0x30, 0x84,
-    0x86, 0x27, 0x59, 0x8f, 0xd8, 0x08, 0x75, 0xe0, 0xb2, 0xef, 0xf9, 0xfa, 0xa5, 0x40, 0x8c, 0xd3,
-    0xeb, 0xbb, 0xda, 0xf2, 0xc8, 0xae, 0x41, 0x22, 0x50, 0x9c, 0xe8, 0xb2, 0x9c, 0x9b, 0x3f, 0x8a,
-    0x78, 0x76, 0xab, 0xd0, 0xbe, 0xfc, 0xe4, 0x79, 0xcb, 0x1b, 0x2b, 0xaa, 0x4d, 0xdd, 0x15, 0x61,
-    0x42, 0x06,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x47,
+    0x44, 0x53, 0x58, 0x20, 0xa4, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x67, 0x41, 0x6e, 0x64, 0x72, 0x6f,
+    0x69, 0x64, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x0c, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00,
+    0x01, 0x11, 0x74, 0x0c, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0xd7, 0x67, 0x6d, 0x47, 0xf1,
+    0x17, 0xf6, 0x16, 0x58, 0x80, 0x5e, 0x40, 0x92, 0x35, 0x8d, 0xc6, 0x9a, 0x0d, 0x71, 0xe0, 0x56,
+    0x33, 0x0e, 0xad, 0x95, 0xf3, 0xd9, 0xa5, 0x44, 0x90, 0x2b, 0xa0, 0x73, 0xa0, 0xf8, 0x17, 0x9b,
+    0x2a, 0xdc, 0xa4, 0x42, 0xdf, 0x8c, 0xfc, 0x32, 0x19, 0x92, 0x66, 0x75, 0x90, 0x88, 0x85, 0x5d,
+    0x89, 0x5a, 0xb1, 0xdc, 0x95, 0xc9, 0x84, 0x68, 0x3f, 0x35, 0xe4, 0x3a, 0x00, 0x47, 0x44, 0x54,
+    0x58, 0x40, 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03,
+    0xb8, 0xd6, 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e,
+    0x1d, 0xc0, 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc, 0x12,
+    0x9e, 0x77, 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4, 0xc6, 0xdf,
+    0x62, 0x9f, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d,
+    0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x45, 0xc7, 0x2d,
+    0x68, 0x01, 0x96, 0x6d, 0xaf, 0x0a, 0xcd, 0x51, 0x56, 0xfb, 0xac, 0x27, 0xa1, 0x61, 0x59, 0x9b,
+    0xfd, 0xb4, 0x86, 0x73, 0x20, 0x65, 0x64, 0x3c, 0x77, 0xf1, 0x7b, 0x1d, 0x4d, 0x3a, 0x00, 0x47,
+    0x44, 0x58, 0x41, 0x20, 0x3a, 0x00, 0x47, 0x44, 0x59, 0x6a, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+    0x64, 0x2e, 0x31, 0x36, 0x58, 0x40, 0xa5, 0xf8, 0xfe, 0x9d, 0x8c, 0xda, 0x71, 0x0c, 0x51, 0x99,
+    0xe5, 0x48, 0xd3, 0x03, 0xb4, 0x96, 0x67, 0xab, 0xf7, 0x82, 0xf5, 0x70, 0x2b, 0x17, 0xe4, 0x02,
+    0xa1, 0x3c, 0xbc, 0x7c, 0x63, 0x79, 0x0b, 0x01, 0x0c, 0x92, 0x13, 0x39, 0xb2, 0xc8, 0x0e, 0x0c,
+    0x09, 0x90, 0xb9, 0x19, 0x9b, 0x3b, 0xc3, 0x12, 0x9c, 0xea, 0xf6, 0xcb, 0x84, 0x14, 0xf0, 0xcb,
+    0xa5, 0x05, 0x58, 0x3d, 0x45, 0x03,
 ];
 const MESSAGE: &[u8] = b"Message for testing";
 
diff --git a/libs/libavf/Android.bp b/libs/libavf/Android.bp
index b583e21..c958796 100644
--- a/libs/libavf/Android.bp
+++ b/libs/libavf/Android.bp
@@ -10,7 +10,10 @@
     source_stem: "bindings",
     bindgen_flags: ["--default-enum-style rust"],
     apex_available: ["com.android.virt"],
-    visibility: ["//packages/modules/Virtualization/tests/vts"],
+    visibility: [
+        "//packages/modules/Virtualization/tests/vts",
+        "//packages/modules/Virtualization/tests/old_images_avf_test",
+    ],
 }
 
 rust_defaults {
diff --git a/libs/libfdt/Android.bp b/libs/libfdt/Android.bp
index 09f288d..829b30f 100644
--- a/libs/libfdt/Android.bp
+++ b/libs/libfdt/Android.bp
@@ -35,7 +35,6 @@
     ],
     edition: "2021",
     rustlibs: [
-        "libcstr",
         "liblibfdt_bindgen",
         "libstatic_assertions",
         "libzerocopy_nostd",
@@ -79,7 +78,6 @@
     ],
     prefer_rlib: true,
     rustlibs: [
-        "libcstr",
         "liblibfdt",
     ],
 }
diff --git a/libs/libfdt/rules.mk b/libs/libfdt/rules.mk
index 2b4e470..ce8aa51 100644
--- a/libs/libfdt/rules.mk
+++ b/libs/libfdt/rules.mk
@@ -27,7 +27,6 @@
 
 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) \
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index c969749..0dcd31a 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -31,7 +31,6 @@
 
 use core::ffi::{c_void, CStr};
 use core::ops::Range;
-use cstr::cstr;
 use libfdt::get_slice_at_ptr;
 use zerocopy::IntoBytes as _;
 
@@ -167,12 +166,12 @@
 
     /// Returns the standard (deprecated) device_type <string> property.
     pub fn device_type(&self) -> Result<Option<&CStr>> {
-        self.getprop_str(cstr!("device_type"))
+        self.getprop_str(c"device_type")
     }
 
     /// Returns the standard reg <prop-encoded-array> property.
     pub fn reg(&self) -> Result<Option<RegIterator<'a>>> {
-        if let Some(cells) = self.getprop_cells(cstr!("reg"))? {
+        if let Some(cells) = self.getprop_cells(c"reg")? {
             let parent = self.parent()?;
 
             let addr_cells = parent.address_cells()?;
@@ -186,7 +185,7 @@
 
     /// Returns the standard ranges property.
     pub fn ranges<A, P, S>(&self) -> Result<Option<RangesIterator<'a, A, P, S>>> {
-        if let Some(cells) = self.getprop_cells(cstr!("ranges"))? {
+        if let Some(cells) = self.getprop_cells(c"ranges")? {
             let parent = self.parent()?;
             let addr_cells = self.address_cells()?;
             let parent_addr_cells = parent.address_cells()?;
@@ -320,9 +319,9 @@
     /// Returns the phandle
     pub fn get_phandle(&self) -> Result<Option<Phandle>> {
         // This rewrites the fdt_get_phandle() because it doesn't return error code.
-        if let Some(prop) = self.getprop_u32(cstr!("phandle"))? {
+        if let Some(prop) = self.getprop_u32(c"phandle")? {
             Ok(Some(prop.try_into()?))
-        } else if let Some(prop) = self.getprop_u32(cstr!("linux,phandle"))? {
+        } else if let Some(prop) = self.getprop_u32(c"linux,phandle")? {
             Ok(Some(prop.try_into()?))
         } else {
             Ok(None)
@@ -693,8 +692,8 @@
     ///
     /// NOTE: This does not support individual "/memory@XXXX" banks.
     pub fn memory(&self) -> Result<MemRegIterator> {
-        let node = self.root().subnode(cstr!("memory"))?.ok_or(FdtError::NotFound)?;
-        if node.device_type()? != Some(cstr!("memory")) {
+        let node = self.root().subnode(c"memory")?.ok_or(FdtError::NotFound)?;
+        if node.device_type()? != Some(c"memory") {
             return Err(FdtError::BadValue);
         }
         node.reg()?.ok_or(FdtError::BadValue).map(MemRegIterator::new)
@@ -707,12 +706,12 @@
 
     /// Returns the standard /chosen node.
     pub fn chosen(&self) -> Result<Option<FdtNode>> {
-        self.root().subnode(cstr!("chosen"))
+        self.root().subnode(c"chosen")
     }
 
     /// Returns the standard /chosen node as mutable.
     pub fn chosen_mut(&mut self) -> Result<Option<FdtNodeMut>> {
-        self.node_mut(cstr!("/chosen"))
+        self.node_mut(c"/chosen")
     }
 
     /// Returns the root node of the tree.
@@ -722,12 +721,12 @@
 
     /// Returns the standard /__symbols__ node.
     pub fn symbols(&self) -> Result<Option<FdtNode>> {
-        self.root().subnode(cstr!("__symbols__"))
+        self.root().subnode(c"__symbols__")
     }
 
     /// Returns the standard /__symbols__ node as mutable
     pub fn symbols_mut(&mut self) -> Result<Option<FdtNodeMut>> {
-        self.node_mut(cstr!("/__symbols__"))
+        self.node_mut(c"/__symbols__")
     }
 
     /// Returns a tree node by its full path.
diff --git a/libs/libfdt/tests/api_test.rs b/libs/libfdt/tests/api_test.rs
index f521a00..e027164 100644
--- a/libs/libfdt/tests/api_test.rs
+++ b/libs/libfdt/tests/api_test.rs
@@ -17,7 +17,6 @@
 //! Integration tests of the library libfdt.
 
 use core::ffi::CStr;
-use cstr::cstr;
 use libfdt::{Fdt, FdtError, FdtNodeMut, Phandle};
 use std::collections::HashSet;
 use std::ffi::CString;
@@ -82,14 +81,14 @@
     let fdt = Fdt::from_slice(&data).unwrap();
 
     let root = fdt.root();
-    assert_eq!(root.name(), Ok(cstr!("")));
+    assert_eq!(root.name(), Ok(c""));
 
     let chosen = fdt.chosen().unwrap().unwrap();
-    assert_eq!(chosen.name(), Ok(cstr!("chosen")));
+    assert_eq!(chosen.name(), Ok(c"chosen"));
 
-    let nested_node_path = cstr!("/cpus/PowerPC,970@0");
+    let nested_node_path = c"/cpus/PowerPC,970@0";
     let nested_node = fdt.node(nested_node_path).unwrap().unwrap();
-    assert_eq!(nested_node.name(), Ok(cstr!("PowerPC,970@0")));
+    assert_eq!(nested_node.name(), Ok(c"PowerPC,970@0"));
 }
 
 #[test]
@@ -97,7 +96,7 @@
     let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
     let fdt = Fdt::from_slice(&data).unwrap();
     let root = fdt.root();
-    let expected = [Ok(cstr!("cpus")), Ok(cstr!("randomnode")), Ok(cstr!("chosen"))];
+    let expected = [Ok(c"cpus"), Ok(c"randomnode"), Ok(c"chosen")];
 
     let root_subnodes = root.subnodes().unwrap();
     let subnode_names: Vec<_> = root_subnodes.map(|node| node.name()).collect();
@@ -112,11 +111,11 @@
     let one_be = 0x1_u32.to_be_bytes();
     type Result<T> = core::result::Result<T, FdtError>;
     let expected: Vec<(Result<&CStr>, Result<&[u8]>)> = vec![
-        (Ok(cstr!("model")), Ok(b"MyBoardName\0".as_ref())),
-        (Ok(cstr!("compatible")), Ok(b"MyBoardName\0MyBoardFamilyName\0".as_ref())),
-        (Ok(cstr!("#address-cells")), Ok(&one_be)),
-        (Ok(cstr!("#size-cells")), Ok(&one_be)),
-        (Ok(cstr!("empty_prop")), Ok(&[])),
+        (Ok(c"model"), Ok(b"MyBoardName\0".as_ref())),
+        (Ok(c"compatible"), Ok(b"MyBoardName\0MyBoardFamilyName\0".as_ref())),
+        (Ok(c"#address-cells"), Ok(&one_be)),
+        (Ok(c"#size-cells"), Ok(&one_be)),
+        (Ok(c"empty_prop"), Ok(&[])),
     ];
 
     let properties = root.properties().unwrap();
@@ -129,8 +128,8 @@
 fn node_supernode_at_depth() {
     let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
     let fdt = Fdt::from_slice(&data).unwrap();
-    let node = fdt.node(cstr!("/cpus/PowerPC,970@1")).unwrap().unwrap();
-    let expected = vec![Ok(cstr!("")), Ok(cstr!("cpus")), Ok(cstr!("PowerPC,970@1"))];
+    let node = fdt.node(c"/cpus/PowerPC,970@1").unwrap().unwrap();
+    let expected = vec![Ok(c""), Ok(c"cpus"), Ok(c"PowerPC,970@1")];
 
     let mut supernode_names = vec![];
     let mut depth = 0;
@@ -187,12 +186,12 @@
     // Test linux,phandle
     let phandle = Phandle::new(0xFF).unwrap();
     let node = fdt.node_with_phandle(phandle).unwrap().unwrap();
-    assert_eq!(node.name(), Ok(cstr!("node_zz")));
+    assert_eq!(node.name(), Ok(c"node_zz"));
 
     // Test phandle
     let phandle = Phandle::new(0x22).unwrap();
     let node = fdt.node_with_phandle(phandle).unwrap().unwrap();
-    assert_eq!(node.name(), Ok(cstr!("node_abc")));
+    assert_eq!(node.name(), Ok(c"node_abc"));
 }
 
 #[test]
@@ -203,12 +202,12 @@
     // Test linux,phandle
     let phandle = Phandle::new(0xFF).unwrap();
     let node: FdtNodeMut = fdt.node_mut_with_phandle(phandle).unwrap().unwrap();
-    assert_eq!(node.as_node().name(), Ok(cstr!("node_zz")));
+    assert_eq!(node.as_node().name(), Ok(c"node_zz"));
 
     // Test phandle
     let phandle = Phandle::new(0x22).unwrap();
     let node: FdtNodeMut = fdt.node_mut_with_phandle(phandle).unwrap().unwrap();
-    assert_eq!(node.as_node().name(), Ok(cstr!("node_abc")));
+    assert_eq!(node.as_node().name(), Ok(c"node_abc"));
 }
 
 #[test]
@@ -217,15 +216,15 @@
     let fdt = Fdt::from_slice(&data).unwrap();
 
     // Test linux,phandle
-    let node = fdt.node(cstr!("/node_z/node_zz")).unwrap().unwrap();
+    let node = fdt.node(c"/node_z/node_zz").unwrap().unwrap();
     assert_eq!(node.get_phandle(), Ok(Phandle::new(0xFF)));
 
     // Test phandle
-    let node = fdt.node(cstr!("/node_a/node_ab/node_abc")).unwrap().unwrap();
+    let node = fdt.node(c"/node_a/node_ab/node_abc").unwrap().unwrap();
     assert_eq!(node.get_phandle(), Ok(Phandle::new(0x22)));
 
     // Test no phandle
-    let node = fdt.node(cstr!("/node_b")).unwrap().unwrap();
+    let node = fdt.node(c"/node_b").unwrap().unwrap();
     assert_eq!(node.get_phandle(), Ok(None));
 }
 
@@ -234,7 +233,7 @@
     let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
     let fdt = Fdt::from_mut_slice(&mut data).unwrap();
     let phandle = Phandle::new(0xFF).unwrap();
-    let path = cstr!("/node_z/node_zz");
+    let path = c"/node_z/node_zz";
 
     fdt.node_with_phandle(phandle).unwrap().unwrap();
     let node = fdt.node_mut(path).unwrap().unwrap();
@@ -259,8 +258,8 @@
     let fdt = Fdt::from_mut_slice(&mut data).unwrap();
     fdt.unpack().unwrap();
 
-    let node_path = cstr!("/node_z/node_zz");
-    let subnode_name = cstr!("123456789");
+    let node_path = c"/node_z/node_zz";
+    let subnode_name = c"123456789";
 
     for len in 0..subnode_name.to_bytes().len() {
         let name = &subnode_name.to_bytes()[0..len];
@@ -289,7 +288,7 @@
     let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
     let fdt = Fdt::from_slice(&data).unwrap();
 
-    let name = cstr!("node_a");
+    let name = c"node_a";
     let root = fdt.root();
     let node = root.subnode(name).unwrap();
     assert_ne!(None, node);
@@ -309,7 +308,7 @@
     assert_ne!(None, node);
     let node = node.unwrap();
 
-    assert_eq!(Ok(cstr!("node_a")), node.name());
+    assert_eq!(Ok(c"node_a"), node.name());
 }
 
 #[test]
@@ -317,7 +316,7 @@
     let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
     let fdt = Fdt::from_slice(&data).unwrap();
 
-    let name = cstr!("node_a");
+    let name = c"node_a";
     let node = {
         let root = fdt.root();
         root.subnode(name).unwrap().unwrap()
@@ -332,7 +331,7 @@
     let fdt = Fdt::from_mut_slice(&mut data).unwrap();
 
     let symbols = fdt.symbols().unwrap().unwrap();
-    assert_eq!(symbols.name(), Ok(cstr!("__symbols__")));
+    assert_eq!(symbols.name(), Ok(c"__symbols__"));
 
     // Validates type.
     let _symbols: FdtNodeMut = fdt.symbols_mut().unwrap().unwrap();
@@ -343,14 +342,14 @@
     let mut data = fs::read(TEST_TREE_WITH_ONE_MEMORY_RANGE_PATH).unwrap();
     let fdt = Fdt::from_mut_slice(&mut data).unwrap();
 
-    let mut memory = fdt.node_mut(cstr!("/memory")).unwrap().unwrap();
+    let mut memory = fdt.node_mut(c"/memory").unwrap().unwrap();
     {
         let memory = memory.as_node();
-        assert_eq!(memory.name(), Ok(cstr!("memory")));
+        assert_eq!(memory.name(), Ok(c"memory"));
     }
 
     // Just check whether borrow checker doesn't complain this.
-    memory.setprop_inplace(cstr!("device_type"), b"MEMORY\0").unwrap();
+    memory.setprop_inplace(c"device_type", b"MEMORY\0").unwrap();
 }
 
 #[test]
@@ -358,18 +357,13 @@
     let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
     let fdt = Fdt::from_mut_slice(&mut data).unwrap();
 
-    let node_z = fdt.node(cstr!("/node_z")).unwrap().unwrap();
+    let node_z = fdt.node(c"/node_z").unwrap().unwrap();
     let descendants: Vec<_> =
         node_z.descendants().map(|(node, depth)| (node.name().unwrap(), depth)).collect();
 
     assert_eq!(
         descendants,
-        vec![
-            (cstr!("node_za"), 1),
-            (cstr!("node_zb"), 1),
-            (cstr!("node_zz"), 1),
-            (cstr!("node_zzz"), 2)
-        ]
+        vec![(c"node_za", 1), (c"node_zb", 1), (c"node_zz", 1), (c"node_zzz", 2)]
     );
 }
 
@@ -382,7 +376,7 @@
     let mut subnode_iter = root.first_subnode().unwrap();
 
     while let Some(subnode) = subnode_iter {
-        if subnode.as_node().name() == Ok(cstr!("node_z")) {
+        if subnode.as_node().name() == Ok(c"node_z") {
             subnode_iter = subnode.delete_and_next_subnode().unwrap();
         } else {
             subnode_iter = subnode.next_subnode().unwrap();
@@ -390,12 +384,7 @@
     }
 
     let root = fdt.root();
-    let expected_names = vec![
-        Ok(cstr!("node_a")),
-        Ok(cstr!("node_b")),
-        Ok(cstr!("node_c")),
-        Ok(cstr!("__symbols__")),
-    ];
+    let expected_names = vec![Ok(c"node_a"), Ok(c"node_b"), Ok(c"node_c"), Ok(c"__symbols__")];
     let subnode_names: Vec<_> = root.subnodes().unwrap().map(|node| node.name()).collect();
 
     assert_eq!(expected_names, subnode_names);
@@ -407,19 +396,19 @@
     let fdt = Fdt::from_mut_slice(&mut data).unwrap();
 
     let expected_nodes = vec![
-        (Ok(cstr!("node_b")), 1),
-        (Ok(cstr!("node_c")), 1),
-        (Ok(cstr!("node_z")), 1),
-        (Ok(cstr!("node_za")), 2),
-        (Ok(cstr!("node_zb")), 2),
-        (Ok(cstr!("__symbols__")), 1),
+        (Ok(c"node_b"), 1),
+        (Ok(c"node_c"), 1),
+        (Ok(c"node_z"), 1),
+        (Ok(c"node_za"), 2),
+        (Ok(c"node_zb"), 2),
+        (Ok(c"__symbols__"), 1),
     ];
 
     let mut expected_nodes_iter = expected_nodes.iter();
     let mut iter = fdt.root_mut().next_node(0).unwrap();
     while let Some((node, depth)) = iter {
         let node_name = node.as_node().name();
-        if node_name == Ok(cstr!("node_a")) || node_name == Ok(cstr!("node_zz")) {
+        if node_name == Ok(c"node_a") || node_name == Ok(c"node_zz") {
             iter = node.delete_and_next_node(depth).unwrap();
         } else {
             // Note: Checking name here is easier than collecting names and assert_eq!(),
@@ -464,7 +453,7 @@
         root.name()
         // Make root to be dropped
     };
-    assert_eq!(Ok(cstr!("")), name);
+    assert_eq!(Ok(c""), name);
 }
 
 #[test]
@@ -473,7 +462,7 @@
     let fdt = Fdt::create_empty_tree(&mut data).unwrap();
 
     let root = fdt.root_mut();
-    let names = [cstr!("a"), cstr!("b")];
+    let names = [c"a", c"b"];
     root.add_subnodes(&names).unwrap();
 
     let expected: HashSet<_> = names.into_iter().collect();
@@ -492,14 +481,14 @@
     let name = {
         let node_a = {
             let root = fdt.root();
-            root.subnode(cstr!("node_a")).unwrap()
+            root.subnode(c"node_a").unwrap()
             // Make root to be dropped
         };
         assert_ne!(None, node_a);
         node_a.unwrap().name()
         // Make node_a to be dropped
     };
-    assert_eq!(Ok(cstr!("node_a")), name);
+    assert_eq!(Ok(c"node_a"), name);
 }
 
 #[test]
@@ -521,7 +510,7 @@
         first_subnode.name()
         // Make first_subnode to be dropped
     };
-    assert_eq!(Ok(cstr!("node_a")), first_subnode_name);
+    assert_eq!(Ok(c"node_a"), first_subnode_name);
 }
 
 #[test]
@@ -543,5 +532,5 @@
         first_descendant.name()
         // Make first_descendant to be dropped
     };
-    assert_eq!(Ok(cstr!("node_a")), first_descendant_name);
+    assert_eq!(Ok(c"node_a"), first_descendant_name);
 }
diff --git a/libs/libservice_vm_fake_chain/Android.bp b/libs/libservice_vm_fake_chain/Android.bp
index 56fb22a..65eddf8 100644
--- a/libs/libservice_vm_fake_chain/Android.bp
+++ b/libs/libservice_vm_fake_chain/Android.bp
@@ -26,9 +26,6 @@
         "//packages/modules/Virtualization/guest/rialto:__subpackages__",
     ],
     prefer_rlib: true,
-    rustlibs: [
-        "libcstr",
-    ],
 }
 
 rust_library {
diff --git a/libs/libservice_vm_fake_chain/src/client_vm.rs b/libs/libservice_vm_fake_chain/src/client_vm.rs
index dc499e0..fa72739 100644
--- a/libs/libservice_vm_fake_chain/src/client_vm.rs
+++ b/libs/libservice_vm_fake_chain/src/client_vm.rs
@@ -22,7 +22,6 @@
 use ciborium::{cbor, value::Value};
 use core::result;
 use coset::CborSerializable;
-use cstr::cstr;
 use diced_open_dice::{
     hash, retry_bcc_format_config_descriptor, retry_bcc_main_flow, Config, DiceArtifacts,
     DiceConfigValues, DiceError, DiceMode, InputValues, OwnedDiceArtifacts, Result, HASH_SIZE,
@@ -96,7 +95,7 @@
 
     // Adds an entry describing the Microdroid kernel.
     let config_values = DiceConfigValues {
-        component_name: Some(cstr!("vm_entry")),
+        component_name: Some(c"vm_entry"),
         component_version: Some(12),
         resettable: true,
         security_version: Some(13),
diff --git a/libs/libservice_vm_fake_chain/src/service_vm.rs b/libs/libservice_vm_fake_chain/src/service_vm.rs
index 04297e4..5064ff8 100644
--- a/libs/libservice_vm_fake_chain/src/service_vm.rs
+++ b/libs/libservice_vm_fake_chain/src/service_vm.rs
@@ -24,7 +24,6 @@
     iana::{self, EnumI64},
     Algorithm, AsCborValue, CborSerializable, CoseKey, KeyOperation, KeyType, Label,
 };
-use cstr::cstr;
 use diced_open_dice::{
     derive_cdi_private_key_seed, keypair_from_seed, retry_bcc_format_config_descriptor,
     retry_bcc_main_flow, retry_dice_main_flow, CdiValues, Config, DiceConfigValues, DiceError,
@@ -113,7 +112,7 @@
 
     // Gets the pvmfw certificate to as the root certificate of DICE chain.
     let config_values = DiceConfigValues {
-        component_name: Some(cstr!("Protected VM firmware")),
+        component_name: Some(c"Protected VM firmware"),
         component_version: Some(1),
         resettable: true,
         rkp_vm_marker: true,
@@ -156,7 +155,7 @@
 pub fn fake_service_vm_dice_artifacts() -> Result<OwnedDiceArtifacts> {
     let (cdi_values, dice_chain) = fake_dice_artifacts_up_to_pvmfw()?;
     let config_values = DiceConfigValues {
-        component_name: Some(cstr!("vm_entry")),
+        component_name: Some(c"vm_entry"),
         component_version: Some(12),
         resettable: true,
         rkp_vm_marker: true,
diff --git a/libs/libvm_payload/Android.bp b/libs/libvm_payload/Android.bp
index bb91737..1ebbe39 100644
--- a/libs/libvm_payload/Android.bp
+++ b/libs/libvm_payload/Android.bp
@@ -34,6 +34,7 @@
     bindgen_flags: [
         "--default-enum-style rust",
         "--allowlist-type=AVmAttestationStatus",
+        "--allowlist-type=AVmAccessRollbackProtectedSecretStatus",
     ],
     visibility: [":__subpackages__"],
 }
diff --git a/libs/libvm_payload/include/vm_payload.h b/libs/libvm_payload/include/vm_payload.h
index 5e15607..e4609fa 100644
--- a/libs/libvm_payload/include/vm_payload.h
+++ b/libs/libvm_payload/include/vm_payload.h
@@ -52,6 +52,22 @@
 } AVmAttestationStatus;
 
 /**
+ * Introduced in API 36.
+ * Status type used to indicate error while accessing RollbackProtectedSecret.
+ */
+typedef enum AVmAccessRollbackProtectedSecretStatus : int32_t {
+    /**
+     * Relevant Entry not found. This can happen either due to no value was ever written or because
+     * Android maliciously deleted the value (deletions may not be authenticated).
+     */
+    AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ENTRY_NOT_FOUND = -1,
+    /** Requested access size is not supported by the implementation */
+    AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_BAD_SIZE = -2,
+    /** Access failed, this could be due to lacking support from Hardware */
+    AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ACCESS_FAILED = -3,
+} AVmAccessRollbackProtectedSecretStatus;
+
+/**
  * Notifies the host that the payload is ready.
  *
  * If the host app has set a `VirtualMachineCallback` for the VM, its
@@ -102,6 +118,11 @@
  * byte sequences and do not need to be kept secret; typically they are
  * hardcoded in the calling code.
  *
+ * The secret is linked to the instance & will be created for a new instance.
+ * Callers should check `AVmPayload_isNewInstance()` to meaningfully use the secret.
+ * For ex, decryption of any old data is meaningless with the returned secret of a new
+ * VM instance with fresh keys.
+ *
  * \param identifier identifier of the secret to return.
  * \param identifier_size size of the secret identifier.
  * \param secret pointer to size bytes where the secret is written.
@@ -259,5 +280,42 @@
 size_t AVmAttestationResult_getCertificateAt(const AVmAttestationResult* _Nonnull result,
                                              size_t index, void* _Nullable data, size_t size)
         __INTRODUCED_IN(__ANDROID_API_V__);
+/**
+ * Writes up to n bytes from buffer starting at `buf`, on behalf of the payload, to rollback
+ * detectable storage. The number of bytes written may be less than n if, for example, the
+ * underlying storage has size constraints. This stored data is confidential to the pVM and
+ * protected via appropriate DICE policy on the payload's DICE chain.
+ *
+ * \param buf A pointer to data to be written. This should have the size of at least n bytes.
+ * \param n The maximum number of bytes to be filled in `buf`.
+ *
+ *  \return On success, the number of bytes written is returned. On error, appropriate
+ * AVmAccessRollbackProtectedSecretStatus (negative number) is returned.
+ */
+
+int32_t AVmPayload_writeRollbackProtectedSecret(const void* _Nonnull buf, size_t n)
+        __INTRODUCED_IN(36);
+/**
+ * Read up to n bytes of payload's data in rollback detectable storage into `buf`.
+ *
+ * \param buf A pointer to buffer where the requested data is written. This should have the size of
+ * at least n bytes.
+ * \param n The maximum number of bytes to be read.
+ *
+ *  \return On success, the number of bytes that would have been written to `buf` if n was
+ * sufficiently large. On error, appropriate AVmAccessRollbackProtectedSecretStatus(a negative
+ * number) is returned.
+ */
+int32_t AVmPayload_readRollbackProtectedSecret(void* _Nullable buf, size_t n) __INTRODUCED_IN(36);
+;
+
+/**
+ * Checks whether the VM instance is new - i.e., if this is the first run of an instance.
+ * This is an indication of fresh new VM secrets. Payload can use this to setup the fresh
+ * instance if needed.
+ *
+ *  \return true if this is the first run of an instance, false otherwise.
+ */
+bool AVmPayload_isNewInstance() __INTRODUCED_IN(36);
 
 __END_DECLS
diff --git a/libs/libvm_payload/libvm_payload.map.txt b/libs/libvm_payload/libvm_payload.map.txt
index 3daad00..ca949d9 100644
--- a/libs/libvm_payload/libvm_payload.map.txt
+++ b/libs/libvm_payload/libvm_payload.map.txt
@@ -15,6 +15,9 @@
     AVmAttestationStatus_toString;       # systemapi introduced=VanillaIceCream
     AVmAttestationResult_getCertificateCount; # systemapi introduced=VanillaIceCream
     AVmAttestationResult_getCertificateAt; # systemapi introduced=VanillaIceCream
+    AVmPayload_writeRollbackProtectedSecret; # systemapi introduced=36
+    AVmPayload_readRollbackProtectedSecret; # systemapi introduced=36
+    AVmPayload_isNewInstance;                # systemapi introduced=36
   local:
     *;
 };
diff --git a/libs/libvm_payload/src/lib.rs b/libs/libvm_payload/src/lib.rs
index eb81752..cbadec2 100644
--- a/libs/libvm_payload/src/lib.rs
+++ b/libs/libvm_payload/src/lib.rs
@@ -16,14 +16,14 @@
 
 use android_system_virtualization_payload::aidl::android::system::virtualization::payload:: IVmPayloadService::{
     IVmPayloadService, ENCRYPTEDSTORE_MOUNTPOINT, VM_APK_CONTENTS_PATH,
-    VM_PAYLOAD_SERVICE_SOCKET_NAME, AttestationResult::AttestationResult,
+    VM_PAYLOAD_SERVICE_SOCKET_NAME, AttestationResult::AttestationResult
 };
 use anyhow::{bail, ensure, Context, Result};
 use binder::{
     unstable_api::{new_spibinder, AIBinder},
     Strong, ExceptionCode,
 };
-use log::{error, info, LevelFilter};
+use log::{error, info, LevelFilter, debug};
 use rpcbinder::{RpcServer, RpcSession};
 use openssl::{ec::EcKey, sha::sha256, ecdsa::EcdsaSig};
 use std::convert::Infallible;
@@ -38,9 +38,12 @@
     Mutex,
 };
 use vm_payload_status_bindgen::AVmAttestationStatus;
+use vm_payload_status_bindgen::AVmAccessRollbackProtectedSecretStatus::{AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ENTRY_NOT_FOUND, AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ACCESS_FAILED, AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_BAD_SIZE};
+use std::cmp::min;
 
 /// Maximum size of an ECDSA signature for EC P-256 key is 72 bytes.
 const MAX_ECDSA_P256_SIGNATURE_SIZE: usize = 72;
+const RP_DATA_SIZE: usize = 32;
 
 static VM_APK_CONTENTS_PATH_C: LazyLock<CString> =
     LazyLock::new(|| CString::new(VM_APK_CONTENTS_PATH).expect("CString::new failed"));
@@ -566,3 +569,98 @@
         ptr::null()
     }
 }
+
+/// Writes up to n bytes from buffer starting at `buf`, on behalf of the payload, to rollback
+/// detectable storage and return the number of bytes written or appropriate (negative) status.
+/// For this implementation, the backing storage is Secretkeeper HAL, which allows storing & reading
+/// of 32 bytes secret!
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `buf` must be [valid] for reads of n bytes.
+///
+/// [valid]: ptr#safety
+#[no_mangle]
+pub unsafe extern "C" fn AVmPayload_writeRollbackProtectedSecret(buf: *const u8, n: usize) -> i32 {
+    initialize_logging();
+    if n < RP_DATA_SIZE {
+        error!(
+            "Requested writing {} bytes, while Secretkeeper supports only {} bytes",
+            n, RP_DATA_SIZE
+        );
+        return AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_BAD_SIZE as i32;
+    }
+    // Safety: See the requirements on `buf` above and we just checked that n >= RP_DATA_SIZE.
+    let buf = unsafe { std::slice::from_raw_parts(buf, RP_DATA_SIZE) };
+    match try_writing_payload_rollback_protected_data(buf.try_into().unwrap()) {
+        Ok(()) => RP_DATA_SIZE as i32,
+        Err(e) => {
+            error!("Failed to write rollback protected data: {e:?}");
+            AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ACCESS_FAILED as i32
+        }
+    }
+}
+
+/// Read up to n bytes of payload's data in rollback detectable storage into `buf`.
+/// For this implementation, the backing storage is Secretkeeper HAL, which allows storing & reading
+/// of 32 bytes secret!
+///
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `buf` must be [valid] for writes of n bytes.
+///
+/// [valid]: ptr#safety
+#[no_mangle]
+pub unsafe extern "C" fn AVmPayload_readRollbackProtectedSecret(buf: *mut u8, n: usize) -> i32 {
+    initialize_logging();
+    match try_read_rollback_protected_data() {
+        Err(e) => {
+            error!("Failed to read rollback protected data: {e:?}");
+            AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ACCESS_FAILED as i32
+        }
+        Ok(stored_data) => {
+            if let Some(stored_data) = stored_data {
+                // SAFETY: See the requirements on `buf` above; `stored_data` is known to have
+                // length `RP_DATA_SIZE`, and cannot overlap `data` because we just allocated
+                // it.
+                unsafe {
+                    ptr::copy_nonoverlapping(stored_data.as_ptr(), buf, min(n, RP_DATA_SIZE));
+                }
+                RP_DATA_SIZE as i32
+            } else {
+                debug!("No relevant entry found in Secretkeeper");
+                AVMACCESSROLLBACKPROTECTEDSECRETSTATUS_ENTRY_NOT_FOUND as i32
+            }
+        }
+    }
+}
+
+fn try_writing_payload_rollback_protected_data(data: &[u8; RP_DATA_SIZE]) -> Result<()> {
+    get_vm_payload_service()?
+        .writePayloadRpData(data)
+        .context("Failed to write payload rollback protected data")?;
+    Ok(())
+}
+
+fn try_read_rollback_protected_data() -> Result<Option<[u8; RP_DATA_SIZE]>> {
+    let rp = get_vm_payload_service()?
+        .readPayloadRpData()
+        .context("Failed to read rollback protected data")?;
+    Ok(rp)
+}
+
+/// Checks whether the VM instance is new - i.e., if this is the first run of an instance.
+///
+/// Panics on error (including unexpected server exit).
+#[no_mangle]
+pub extern "C" fn AVmPayload_isNewInstance() -> bool {
+    unwrap_or_abort(try_is_new_instance())
+}
+
+fn try_is_new_instance() -> Result<bool> {
+    get_vm_payload_service()?.isNewInstance().context("Cannot determine if the instance is new")
+}
diff --git a/libs/libvm_payload/wrapper/lib.rs b/libs/libvm_payload/wrapper/lib.rs
index b9ce6c8..bf274b0 100644
--- a/libs/libvm_payload/wrapper/lib.rs
+++ b/libs/libvm_payload/wrapper/lib.rs
@@ -31,7 +31,9 @@
 use std::ptr;
 use vm_payload_bindgen::{
     AIBinder, AVmPayload_getApkContentsPath, AVmPayload_getEncryptedStoragePath,
-    AVmPayload_getVmInstanceSecret, AVmPayload_notifyPayloadReady, AVmPayload_runVsockRpcServer,
+    AVmPayload_getVmInstanceSecret, AVmPayload_isNewInstance, AVmPayload_notifyPayloadReady,
+    AVmPayload_readRollbackProtectedSecret, AVmPayload_runVsockRpcServer,
+    AVmPayload_writeRollbackProtectedSecret,
 };
 
 /// The functions declared here are restricted to VMs created with a config file;
@@ -194,3 +196,23 @@
         )
     }
 }
+
+/// Read payload's `data` written on behalf of the payload in Secretkeeper.
+pub fn read_rollback_protected_secret(data: &mut [u8]) -> i32 {
+    // SAFETY: The function only reads from`[data]` within its bounds.
+    unsafe { AVmPayload_readRollbackProtectedSecret(data.as_ptr() as *mut c_void, data.len()) }
+}
+
+/// Write `data`, on behalf of the payload, to Secretkeeper.
+pub fn write_rollback_protected_secret(data: &[u8]) -> i32 {
+    // SAFETY: The function only writes to `[data]` within its bounds.
+    unsafe { AVmPayload_writeRollbackProtectedSecret(data.as_ptr() as *const c_void, data.len()) }
+}
+
+/// Checks whether the VM instance is new - i.e., if this is the first run of an instance.
+/// This is an indication of fresh new VM secrets. Payload can use this to setup the fresh
+/// instance if needed.
+pub fn is_new_instance_status() -> bool {
+    // SAFETY: The function returns bool, no arguments are needed.
+    unsafe { AVmPayload_isNewInstance() }
+}
diff --git a/libs/libvmbase/Android.bp b/libs/libvmbase/Android.bp
index 3088633..de347c7 100644
--- a/libs/libvmbase/Android.bp
+++ b/libs/libvmbase/Android.bp
@@ -80,7 +80,6 @@
         "libaarch64_paging",
         "libbuddy_system_allocator",
         "libcfg_if",
-        "libcstr",
         "libhypervisor_backends",
         "liblibfdt_nostd",
         "liblog_rust_nostd",
diff --git a/libs/libvmbase/src/bionic.rs b/libs/libvmbase/src/bionic.rs
index 3c0cd6f..37b6e45 100644
--- a/libs/libvmbase/src/bionic.rs
+++ b/libs/libvmbase/src/bionic.rs
@@ -24,7 +24,6 @@
 use core::slice;
 use core::str;
 
-use cstr::cstr;
 use log::error;
 use log::info;
 
@@ -230,138 +229,138 @@
 fn cstr_error(n: c_int) -> &'static CStr {
     // Messages taken from errno(1).
     match n {
-        0 => cstr!("Success"),
-        1 => cstr!("Operation not permitted"),
-        2 => cstr!("No such file or directory"),
-        3 => cstr!("No such process"),
-        4 => cstr!("Interrupted system call"),
-        5 => cstr!("Input/output error"),
-        6 => cstr!("No such device or address"),
-        7 => cstr!("Argument list too long"),
-        8 => cstr!("Exec format error"),
-        9 => cstr!("Bad file descriptor"),
-        10 => cstr!("No child processes"),
-        11 => cstr!("Resource temporarily unavailable"),
-        12 => cstr!("Cannot allocate memory"),
-        13 => cstr!("Permission denied"),
-        14 => cstr!("Bad address"),
-        15 => cstr!("Block device required"),
-        16 => cstr!("Device or resource busy"),
-        17 => cstr!("File exists"),
-        18 => cstr!("Invalid cross-device link"),
-        19 => cstr!("No such device"),
-        20 => cstr!("Not a directory"),
-        21 => cstr!("Is a directory"),
-        22 => cstr!("Invalid argument"),
-        23 => cstr!("Too many open files in system"),
-        24 => cstr!("Too many open files"),
-        25 => cstr!("Inappropriate ioctl for device"),
-        26 => cstr!("Text file busy"),
-        27 => cstr!("File too large"),
-        28 => cstr!("No space left on device"),
-        29 => cstr!("Illegal seek"),
-        30 => cstr!("Read-only file system"),
-        31 => cstr!("Too many links"),
-        32 => cstr!("Broken pipe"),
-        33 => cstr!("Numerical argument out of domain"),
-        34 => cstr!("Numerical result out of range"),
-        35 => cstr!("Resource deadlock avoided"),
-        36 => cstr!("File name too long"),
-        37 => cstr!("No locks available"),
-        38 => cstr!("Function not implemented"),
-        39 => cstr!("Directory not empty"),
-        40 => cstr!("Too many levels of symbolic links"),
-        42 => cstr!("No message of desired type"),
-        43 => cstr!("Identifier removed"),
-        44 => cstr!("Channel number out of range"),
-        45 => cstr!("Level 2 not synchronized"),
-        46 => cstr!("Level 3 halted"),
-        47 => cstr!("Level 3 reset"),
-        48 => cstr!("Link number out of range"),
-        49 => cstr!("Protocol driver not attached"),
-        50 => cstr!("No CSI structure available"),
-        51 => cstr!("Level 2 halted"),
-        52 => cstr!("Invalid exchange"),
-        53 => cstr!("Invalid request descriptor"),
-        54 => cstr!("Exchange full"),
-        55 => cstr!("No anode"),
-        56 => cstr!("Invalid request code"),
-        57 => cstr!("Invalid slot"),
-        59 => cstr!("Bad font file format"),
-        60 => cstr!("Device not a stream"),
-        61 => cstr!("No data available"),
-        62 => cstr!("Timer expired"),
-        63 => cstr!("Out of streams resources"),
-        64 => cstr!("Machine is not on the network"),
-        65 => cstr!("Package not installed"),
-        66 => cstr!("Object is remote"),
-        67 => cstr!("Link has been severed"),
-        68 => cstr!("Advertise error"),
-        69 => cstr!("Srmount error"),
-        70 => cstr!("Communication error on send"),
-        71 => cstr!("Protocol error"),
-        72 => cstr!("Multihop attempted"),
-        73 => cstr!("RFS specific error"),
-        74 => cstr!("Bad message"),
-        75 => cstr!("Value too large for defined data type"),
-        76 => cstr!("Name not unique on network"),
-        77 => cstr!("File descriptor in bad state"),
-        78 => cstr!("Remote address changed"),
-        79 => cstr!("Can not access a needed shared library"),
-        80 => cstr!("Accessing a corrupted shared library"),
-        81 => cstr!(".lib section in a.out corrupted"),
-        82 => cstr!("Attempting to link in too many shared libraries"),
-        83 => cstr!("Cannot exec a shared library directly"),
-        84 => cstr!("Invalid or incomplete multibyte or wide character"),
-        85 => cstr!("Interrupted system call should be restarted"),
-        86 => cstr!("Streams pipe error"),
-        87 => cstr!("Too many users"),
-        88 => cstr!("Socket operation on non-socket"),
-        89 => cstr!("Destination address required"),
-        90 => cstr!("Message too long"),
-        91 => cstr!("Protocol wrong type for socket"),
-        92 => cstr!("Protocol not available"),
-        93 => cstr!("Protocol not supported"),
-        94 => cstr!("Socket type not supported"),
-        95 => cstr!("Operation not supported"),
-        96 => cstr!("Protocol family not supported"),
-        97 => cstr!("Address family not supported by protocol"),
-        98 => cstr!("Address already in use"),
-        99 => cstr!("Cannot assign requested address"),
-        100 => cstr!("Network is down"),
-        101 => cstr!("Network is unreachable"),
-        102 => cstr!("Network dropped connection on reset"),
-        103 => cstr!("Software caused connection abort"),
-        104 => cstr!("Connection reset by peer"),
-        105 => cstr!("No buffer space available"),
-        106 => cstr!("Transport endpoint is already connected"),
-        107 => cstr!("Transport endpoint is not connected"),
-        108 => cstr!("Cannot send after transport endpoint shutdown"),
-        109 => cstr!("Too many references: cannot splice"),
-        110 => cstr!("Connection timed out"),
-        111 => cstr!("Connection refused"),
-        112 => cstr!("Host is down"),
-        113 => cstr!("No route to host"),
-        114 => cstr!("Operation already in progress"),
-        115 => cstr!("Operation now in progress"),
-        116 => cstr!("Stale file handle"),
-        117 => cstr!("Structure needs cleaning"),
-        118 => cstr!("Not a XENIX named type file"),
-        119 => cstr!("No XENIX semaphores available"),
-        120 => cstr!("Is a named type file"),
-        121 => cstr!("Remote I/O error"),
-        122 => cstr!("Disk quota exceeded"),
-        123 => cstr!("No medium found"),
-        124 => cstr!("Wrong medium type"),
-        125 => cstr!("Operation canceled"),
-        126 => cstr!("Required key not available"),
-        127 => cstr!("Key has expired"),
-        128 => cstr!("Key has been revoked"),
-        129 => cstr!("Key was rejected by service"),
-        130 => cstr!("Owner died"),
-        131 => cstr!("State not recoverable"),
-        132 => cstr!("Operation not possible due to RF-kill"),
-        133 => cstr!("Memory page has hardware error"),
-        _ => cstr!("Unknown errno value"),
+        0 => c"Success",
+        1 => c"Operation not permitted",
+        2 => c"No such file or directory",
+        3 => c"No such process",
+        4 => c"Interrupted system call",
+        5 => c"Input/output error",
+        6 => c"No such device or address",
+        7 => c"Argument list too long",
+        8 => c"Exec format error",
+        9 => c"Bad file descriptor",
+        10 => c"No child processes",
+        11 => c"Resource temporarily unavailable",
+        12 => c"Cannot allocate memory",
+        13 => c"Permission denied",
+        14 => c"Bad address",
+        15 => c"Block device required",
+        16 => c"Device or resource busy",
+        17 => c"File exists",
+        18 => c"Invalid cross-device link",
+        19 => c"No such device",
+        20 => c"Not a directory",
+        21 => c"Is a directory",
+        22 => c"Invalid argument",
+        23 => c"Too many open files in system",
+        24 => c"Too many open files",
+        25 => c"Inappropriate ioctl for device",
+        26 => c"Text file busy",
+        27 => c"File too large",
+        28 => c"No space left on device",
+        29 => c"Illegal seek",
+        30 => c"Read-only file system",
+        31 => c"Too many links",
+        32 => c"Broken pipe",
+        33 => c"Numerical argument out of domain",
+        34 => c"Numerical result out of range",
+        35 => c"Resource deadlock avoided",
+        36 => c"File name too long",
+        37 => c"No locks available",
+        38 => c"Function not implemented",
+        39 => c"Directory not empty",
+        40 => c"Too many levels of symbolic links",
+        42 => c"No message of desired type",
+        43 => c"Identifier removed",
+        44 => c"Channel number out of range",
+        45 => c"Level 2 not synchronized",
+        46 => c"Level 3 halted",
+        47 => c"Level 3 reset",
+        48 => c"Link number out of range",
+        49 => c"Protocol driver not attached",
+        50 => c"No CSI structure available",
+        51 => c"Level 2 halted",
+        52 => c"Invalid exchange",
+        53 => c"Invalid request descriptor",
+        54 => c"Exchange full",
+        55 => c"No anode",
+        56 => c"Invalid request code",
+        57 => c"Invalid slot",
+        59 => c"Bad font file format",
+        60 => c"Device not a stream",
+        61 => c"No data available",
+        62 => c"Timer expired",
+        63 => c"Out of streams resources",
+        64 => c"Machine is not on the network",
+        65 => c"Package not installed",
+        66 => c"Object is remote",
+        67 => c"Link has been severed",
+        68 => c"Advertise error",
+        69 => c"Srmount error",
+        70 => c"Communication error on send",
+        71 => c"Protocol error",
+        72 => c"Multihop attempted",
+        73 => c"RFS specific error",
+        74 => c"Bad message",
+        75 => c"Value too large for defined data type",
+        76 => c"Name not unique on network",
+        77 => c"File descriptor in bad state",
+        78 => c"Remote address changed",
+        79 => c"Can not access a needed shared library",
+        80 => c"Accessing a corrupted shared library",
+        81 => c".lib section in a.out corrupted",
+        82 => c"Attempting to link in too many shared libraries",
+        83 => c"Cannot exec a shared library directly",
+        84 => c"Invalid or incomplete multibyte or wide character",
+        85 => c"Interrupted system call should be restarted",
+        86 => c"Streams pipe error",
+        87 => c"Too many users",
+        88 => c"Socket operation on non-socket",
+        89 => c"Destination address required",
+        90 => c"Message too long",
+        91 => c"Protocol wrong type for socket",
+        92 => c"Protocol not available",
+        93 => c"Protocol not supported",
+        94 => c"Socket type not supported",
+        95 => c"Operation not supported",
+        96 => c"Protocol family not supported",
+        97 => c"Address family not supported by protocol",
+        98 => c"Address already in use",
+        99 => c"Cannot assign requested address",
+        100 => c"Network is down",
+        101 => c"Network is unreachable",
+        102 => c"Network dropped connection on reset",
+        103 => c"Software caused connection abort",
+        104 => c"Connection reset by peer",
+        105 => c"No buffer space available",
+        106 => c"Transport endpoint is already connected",
+        107 => c"Transport endpoint is not connected",
+        108 => c"Cannot send after transport endpoint shutdown",
+        109 => c"Too many references: cannot splice",
+        110 => c"Connection timed out",
+        111 => c"Connection refused",
+        112 => c"Host is down",
+        113 => c"No route to host",
+        114 => c"Operation already in progress",
+        115 => c"Operation now in progress",
+        116 => c"Stale file handle",
+        117 => c"Structure needs cleaning",
+        118 => c"Not a XENIX named type file",
+        119 => c"No XENIX semaphores available",
+        120 => c"Is a named type file",
+        121 => c"Remote I/O error",
+        122 => c"Disk quota exceeded",
+        123 => c"No medium found",
+        124 => c"Wrong medium type",
+        125 => c"Operation canceled",
+        126 => c"Required key not available",
+        127 => c"Key has expired",
+        128 => c"Key has been revoked",
+        129 => c"Key was rejected by service",
+        130 => c"Owner died",
+        131 => c"State not recoverable",
+        132 => c"Operation not possible due to RF-kill",
+        133 => c"Memory page has hardware error",
+        _ => c"Unknown errno value",
     }
 }
diff --git a/libs/libvmbase/src/fdt.rs b/libs/libvmbase/src/fdt.rs
index aaf354e..2113787 100644
--- a/libs/libvmbase/src/fdt.rs
+++ b/libs/libvmbase/src/fdt.rs
@@ -17,7 +17,6 @@
 pub mod pci;
 
 use core::ops::Range;
-use cstr::cstr;
 use libfdt::{self, Fdt, FdtError};
 
 /// Represents information about a SWIOTLB buffer.
@@ -34,7 +33,7 @@
 impl SwiotlbInfo {
     /// Creates a `SwiotlbInfo` struct from the given device tree.
     pub fn new_from_fdt(fdt: &Fdt) -> libfdt::Result<Option<SwiotlbInfo>> {
-        let Some(node) = fdt.compatible_nodes(cstr!("restricted-dma-pool"))?.next() else {
+        let Some(node) = fdt.compatible_nodes(c"restricted-dma-pool")?.next() else {
             return Ok(None);
         };
         let (addr, size, align) = if let Some(mut reg) = node.reg()? {
@@ -42,8 +41,8 @@
             let size = reg.size.ok_or(FdtError::BadValue)?;
             (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap(), None)
         } else {
-            let size = node.getprop_u64(cstr!("size"))?.ok_or(FdtError::NotFound)?;
-            let align = node.getprop_u64(cstr!("alignment"))?.ok_or(FdtError::NotFound)?;
+            let size = node.getprop_u64(c"size")?.ok_or(FdtError::NotFound)?;
+            let align = node.getprop_u64(c"alignment")?.ok_or(FdtError::NotFound)?;
             (None, size.try_into().unwrap(), Some(align.try_into().unwrap()))
         };
         Ok(Some(Self { addr, size, align }))
diff --git a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
index 6a3bc1b..6a413d6 100644
--- a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
+++ b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
@@ -80,8 +80,28 @@
     String readLineFromConsole();
 
     /**
+     * Read payload's rollback protected data. The `AVmAccessRollbackProtectedSecretStatus` is
+     * wrapped as service_specific error in case of failure. This is _only_ used for testing.
+     */
+    byte[32] insecurelyReadPayloadRpData();
+
+    /**
+     * Request VM to write payload's rollback protected data. The
+     * `AVmAccessRollbackProtectedSecretStatus` is wrapped as service_specific error in case of
+     * failure. This is _only_ used for testing.
+     */
+    void insecurelyWritePayloadRpData(in byte[32] data);
+
+    /**
      * Request the service to exit, triggering the termination of the VM. This may cause any
      * requests in flight to fail.
      */
     oneway void quit();
+
+    /**
+     * Checks whether the VM instance is new - i.e., if this is the first run of an instance.
+     *
+     * @return true on the first boot of the instance & false on subsequent boot.
+     */
+    boolean isNewInstance();
 }
diff --git a/tests/early_vm_test/Android.bp b/tests/early_vm_test/Android.bp
new file mode 100644
index 0000000..dbb0c28
--- /dev/null
+++ b/tests/early_vm_test/Android.bp
@@ -0,0 +1,53 @@
+prebuilt_etc {
+    name: "avf_early_vm_test_kernel",
+    filename: "rialto.bin",
+    src: ":empty_file",
+    target: {
+        android_arm64: {
+            src: ":rialto_signed",
+        },
+    },
+    installable: false,
+    system_ext_specific: true,
+    visibility: ["//visibility:private"],
+}
+
+rust_binary {
+    name: "avf_early_vm_test_launcher",
+    crate_name: "avf_early_vm_test_launcher",
+    srcs: ["src/main.rs"],
+    rustlibs: [
+        "android.system.virtualizationservice-rust",
+        "libanyhow",
+        "libclap",
+        "libhypervisor_props",
+        "liblog_rust",
+        "libservice_vm_comm",
+        "libservice_vm_manager",
+        "libvmclient",
+    ],
+    cfgs: select(release_flag("RELEASE_AVF_ENABLE_EARLY_VM"), {
+        true: ["early_vm_enabled"],
+        default: [],
+    }),
+    prefer_rlib: true,
+    system_ext_specific: true,
+    compile_multilib: "first",
+    installable: false,
+}
+
+python_test_host {
+    name: "avf_early_vm_test",
+    main: "avf_early_vm_test.py",
+    srcs: ["avf_early_vm_test.py"],
+    device_first_data: [
+        ":avf_early_vm_test_kernel",
+        ":avf_early_vm_test_launcher",
+    ],
+    data: ["early_vms_rialto_test.xml"],
+    test_suites: ["general-tests"],
+    test_config: "AndroidTest.xml",
+    test_options: {
+        unit_test: false,
+    },
+}
diff --git a/tests/early_vm_test/AndroidTest.xml b/tests/early_vm_test/AndroidTest.xml
new file mode 100644
index 0000000..3eae96d
--- /dev/null
+++ b/tests/early_vm_test/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs avf_early_vm_test.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+        <option name="force-root" value="true"/>
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+    <option name="abort-on-push-failure" value="true" />
+        <option name="remount-system" value="true" />
+        <option name="push-file" key="avf_early_vm_test_launcher" value="/system_ext/bin/avf_early_vm_test_launcher" />
+        <option name="push-file" key="rialto.bin" value="/system_ext/etc/avf/rialto_test.bin" />
+        <option name="push-file" key="early_vms_rialto_test.xml" value="/system_ext/etc/avf/early_vms_rialto_test.xml" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.python.PythonBinaryHostTest">
+        <option name="par-file-name" value="avf_early_vm_test" />
+        <option name="test-timeout" value="5m" />
+    </test>
+</configuration>
diff --git a/tests/early_vm_test/TEST_MAPPING b/tests/early_vm_test/TEST_MAPPING
new file mode 100644
index 0000000..1f2335b
--- /dev/null
+++ b/tests/early_vm_test/TEST_MAPPING
@@ -0,0 +1,9 @@
+// When adding or removing tests here, don't forget to amend _all_modules list in
+// wireless/android/busytown/ath_config/configs/prod/avf/tests.gcl
+{
+  "avf-presubmit": [
+    {
+      "name": "avf_early_vm_test"
+    }
+  ]
+}
diff --git a/tests/early_vm_test/avf_early_vm_test.py b/tests/early_vm_test/avf_early_vm_test.py
new file mode 100644
index 0000000..0003351
--- /dev/null
+++ b/tests/early_vm_test/avf_early_vm_test.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+#
+# 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.
+#
+
+import logging
+import os
+import subprocess
+import unittest
+
+_DEFAULT_COMMAND_TIMEOUT = 300
+_LAUNCHER_PATH = "/system_ext/bin/avf_early_vm_test_launcher"
+_RIALTO_PATH = "/system_ext/etc/avf/rialto_test.bin"
+
+def _RunCommand(cmd, timeout=_DEFAULT_COMMAND_TIMEOUT):
+    with subprocess.Popen(args=cmd,
+                          stderr=subprocess.PIPE,
+                          stdout=subprocess.PIPE,
+                          universal_newlines=True) as proc:
+        try:
+            out, err = proc.communicate(timeout=timeout)
+            returncode = proc.returncode
+        except subprocess.TimeoutExpired:
+            proc.kill()
+            out, err = proc.communicate()
+            returncode = proc.returncode
+
+    return out, err, returncode
+
+class AvfEarlyVmTest(unittest.TestCase):
+    def setUp(self):
+        self._serial_number = os.environ.get("ANDROID_SERIAL")
+        self.assertTrue(self._serial_number, "$ANDROID_SERIAL is empty.")
+
+    def _TestAvfEarlyVm(self, protected):
+        adb_cmd = ["adb", "-s", self._serial_number, "shell", _LAUNCHER_PATH, "--kernel",
+                   _RIALTO_PATH]
+        if protected:
+            adb_cmd.append("--protected")
+
+        _, err, returncode = _RunCommand(adb_cmd)
+        self.assertEqual(returncode, 0, f"{adb_cmd} failed: {err}")
+
+    def testAvfEarlyVmNonProtected(self):
+        self._TestAvfEarlyVm(False)
+
+    def testAvfEarlyVmProtected(self):
+        self._TestAvfEarlyVm(True)
+
+if __name__ == "__main__":
+    # Setting verbosity is required to generate output that the TradeFed test
+    # runner can parse.
+    unittest.main(verbosity=3)
diff --git a/tests/early_vm_test/early_vms_rialto_test.xml b/tests/early_vm_test/early_vms_rialto_test.xml
new file mode 100644
index 0000000..799fc3f
--- /dev/null
+++ b/tests/early_vm_test/early_vms_rialto_test.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<early_vms>
+    <early_vm>
+        <name>avf_early_vm_test_launcher</name>
+        <cid>299</cid>
+        <path>/system_ext/bin/avf_early_vm_test_launcher</path>
+    </early_vm>
+</early_vms>
diff --git a/tests/early_vm_test/src/main.rs b/tests/early_vm_test/src/main.rs
new file mode 100644
index 0000000..a3c80ca
--- /dev/null
+++ b/tests/early_vm_test/src/main.rs
@@ -0,0 +1,116 @@
+// 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.
+
+//! Tests running an early VM
+
+use android_system_virtualizationservice::{
+    aidl::android::system::virtualizationservice::{
+        IVirtualizationService::IVirtualizationService, VirtualMachineConfig::VirtualMachineConfig,
+        VirtualMachineRawConfig::VirtualMachineRawConfig,
+    },
+    binder::{ParcelFileDescriptor, ProcessState, Strong},
+};
+use anyhow::{Context, Result};
+use clap::Parser;
+use log::info;
+use std::fs::File;
+use std::path::PathBuf;
+
+use service_vm_comm::{Request, Response, VmType};
+use service_vm_manager::ServiceVm;
+use vmclient::VmInstance;
+
+const VM_MEMORY_MB: i32 = 16;
+
+#[derive(Parser)]
+/// Collection of CLI for avf_early_vm_test_rialto
+pub struct Args {
+    /// Path to the Rialto kernel image.
+    #[arg(long)]
+    kernel: PathBuf,
+
+    /// Whether the VM is protected or not.
+    #[arg(long)]
+    protected: bool,
+}
+
+fn get_service() -> Result<Strong<dyn IVirtualizationService>> {
+    let virtmgr = vmclient::VirtualizationService::new_early()
+        .context("Failed to spawn VirtualizationService")?;
+    virtmgr.connect().context("Failed to connect to VirtualizationService")
+}
+
+fn main() -> Result<()> {
+    if std::env::consts::ARCH != "aarch64" {
+        info!("{} not supported. skipping test", std::env::consts::ARCH);
+        return Ok(());
+    }
+
+    if !cfg!(early_vm_enabled) {
+        info!("early VM disabled. skipping test");
+        return Ok(());
+    }
+
+    let args = Args::parse();
+
+    if args.protected {
+        if !hypervisor_props::is_protected_vm_supported()? {
+            info!("pVMs are not supported on device. skipping test");
+            return Ok(());
+        }
+    } else if !hypervisor_props::is_vm_supported()? {
+        info!("non-pVMs are not supported on device. skipping test");
+        return Ok(());
+    }
+
+    let service = get_service()?;
+    let kernel =
+        File::open(&args.kernel).with_context(|| format!("Failed to open {:?}", &args.kernel))?;
+    let kernel = ParcelFileDescriptor::new(kernel);
+
+    let vm_config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
+        name: "avf_early_vm_test_launcher".to_owned(),
+        kernel: Some(kernel),
+        protectedVm: args.protected,
+        memoryMib: VM_MEMORY_MB,
+        platformVersion: "~1.0".to_owned(),
+        ..Default::default()
+    });
+
+    let vm_instance = VmInstance::create(
+        service.as_ref(),
+        &vm_config,
+        // console_in, console_out, and log will be redirected to the kernel log by virtmgr
+        None, // console_in
+        None, // console_out
+        None, // log
+        None, // dump_dt
+        None, // callback
+    )
+    .context("Failed to create VM")?;
+
+    ProcessState::start_thread_pool();
+
+    let vm_type = if args.protected { VmType::ProtectedVm } else { VmType::NonProtectedVm };
+    let mut vm_service = ServiceVm::start_vm(vm_instance, vm_type)?;
+
+    let request_data = vec![1, 2, 3, 4, 5];
+    let reversed_data = vec![5, 4, 3, 2, 1];
+    let response = vm_service
+        .process_request(Request::Reverse(request_data))
+        .context("Failed to process request")?;
+    assert_eq!(Response::Reverse(reversed_data), response);
+
+    Ok(())
+}
diff --git a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
index a932d32..c05fb0b 100644
--- a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
+++ b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
@@ -278,9 +278,11 @@
     }
 
     protected void assumeNoUpdatableVmSupport() throws VirtualMachineException {
-        assume().withMessage("Secretkeeper not supported")
-                .that(getVirtualMachineManager().isUpdatableVmSupported())
-                .isFalse();
+        assume().withMessage("Secretkeeper not supported").that(isUpdatableVmSupported()).isFalse();
+    }
+
+    protected boolean isUpdatableVmSupported() throws VirtualMachineException {
+        return getVirtualMachineManager().isUpdatableVmSupported();
     }
 
     protected void ensureVmAttestationSupported() throws Exception {
@@ -612,6 +614,8 @@
         public String mConsoleInput;
         public byte[] mInstanceSecret;
         public int mPageSize;
+        public byte[] mPayloadRpData;
+        public boolean mIsNewInstance;
 
         public void assertNoException() {
             if (mException != null) {
diff --git a/tests/hostside/Android.bp b/tests/hostside/Android.bp
index 0966c20..6d7c25e 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -59,7 +59,8 @@
 java_test_host {
     name: "MicrodroidHostTestCases",
     defaults: ["MicrodroidHostTestCases.default"],
-    test_config: "AndroidTest.xml",
+    test_config_template: "AndroidTestTemplate.xml",
+    auto_gen_config: true,
     test_suites: [
         "general-tests",
         "pts",
@@ -71,8 +72,21 @@
 java_test_host {
     name: "MicrodroidHostTestCases.CTS",
     defaults: ["MicrodroidHostTestCases.default"],
-    test_config: ":MicrodroidHostTestCases.CTS.config",
+    test_config_template: "AndroidTestTemplate.xml",
     test_suites: ["cts"],
+    auto_gen_config: true,
+    test_options: {
+        tradefed_options: [
+            {
+                name: "include-annotation",
+                value: "com.android.compatibility.common.util.CddTest",
+            },
+            {
+                name: "test-suite-tag",
+                value: "cts",
+            },
+        ],
+    },
     device_common_data: DEVICE_DATA,
     data_native_bins: BINS,
 }
@@ -80,30 +94,43 @@
 java_test_host {
     name: "MicrodroidHostTestCases.VTS",
     defaults: ["MicrodroidHostTestCases.default"],
-    test_config: ":MicrodroidHostTestCases.VTS.config",
+    test_config_template: "AndroidTestTemplate.xml",
     test_suites: ["vts"],
+    auto_gen_config: true,
+    test_options: {
+        tradefed_options: [
+            {
+                name: "include-annotation",
+                value: "com.android.compatibility.common.util.VsrTest",
+            },
+            {
+                name: "test-suite-tag",
+                value: "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)",
+java_test_host {
+    name: "MicrodroidHostTestCases.GTS",
+    defaults: ["MicrodroidHostTestCases.default"],
+    test_config_template: "AndroidTestTemplate.xml",
+    test_suites: ["gts"],
+    auto_gen_config: true,
+    test_options: {
+        tradefed_options: [
+            {
+                name: "include-annotation",
+                value: "com.android.compatibility.common.util.GmsTest",
+            },
+            {
+                name: "test-suite-tag",
+                value: "gts",
+            },
+        ],
+    },
+    device_common_data: DEVICE_DATA,
+    data_native_bins: BINS,
 }
diff --git a/tests/hostside/AndroidTest.xml b/tests/hostside/AndroidTestTemplate.xml
similarity index 91%
rename from tests/hostside/AndroidTest.xml
rename to tests/hostside/AndroidTestTemplate.xml
index c277865..ac066bc 100644
--- a/tests/hostside/AndroidTest.xml
+++ b/tests/hostside/AndroidTestTemplate.xml
@@ -14,7 +14,6 @@
      limitations under the License.
 -->
 <configuration description="Host driven tests for Microdroid">
-    <option name="test-suite-tag" value="cts" />
     <option name="config-descriptor:metadata" key="component" value="security" />
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
@@ -26,12 +25,12 @@
     </target_preparer>
 
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
-        <option name="jar" value="MicrodroidHostTestCases.jar" />
+        <option name="jar" value="{MODULE}.jar" />
     </test>
 
     <!-- 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 -->
+    {EXTRA_CONFIGS}
 </configuration>
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index 01ac6a1..4f9806a 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -36,6 +36,7 @@
 import android.cts.statsdatom.lib.ReportUtils;
 
 import com.android.compatibility.common.util.CddTest;
+import com.android.compatibility.common.util.GmsTest;
 import com.android.compatibility.common.util.PropertyUtil;
 import com.android.compatibility.common.util.VsrTest;
 import com.android.microdroid.test.common.ProcessUtil;
@@ -415,7 +416,8 @@
 
     @Test
     @CddTest
-    @VsrTest(requirements = {"VSR-7.1-001.008"})
+    @GmsTest(requirements = {"GMS-3-7.1-002", "GMS-VSR-7.1-001.006"})
+    @VsrTest(requirements = {"VSR-7.1-001.007"})
     public void UpgradedPackageIsAcceptedWithSecretkeeper() throws Exception {
         // Preconditions
         assumeVmTypeSupported("microdroid", true); // Non-protected VMs may not support upgrades
@@ -433,7 +435,8 @@
 
     @Test
     @CddTest
-    @VsrTest(requirements = {"VSR-7.1-001.008"})
+    @GmsTest(requirements = {"GMS-3-7.1-002", "GMS-VSR-7.1-001.006"})
+    @VsrTest(requirements = {"VSR-7.1-001.007"})
     public void DowngradedPackageIsRejectedProtectedVm() throws Exception {
         // Preconditions: Rollback protection is provided only for protected VM.
         assumeVmTypeSupported("microdroid", true);
@@ -482,7 +485,7 @@
     @Test
     @Parameters(method = "osVersions")
     @TestCaseName("{method}_os_{0}")
-    @CddTest(requirements = {"9.17/C-2-1", "9.17/C-2-2", "9.17/C-2-6"})
+    @GmsTest(requirements = {"GMS-3-7.1-010"})
     public void protectedVmRunsPvmfw(String os) throws Exception {
         // Arrange
         assumeKernelSupported(os);
@@ -515,7 +518,7 @@
     @Test
     @Parameters(method = "osVersions")
     @TestCaseName("{method}_os_{0}")
-    @CddTest(requirements = {"9.17/C-2-1", "9.17/C-2-2", "9.17/C-2-5", "9.17/C-2-6"})
+    @GmsTest(requirements = {"GMS-3-7.1-003", "GMS-3-7.1-010"})
     public void protectedVmWithImageSignedWithDifferentKeyFailsToVerifyPayload(String os)
             throws Exception {
         assumeKernelSupported(os);
@@ -544,7 +547,7 @@
     @Test
     @Parameters(method = "osVersions")
     @TestCaseName("{method}_os_{0}")
-    @CddTest(requirements = {"9.17/C-2-2", "9.17/C-2-6"})
+    @GmsTest(requirements = {"GMS-3-7.1-003", "GMS-3-7.1-010"})
     public void testBootSucceedsWhenNonProtectedVmStartsWithImagesSignedWithDifferentKey(String os)
             throws Exception {
         // Preconditions
@@ -572,7 +575,7 @@
     @Test
     @Parameters(method = "osVersions")
     @TestCaseName("{method}_os_{0}")
-    @CddTest(requirements = {"9.17/C-2-2", "9.17/C-2-5", "9.17/C-2-6"})
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void testBootFailsWhenVbMetaDigestDoesNotMatchBootconfig(String os) throws Exception {
         // protectedVmWithImageSignedWithDifferentKeyRunsPvmfw() is the protected case.
         assumeKernelSupported(os);
@@ -1010,7 +1013,8 @@
     @Test
     @Parameters(method = "params")
     @TestCaseName("{method}_protectedVm_{0}_os_{1}")
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-1-2", "9.17/C/1-3"})
+    @CddTest
+    @GmsTest(requirements = {"GMS-3-7.1-001.002"})
     public void testMicrodroidBoots(boolean protectedVm, String os) throws Exception {
         // Preconditions
         assumeKernelSupported(os);
@@ -1097,6 +1101,7 @@
     }
 
     @Test
+    @CddTest
     public void testPathToBinaryIsRejected() throws Exception {
         CommandRunner android = new CommandRunner(getDevice());
 
@@ -1145,6 +1150,7 @@
     }
 
     @Test
+    @CddTest
     public void testRunEmptyPayload() throws Exception {
         CommandRunner android = new CommandRunner(getDevice());
 
@@ -1198,7 +1204,6 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-2-2", "9.17/C-2-6"})
     public void testAllVbmetaUseSHA256() throws Exception {
         File virtApexDir = FileUtil.createTempDir("virt_apex");
         // Pull the virt apex's etc/ directory (which contains images)
@@ -1309,6 +1314,7 @@
     @Test
     @Parameters(method = "params")
     @TestCaseName("{method}_protectedVm_{0}_os_{1}")
+    @CddTest
     public void testDeviceAssignment(boolean protectedVm, String os) throws Exception {
         // Preconditions
         assumeKernelSupported(os);
@@ -1364,6 +1370,8 @@
     }
 
     @Test
+    @CddTest
+    @GmsTest(requirements = {"GMS-3-7.1-001.002"})
     public void testOsVersions() throws Exception {
         for (String os : getSupportedOSList()) {
             assertWithMessage("Unknown OS \"%s\"", os).that(SUPPORTED_OSES.values()).contains(os);
@@ -1414,6 +1422,7 @@
     @Test
     @Parameters(method = "osVersions")
     @TestCaseName("{method}_os_{0}")
+    @CddTest
     public void microdroidDeviceTreeCompat(String os) throws Exception {
         assumeArm64Supported();
         final String configPath = "assets/vm_config.json";
@@ -1442,6 +1451,7 @@
     @Test
     @Parameters(method = "osVersions")
     @TestCaseName("{method}_os_{0}")
+    @CddTest
     public void microdroidProtectedDeviceTreeCompat(String os) throws Exception {
         assumeArm64Supported();
         final String configPath = "assets/vm_config.json";
diff --git a/tests/old_images_avf_test/Android.bp b/tests/old_images_avf_test/Android.bp
new file mode 100644
index 0000000..b3d5baf
--- /dev/null
+++ b/tests/old_images_avf_test/Android.bp
@@ -0,0 +1,57 @@
+prebuilt_etc {
+    name: "backcompat_rialto_kernel",
+    filename: "rialto.bin",
+    src: ":empty_file",
+    target: {
+        android_arm64: {
+            src: ":rialto_signed",
+        },
+    },
+    installable: false,
+    visibility: ["//visibility:private"],
+}
+
+prebuilt_etc {
+    name: "android16_rialto_kernel",
+    filename: "android16_rialto.bin",
+    src: ":empty_file",
+    target: {
+        android_arm64: {
+            src: "images/android16_rialto.bin",
+        },
+    },
+    installable: false,
+    visibility: ["//visibility:private"],
+}
+
+rust_test {
+    name: "old_images_avf_test",
+    crate_name: "old_images_avf_test",
+    srcs: ["src/main.rs"],
+    rustlibs: [
+        "libanyhow",
+        "libavf_bindgen",
+        "libciborium",
+        "liblog_rust",
+        "libhypervisor_props",
+        "libscopeguard",
+        "libservice_vm_comm",
+        "libvsock",
+    ],
+    shared_libs: ["libavf"],
+    test_suites: [
+        "general-tests",
+    ],
+    data: [
+        ":android16_rialto_kernel",
+        ":backcompat_rialto_kernel",
+    ],
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    test_config: "AndroidTest.xml",
+    compile_multilib: "first",
+}
diff --git a/tests/old_images_avf_test/AndroidTest.xml b/tests/old_images_avf_test/AndroidTest.xml
new file mode 100644
index 0000000..089a424
--- /dev/null
+++ b/tests/old_images_avf_test/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+<configuration description="Runs old images on current AVF VM.">
+    <option name="test-suite-tag" value="general-tests" />
+    <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="old_images_avf_test->/data/local/tmp/old_images_avf_test" />
+        <option name="push" value="rialto.bin->/data/local/tmp/rialto.bin" />
+        <option name="push" value="android16_rialto.bin->/data/local/tmp/android16_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="old_images_avf_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/old_images_avf_test/images/android16_rialto.bin b/tests/old_images_avf_test/images/android16_rialto.bin
new file mode 100644
index 0000000..ff4c38e
--- /dev/null
+++ b/tests/old_images_avf_test/images/android16_rialto.bin
Binary files differ
diff --git a/tests/old_images_avf_test/src/main.rs b/tests/old_images_avf_test/src/main.rs
new file mode 100644
index 0000000..018a80e
--- /dev/null
+++ b/tests/old_images_avf_test/src/main.rs
@@ -0,0 +1,229 @@
+// 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.
+
+//! Tests running a VM with older images
+
+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_vm(image_path: &str, test_name: &CStr, protected_vm: bool) -> Result<()> {
+    let kernel_file = File::open(image_path).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, test_name.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"
+    );
+    assert_eq!(stop_reason, AVirtualMachineStopReason::AVIRTUAL_MACHINE_SHUTDOWN);
+
+    info!("stopped");
+
+    Ok(())
+}
+
+#[test]
+fn test_run_rialto_protected() -> Result<()> {
+    if hypervisor_props::is_protected_vm_supported()? {
+        run_vm(
+            "/data/local/tmp/rialto.bin", /* image_path */
+            c"test_rialto",               /* test_name */
+            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_vm(
+            "/data/local/tmp/rialto.bin", /* image_path */
+            c"test_rialto",               /* test_name */
+            false,                        /* protected_vm */
+        )
+    } else {
+        info!("VMs are not supported on device. skipping test");
+        Ok(())
+    }
+}
+
+#[test]
+fn test_run_android16_rialto_protected() -> Result<()> {
+    if hypervisor_props::is_protected_vm_supported()? {
+        run_vm(
+            "/data/local/tmp/android16_rialto.bin", /* image_path */
+            c"android16_test_rialto",               /* test_name */
+            true,                                   /* protected_vm */
+        )
+    } else {
+        info!("pVMs are not supported on device. skipping test");
+        Ok(())
+    }
+}
+
+#[test]
+fn test_run_android16_rialto_non_protected() -> Result<()> {
+    if hypervisor_props::is_vm_supported()? {
+        run_vm(
+            "/data/local/tmp/android16_rialto.bin", /* image_path */
+            c"android16_test_rialto",               /* test_name */
+            false,                                  /* protected_vm */
+        )
+    } else {
+        info!("VMs are not supported on device. skipping test");
+        Ok(())
+    }
+}
diff --git a/tests/testapk/Android.bp b/tests/testapk/Android.bp
index cb374a5..d0e045b 100644
--- a/tests/testapk/Android.bp
+++ b/tests/testapk/Android.bp
@@ -73,7 +73,8 @@
     defaults: ["MicrodroidVersionsTestAppDefaults"],
     manifest: "AndroidManifestV5.xml",
     test_suites: ["general-tests"],
-    test_config: "AndroidTest.xml",
+    test_config_template: "AndroidTestTemplate.xml",
+    auto_gen_config: true,
     data: DATA,
 }
 
@@ -81,8 +82,21 @@
     name: "MicrodroidTestApp.CTS",
     defaults: ["MicrodroidVersionsTestAppDefaults"],
     manifest: "AndroidManifestV5.xml",
+    test_config_template: "AndroidTestTemplate.xml",
     test_suites: ["cts"],
-    test_config: ":MicrodroidTestApp.CTS.config",
+    auto_gen_config: true,
+    test_options: {
+        tradefed_options: [
+            {
+                name: "include-annotation",
+                value: "com.android.compatibility.common.util.CddTest",
+            },
+            {
+                name: "test-suite-tag",
+                value: "cts",
+            },
+        ],
+    },
     data: DATA,
 }
 
@@ -90,31 +104,44 @@
     name: "MicrodroidTestApp.VTS",
     defaults: ["MicrodroidVersionsTestAppDefaults"],
     manifest: "AndroidManifestV5.xml",
+    test_config_template: "AndroidTestTemplate.xml",
     test_suites: ["vts"],
-    test_config: ":MicrodroidTestApp.VTS.config",
+    auto_gen_config: true,
+    test_options: {
+        tradefed_options: [
+            {
+                name: "include-annotation",
+                value: "com.android.compatibility.common.util.VsrTest",
+            },
+            {
+                name: "test-suite-tag",
+                value: "vts",
+            },
+        ],
+    },
     data: DATA,
 }
 
-genrule {
-    name: "MicrodroidTestApp.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/MicrodroidTestApp.apk/MicrodroidTestApp.CTS.apk/' " +
-        "$(in) > $(out)",
-}
-
-genrule {
-    name: "MicrodroidTestApp.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/MicrodroidTestApp.apk/MicrodroidTestApp.VTS.apk/' " +
-        "$(in) > $(out)",
+android_test {
+    name: "MicrodroidTestApp.GTS",
+    defaults: ["MicrodroidVersionsTestAppDefaults"],
+    manifest: "AndroidManifestV5.xml",
+    test_config_template: "AndroidTestTemplate.xml",
+    test_suites: ["gts"],
+    auto_gen_config: true,
+    test_options: {
+        tradefed_options: [
+            {
+                name: "include-annotation",
+                value: "com.android.compatibility.common.util.GmsTest",
+            },
+            {
+                name: "test-suite-tag",
+                value: "gts",
+            },
+        ],
+    },
+    data: DATA,
 }
 
 android_test_helper_app {
@@ -224,7 +251,6 @@
         "libandroid_logger",
         "libanyhow",
         "libavflog",
-        "libcstr",
         "liblog_rust",
         "libvm_payload_rs",
     ],
diff --git a/tests/testapk/AndroidTest.xml b/tests/testapk/AndroidTestTemplate.xml
similarity index 92%
rename from tests/testapk/AndroidTest.xml
rename to tests/testapk/AndroidTestTemplate.xml
index 221c25c..613ce28 100644
--- a/tests/testapk/AndroidTest.xml
+++ b/tests/testapk/AndroidTestTemplate.xml
@@ -14,14 +14,12 @@
      limitations under the License.
 -->
 <configuration description="Runs Microdroid device-side tests.">
-    <option name="test-suite-tag" value="cts" />
-    <option name="test-suite-tag" value="vts" />
     <option name="config-descriptor:metadata" key="component" value="security" />
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="test-file-name" value="MicrodroidTestApp.apk" />
+        <option name="test-file-name" value="{MODULE}.apk" />
         <option name="test-file-name" value="MicrodroidVmShareApp.apk" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
@@ -44,5 +42,5 @@
     <!-- 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 -->
+    {EXTRA_CONFIGS}
 </configuration>
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidCapabilitiesTest.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidCapabilitiesTest.java
index 08bc310..df5525f 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidCapabilitiesTest.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidCapabilitiesTest.java
@@ -40,7 +40,7 @@
 @RunWith(JUnit4.class)
 public class MicrodroidCapabilitiesTest extends MicrodroidDeviceTestBase {
     @Test
-    @CddTest(requirements = "9.17/C-1-6")
+    @CddTest(requirements = "9.17/C-1-1")
     public void supportForProtectedOrNonProtectedVms() {
         assumeSupportedDevice();
 
@@ -61,7 +61,7 @@
     }
 
     @Test
-    @VsrTest(requirements = "VSR-7.1-001.005")
+    @VsrTest(requirements = "VSR-7.1-001.004")
     public void avfIsRequired() {
         assumeVsrCompliant();
         assume().withMessage("Requirement doesn't apply due to vendor API level")
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 9c66765..8502ec3 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -66,6 +66,7 @@
 import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.compatibility.common.util.CddTest;
+import com.android.compatibility.common.util.GmsTest;
 import com.android.compatibility.common.util.VsrTest;
 import com.android.microdroid.test.device.MicrodroidDeviceTestBase;
 import com.android.microdroid.test.vmshare.IVmShareTestService;
@@ -216,13 +217,13 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     public void createAndConnectToVm() throws Exception {
         createAndConnectToVmHelper(CPU_TOPOLOGY_ONE_CPU, /* shouldUseHugepages= */ false);
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     public void createAndConnectToVm_HostCpuTopology() throws Exception {
         createAndConnectToVmHelper(CPU_TOPOLOGY_MATCH_HOST, /* shouldUseHugepages= */ false);
     }
@@ -248,8 +249,9 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     @VsrTest(requirements = {"VSR-7.1-001.006"})
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.005"})
     public void vmAttestationWhenRemoteAttestationIsNotSupported() throws Exception {
         // pVM remote attestation is only supported on protected VMs.
         assumeProtectedVM();
@@ -276,8 +278,9 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     @VsrTest(requirements = {"VSR-7.1-001.006"})
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.005"})
     public void vmAttestationWithVendorPartitionWhenSupported() throws Exception {
         // pVM remote attestation is only supported on protected VMs.
         assumeProtectedVM();
@@ -294,8 +297,9 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     @VsrTest(requirements = {"VSR-7.1-001.006"})
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.005"})
     public void vmAttestationWhenRemoteAttestationIsSupported() throws Exception {
         // pVM remote attestation is only supported on protected VMs.
         assumeProtectedVM();
@@ -340,7 +344,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     public void createAndRunNoDebugVm() throws Exception {
         assumeSupportedDevice();
 
@@ -361,7 +365,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void autoCloseVm() throws Exception {
         assumeSupportedDevice();
 
@@ -391,7 +395,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void autoCloseVmDescriptor() throws Exception {
         VirtualMachineConfig config =
                 newVmConfigBuilderWithPayloadBinary("MicrodroidTestNativeLib.so")
@@ -420,7 +424,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void vmDescriptorClosedOnImport() throws Exception {
         VirtualMachineConfig config =
                 newVmConfigBuilderWithPayloadBinary("MicrodroidTestNativeLib.so")
@@ -443,7 +447,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void vmLifecycleChecks() throws Exception {
         assumeSupportedDevice();
 
@@ -491,7 +495,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void connectVsock() throws Exception {
         assumeSupportedDevice();
 
@@ -529,7 +533,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void binderCallbacksWork() throws Exception {
         assumeSupportedDevice();
 
@@ -581,7 +585,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void vmConfigGetAndSetTests() {
         // Minimal has as little as specified as possible; everything that can be is defaulted.
         VirtualMachineConfig.Builder minimalBuilder =
@@ -650,7 +654,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void vmConfigBuilderValidationTests() {
         VirtualMachineConfig.Builder builder =
                 new VirtualMachineConfig.Builder(getContext()).setProtectedVm(mProtectedVm);
@@ -700,7 +704,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void compatibleConfigTests() {
         VirtualMachineConfig baseline = newBaselineBuilder().build();
 
@@ -787,7 +791,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void vmUnitTests() throws Exception {
         VirtualMachineConfig.Builder builder = newVmConfigBuilderWithPayloadBinary("binary.so");
         VirtualMachineConfig config = builder.build();
@@ -808,7 +812,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void testAvfRequiresUpdatableApex() throws Exception {
         assertWithMessage("Devices that support AVF must also support updatable APEX")
                 .that(SystemProperties.getBoolean("ro.apex.updatable", false))
@@ -816,7 +820,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void vmmGetAndCreate() throws Exception {
         assumeSupportedDevice();
 
@@ -863,7 +867,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void vmFilesStoredInDeDirWhenCreatedFromDEContext() throws Exception {
         final Context ctx = getContext().createDeviceProtectedStorageContext();
         final int userId = ctx.getUserId();
@@ -881,7 +885,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void vmFilesStoredInCeDirWhenCreatedFromCEContext() throws Exception {
         final Context ctx = getContext().createCredentialProtectedStorageContext();
         final int userId = ctx.getUserId();
@@ -898,7 +902,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void differentManagersForDifferentContexts() throws Exception {
         final Context ceCtx = getContext().createCredentialProtectedStorageContext();
         final Context deCtx = getContext().createDeviceProtectedStorageContext();
@@ -907,12 +911,7 @@
     }
 
     @Test
-    @CddTest(
-            requirements = {
-                "9.17/C-1-1",
-                "9.17/C-1-2",
-                "9.17/C-1-4",
-            })
+    @CddTest
     public void createVmWithConfigRequiresPermission() throws Exception {
         assumeSupportedDevice();
         revokePermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
@@ -934,10 +933,7 @@
     }
 
     @Test
-    @CddTest(
-            requirements = {
-                "9.17/C-1-1",
-            })
+    @CddTest
     public void deleteVm() throws Exception {
         assumeSupportedDevice();
 
@@ -961,10 +957,7 @@
     }
 
     @Test
-    @CddTest(
-            requirements = {
-                "9.17/C-1-1",
-            })
+    @CddTest
     public void deleteVmFiles() throws Exception {
         assumeSupportedDevice();
 
@@ -994,10 +987,7 @@
     }
 
     @Test
-    @CddTest(
-            requirements = {
-                "9.17/C-1-1",
-            })
+    @CddTest
     public void validApkPathIsAccepted() throws Exception {
         assumeSupportedDevice();
 
@@ -1022,7 +1012,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void invalidVmNameIsRejected() {
         VirtualMachineManager vmm = getVirtualMachineManager();
         assertThrows(IllegalArgumentException.class, () -> vmm.get("../foo"));
@@ -1030,7 +1020,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     public void extraApk() throws Exception {
         assumeSupportedDevice();
 
@@ -1055,7 +1045,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     public void extraApkInVmConfig() throws Exception {
         assumeSupportedDevice();
         assumeFeatureEnabled(VirtualMachineManager.FEATURE_MULTI_TENANT);
@@ -1114,7 +1104,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-7"})
+    @CddTest
     public void changingNonDebuggableVmDebuggableInvalidatesVmIdentity() throws Exception {
         // Debuggability changes initrd which is verified by pvmfw.
         // Therefore, skip this on non-protected VM.
@@ -1168,7 +1158,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-7"})
+    @CddTest
     public void changingDebuggableVmNonDebuggableInvalidatesVmIdentity() throws Exception {
         // Debuggability changes initrd which is verified by pvmfw.
         // Therefore, skip this on non-protected VM.
@@ -1249,7 +1239,8 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-7", "9.17/C-3-4"})
+    @CddTest
+    @GmsTest(requirements = {"GMS-3-7.1-011"})
     public void instancesOfSameVmHaveDifferentCdis() throws Exception {
         assumeSupportedDevice();
         // TODO(b/325094712): VMs on CF with same payload have the same secret. This is because
@@ -1276,7 +1267,8 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-7", "9.17/C-3-4"})
+    @CddTest
+    @GmsTest(requirements = {"GMS-3-7.1-011"})
     public void sameInstanceKeepsSameCdis() throws Exception {
         assumeSupportedDevice();
         assume().withMessage("Skip on CF. Too Slow. b/257270529").that(isCuttlefish()).isFalse();
@@ -1297,8 +1289,9 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-7"})
+    @CddTest
     @VsrTest(requirements = {"VSR-7.1-001.005"})
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.004"})
     public void bccIsSuperficiallyWellFormed() throws Exception {
         assumeSupportedDevice();
 
@@ -1344,6 +1337,7 @@
 
     @Test
     @VsrTest(requirements = {"VSR-7.1-001.005"})
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.004"})
     public void protectedVmHasValidDiceChain() throws Exception {
         // This test validates two things regarding the pVM DICE chain:
         // 1. The DICE chain is well-formed that all the entries conform to the DICE spec.
@@ -1377,7 +1371,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-1-2"})
+    @CddTest
     public void accessToCdisIsRestricted() throws Exception {
         assumeSupportedDevice();
 
@@ -1454,7 +1448,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-7"})
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void bootFailsWhenMicrodroidDataIsCompromised() throws Exception {
         // If Updatable VM is supported => No instance.img required
         assumeNoUpdatableVmSupport();
@@ -1462,7 +1456,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-7"})
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void bootFailsWhenPvmFwDataIsCompromised() throws Exception {
         // If Updatable VM is supported => No instance.img required
         assumeNoUpdatableVmSupport();
@@ -1475,6 +1469,7 @@
     }
 
     @Test
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void bootFailsWhenConfigIsInvalid() throws Exception {
         grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
         VirtualMachineConfig config =
@@ -1489,6 +1484,7 @@
     }
 
     @Test
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void bootFailsWhenBinaryNameIsInvalid() throws Exception {
         VirtualMachineConfig config =
                 newVmConfigBuilderWithPayloadBinary("DoesNotExist.so")
@@ -1502,6 +1498,7 @@
     }
 
     @Test
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void bootFailsWhenApkPathIsInvalid() {
         VirtualMachineConfig config =
                 newVmConfigBuilderWithPayloadBinary("MicrodroidTestNativeLib.so")
@@ -1515,6 +1512,7 @@
     }
 
     @Test
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void bootFailsWhenExtraApkPackageIsInvalid() {
         VirtualMachineConfig config =
                 newVmConfigBuilderWithPayloadBinary("MicrodroidTestNativeLib.so")
@@ -1558,6 +1556,7 @@
     }
 
     @Test
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void bootFailsWhenBinaryIsMissingEntryFunction() throws Exception {
         VirtualMachineConfig normalConfig =
                 newVmConfigBuilderWithPayloadBinary("MicrodroidEmptyNativeLib.so")
@@ -1570,6 +1569,7 @@
     }
 
     @Test
+    @GmsTest(requirements = {"GMS-3-7.1-006"})
     public void bootFailsWhenBinaryTriesToLinkAgainstPrivateLibs() throws Exception {
         VirtualMachineConfig normalConfig =
                 newVmConfigBuilderWithPayloadBinary("MicrodroidPrivateLinkingNativeLib.so")
@@ -1582,6 +1582,7 @@
     }
 
     @Test
+    @CddTest
     public void sameInstancesShareTheSameVmObject() throws Exception {
         VirtualMachineConfig config =
                 newVmConfigBuilderWithPayloadBinary("MicrodroidTestNativeLib.so").build();
@@ -1598,6 +1599,7 @@
     }
 
     @Test
+    @CddTest
     public void importedVmAndOriginalVmHaveTheSameCdi() throws Exception {
         assumeSupportedDevice();
         // Arrange
@@ -1693,7 +1695,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void encryptedStorageAvailable() throws Exception {
         assumeSupportedDevice();
 
@@ -1716,7 +1718,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void encryptedStorageIsInaccessibleToDifferentVm() throws Exception {
         assumeSupportedDevice();
         // TODO(b/325094712): VMs on CF with same payload have the same secret. This is because
@@ -1781,7 +1783,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
+    @CddTest
     public void microdroidLauncherHasEmptyCapabilities() throws Exception {
         assumeSupportedDevice();
 
@@ -1805,7 +1807,8 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
+    @GmsTest(requirements = {"GMS-3-7.1-005"})
     public void payloadIsNotRoot() throws Exception {
         assumeSupportedDevice();
         assumeFeatureEnabled(VirtualMachineManager.FEATURE_MULTI_TENANT);
@@ -1828,7 +1831,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-1"})
+    @CddTest
     public void encryptedStorageIsPersistent() throws Exception {
         assumeSupportedDevice();
 
@@ -1863,6 +1866,122 @@
         assertThat(testResults.mFileContent).isEqualTo(EXAMPLE_STRING);
     }
 
+    private boolean deviceCapableOfProtectedVm() {
+        int capabilities = getVirtualMachineManager().getCapabilities();
+        if ((capabilities & CAPABILITY_PROTECTED_VM) != 0) {
+            return true;
+        }
+        return false;
+    }
+
+    private void ensureUpdatableVmSupported() throws Exception {
+        if (getVendorApiLevel() >= 202504 && deviceCapableOfProtectedVm()) {
+            assertTrue(
+                    "Missing Updatable VM support, have you declared Secretkeeper interface?",
+                    isUpdatableVmSupported());
+        } else {
+            assumeTrue("Device does not support Updatable VM", isUpdatableVmSupported());
+        }
+    }
+
+    @Test
+    public void rollbackProtectedDataOfPayload() throws Exception {
+        assumeSupportedDevice();
+        // Rollback protected data is only possible if Updatable VMs is supported -
+        // which implies Secretkeeper support.
+        ensureUpdatableVmSupported();
+        byte[] value1 = new byte[32];
+        Arrays.fill(value1, (byte) 0xcc);
+        byte[] value2 = new byte[32];
+        Arrays.fill(value2, (byte) 0xdd);
+
+        VirtualMachineConfig config =
+                newVmConfigBuilderWithPayloadBinary("MicrodroidTestNativeLib.so")
+                        .setMemoryBytes(minMemoryRequired())
+                        .setEncryptedStorageBytes(ENCRYPTED_STORAGE_BYTES)
+                        .setDebugLevel(DEBUG_LEVEL_FULL)
+                        .build();
+        VirtualMachine vm = forceCreateNewVirtualMachine("test_vm", config);
+        TestResults testResults =
+                runVmTestService(
+                        TAG,
+                        vm,
+                        (ts, tr) -> {
+                            tr.mPayloadRpData = ts.insecurelyReadPayloadRpData();
+                        });
+        // ainsecurelyReadPayloadRpData()` must've failed since no data was ever written!
+        assertWithMessage("The read (unexpectedly) succeeded!")
+                .that(testResults.mException)
+                .isNotNull();
+
+        // Re-run the same VM & write/read th RP data & verify it what we just wrote!
+        testResults =
+                runVmTestService(
+                        TAG,
+                        vm,
+                        (ts, tr) -> {
+                            ts.insecurelyWritePayloadRpData(value1);
+                            tr.mPayloadRpData = ts.insecurelyReadPayloadRpData();
+                            ts.insecurelyWritePayloadRpData(value2);
+                        });
+        testResults.assertNoException();
+        assertThat(testResults.mPayloadRpData).isEqualTo(value1);
+
+        // Re-run the same VM again
+        testResults =
+                runVmTestService(
+                        TAG,
+                        vm,
+                        (ts, tr) -> {
+                            tr.mPayloadRpData = ts.insecurelyReadPayloadRpData();
+                        });
+        testResults.assertNoException();
+        assertThat(testResults.mPayloadRpData).isEqualTo(value2);
+    }
+
+    @Test
+    @CddTest
+    public void isNewInstanceTest() throws Exception {
+        assumeSupportedDevice();
+
+        VirtualMachineConfig config =
+                newVmConfigBuilderWithPayloadBinary("MicrodroidTestNativeLib.so")
+                        .setMemoryBytes(minMemoryRequired())
+                        .setDebugLevel(DEBUG_LEVEL_FULL)
+                        .build();
+        // TODO(b/325094712): Cuttlefish doesn't support device tree overlays which is required to
+        // find if the VM run is a new instance.
+        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(
+                        TAG,
+                        vm,
+                        (ts, tr) -> {
+                            tr.mIsNewInstance = ts.isNewInstance();
+                        });
+        testResults.assertNoException();
+        assertThat(testResults.mIsNewInstance).isTrue();
+
+        // Re-run the same VM & ensure isNewInstance is false.
+        testResults =
+                runVmTestService(
+                        TAG,
+                        vm,
+                        (ts, tr) -> {
+                            tr.mIsNewInstance = ts.isNewInstance();
+                        });
+        testResults.assertNoException();
+        assertThat(testResults.mIsNewInstance).isFalse();
+    }
+
     @Test
     @CddTest(requirements = {"9.17/C-1-1", "9.17/C-2-1"})
     public void canReadFileFromAssets_debugFull() throws Exception {
@@ -1888,6 +2007,7 @@
     }
 
     @Test
+    @CddTest
     public void outputShouldBeExplicitlyCaptured() throws Exception {
         assumeSupportedDevice();
 
@@ -1910,6 +2030,7 @@
     }
 
     @Test
+    @CddTest
     public void inputShouldBeExplicitlyAllowed() throws Exception {
         assumeSupportedDevice();
 
@@ -1961,6 +2082,7 @@
     }
 
     @Test
+    @CddTest
     public void outputIsRedirectedToLogcatIfNotCaptured() throws Exception {
         assumeSupportedDevice();
 
@@ -1981,6 +2103,7 @@
     }
 
     @Test
+    @CddTest
     public void outputIsNotRedirectedToLogcatIfNotDebuggable() throws Exception {
         assumeSupportedDevice();
 
@@ -1991,6 +2114,7 @@
     }
 
     @Test
+    @CddTest
     public void testConsoleInputSupported() throws Exception {
         assumeSupportedDevice();
         assumeFalse("Not supported on GKI kernels", mOs.startsWith("microdroid_gki-"));
@@ -2020,6 +2144,7 @@
     }
 
     @Test
+    @CddTest
     public void testStartVmWithPayloadOfAnotherApp() throws Exception {
         assumeSupportedDevice();
 
@@ -2049,6 +2174,7 @@
     }
 
     @Test
+    @CddTest
     public void testVmDescriptorParcelUnparcel_noTrustedStorage() throws Exception {
         assumeSupportedDevice();
 
@@ -2082,6 +2208,7 @@
     }
 
     @Test
+    @CddTest
     public void testVmDescriptorParcelUnparcel_withTrustedStorage() throws Exception {
         assumeSupportedDevice();
 
@@ -2135,6 +2262,7 @@
     }
 
     @Test
+    @CddTest
     public void testShareVmWithAnotherApp() throws Exception {
         assumeSupportedDevice();
 
@@ -2180,6 +2308,7 @@
     }
 
     @Test
+    @CddTest
     public void testShareVmWithAnotherApp_encryptedStorage() throws Exception {
         assumeSupportedDevice();
 
@@ -2249,7 +2378,8 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-5"})
+    @CddTest
+    @GmsTest(requirements = {"GMS-3-7.1-005"})
     public void testFileUnderBinHasExecutePermission() throws Exception {
         assumeSupportedDevice();
 
@@ -2292,7 +2422,7 @@
     private static final int MS_NOATIME = 1024;
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-5"})
+    @GmsTest(requirements = {"GMS-3-7.1-004", "GMS-3-7.1-005"})
     public void dataIsMountedWithNoExec() throws Exception {
         assumeSupportedDevice();
 
@@ -2317,7 +2447,7 @@
     }
 
     @Test
-    @CddTest(requirements = {"9.17/C-1-5"})
+    @GmsTest(requirements = {"GMS-3-7.1-004", "GMS-3-7.1-005"})
     public void encryptedStoreIsMountedWithNoExec() throws Exception {
         assumeSupportedDevice();
 
@@ -2343,7 +2473,6 @@
     }
 
     @Test
-    @VsrTest(requirements = {"VSR-7.1-001.003"})
     public void kernelVersionRequirement() throws Exception {
         assumeVsrCompliant();
         int firstApiLevel = SystemProperties.getInt("ro.product.first_api_level", 0);
@@ -2445,6 +2574,9 @@
     }
 
     @Test
+    @CddTest
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.007"})
+    @VsrTest(requirements = {"VSR-7.1-001.008"})
     public void configuringVendorDiskImageRequiresCustomPermission() throws Exception {
         File vendorDiskImage =
                 new File("/data/local/tmp/cts/microdroid/test_microdroid_vendor_image.img");
@@ -2462,6 +2594,9 @@
     }
 
     @Test
+    @CddTest
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.007"})
+    @VsrTest(requirements = {"VSR-7.1-001.008"})
     public void bootsWithVendorPartition() throws Exception {
         File vendorDiskImage = new File("/vendor/etc/avf/microdroid/microdroid_vendor.img");
         assumeTrue("Microdroid vendor image doesn't exist, skip", vendorDiskImage.exists());
@@ -2481,6 +2616,9 @@
     }
 
     @Test
+    @CddTest
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.007"})
+    @VsrTest(requirements = {"VSR-7.1-001.008"})
     public void bootsWithCustomVendorPartitionForNonPvm() throws Exception {
         assumeNonProtectedVM();
         File vendorDiskImage =
@@ -2502,6 +2640,9 @@
     }
 
     @Test
+    @CddTest
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.007"})
+    @VsrTest(requirements = {"VSR-7.1-001.008"})
     public void bootFailsWithCustomVendorPartitionForPvm() throws Exception {
         assumeProtectedVM();
         File vendorDiskImage =
@@ -2514,6 +2655,9 @@
     }
 
     @Test
+    @CddTest
+    @GmsTest(requirements = {"GMS-VSR-7.1-001.007"})
+    @VsrTest(requirements = {"VSR-7.1-001.008"})
     public void creationFailsWithUnsignedVendorPartition() throws Exception {
         File vendorDiskImage =
                 new File(
@@ -2526,6 +2670,7 @@
     }
 
     @Test
+    @GmsTest(requirements = {"GMS-3-7.1-004", "GMS-3-7.1-005"})
     public void systemPartitionMountFlags() throws Exception {
         assumeSupportedDevice();
 
diff --git a/tests/testapk/src/native/testbinary.cpp b/tests/testapk/src/native/testbinary.cpp
index 7edabfd..06c7e9d 100644
--- a/tests/testapk/src/native/testbinary.cpp
+++ b/tests/testapk/src/native/testbinary.cpp
@@ -347,6 +347,28 @@
             return ScopedAStatus::ok();
         }
 
+        ScopedAStatus insecurelyReadPayloadRpData(std::array<uint8_t, 32>* out) override {
+            int32_t ret = AVmPayload_readRollbackProtectedSecret(out->data(), 32);
+            if (ret != 32) {
+                return ScopedAStatus::fromServiceSpecificError(ret);
+            }
+            return ScopedAStatus::ok();
+        }
+
+        ScopedAStatus insecurelyWritePayloadRpData(
+                const std::array<uint8_t, 32>& inputData) override {
+            int32_t ret = AVmPayload_writeRollbackProtectedSecret(inputData.data(), 32);
+            if (ret != 32) {
+                return ScopedAStatus::fromServiceSpecificError(ret);
+            }
+            return ScopedAStatus::ok();
+        }
+
+        ScopedAStatus isNewInstance(bool* is_new_instance_out) override {
+            *is_new_instance_out = AVmPayload_isNewInstance();
+            return ScopedAStatus::ok();
+        }
+
         ScopedAStatus quit() override { exit(0); }
     };
     auto testService = ndk::SharedRefBase::make<TestService>();
diff --git a/tests/testapk/src/native/testbinary.rs b/tests/testapk/src/native/testbinary.rs
index 2502113..c9d46b8 100644
--- a/tests/testapk/src/native/testbinary.rs
+++ b/tests/testapk/src/native/testbinary.rs
@@ -24,7 +24,6 @@
     },
     binder::{BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Status, Strong},
 };
-use cstr::cstr;
 use log::{error, info};
 use std::process::exit;
 use std::string::String;
@@ -127,10 +126,19 @@
     fn readLineFromConsole(&self) -> BinderResult<String> {
         unimplemented()
     }
+    fn insecurelyReadPayloadRpData(&self) -> BinderResult<[u8; 32]> {
+        unimplemented()
+    }
+    fn insecurelyWritePayloadRpData(&self, _: &[u8; 32]) -> BinderResult<()> {
+        unimplemented()
+    }
+    fn isNewInstance(&self) -> BinderResult<bool> {
+        unimplemented()
+    }
 }
 
 fn unimplemented<T>() -> BinderResult<T> {
-    let message = cstr!("Got a call to an unimplemented ITestService method in testbinary.rs");
+    let message = c"Got a call to an unimplemented ITestService method in testbinary.rs";
     error!("{message:?}");
     Err(Status::new_exception(ExceptionCode::UNSUPPORTED_OPERATION, Some(message)))
 }
diff --git a/tests/vmshareapp/src/java/com/android/microdroid/test/sharevm/VmShareServiceImpl.java b/tests/vmshareapp/src/java/com/android/microdroid/test/sharevm/VmShareServiceImpl.java
index 13b0c51..1f71888 100644
--- a/tests/vmshareapp/src/java/com/android/microdroid/test/sharevm/VmShareServiceImpl.java
+++ b/tests/vmshareapp/src/java/com/android/microdroid/test/sharevm/VmShareServiceImpl.java
@@ -276,5 +276,20 @@
         public void quit() throws RemoteException {
             throw new UnsupportedOperationException("Not supported");
         }
+
+        @Override
+        public byte[] insecurelyReadPayloadRpData() {
+            throw new UnsupportedOperationException("Not supported");
+        }
+
+        @Override
+        public void insecurelyWritePayloadRpData(byte[] data) {
+            throw new UnsupportedOperationException("Not supported");
+        }
+
+        @Override
+        public boolean isNewInstance() {
+            throw new UnsupportedOperationException("Not supported");
+        }
     }
 }
diff --git a/tests/vts/Android.bp b/tests/vts/Android.bp
index c8e2523..c570873 100644
--- a/tests/vts/Android.bp
+++ b/tests/vts/Android.bp
@@ -33,4 +33,5 @@
     data: [":vts_libavf_test_kernel"],
     test_config: "AndroidTest.xml",
     compile_multilib: "first",
+    vendor: true,
 }
diff --git a/tests/vts/AndroidTest.xml b/tests/vts/AndroidTest.xml
index 75c8d31..6926f9f 100644
--- a/tests/vts/AndroidTest.xml
+++ b/tests/vts/AndroidTest.xml
@@ -20,7 +20,7 @@
 
     <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="vts_libavf_test->/data/nativetest64/vendor/vts_libavf_test" />
         <option name="push" value="rialto.bin->/data/local/tmp/rialto.bin" />
     </target_preparer>
 
@@ -29,7 +29,7 @@
     </object>
 
     <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
-        <option name="test-device-path" value="/data/local/tmp" />
+        <option name="test-device-path" value="/data/nativetest64/vendor" />
         <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" />