Merge "Encryptedstore IO throughput" into main
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 8cb01d7..5dd060a 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -49,6 +49,12 @@
     },
     {
       "name": "vm_accessor_test"
+    },
+    {
+      "name": "avf_backcompat_tests"
+    },
+    {
+      "name": "old_images_avf_test"
     }
   ],
   "avf-postsubmit": [
diff --git a/android/TerminalApp/Android.bp b/android/TerminalApp/Android.bp
index 59f18df..2bac412 100644
--- a/android/TerminalApp/Android.bp
+++ b/android/TerminalApp/Android.bp
@@ -11,12 +11,17 @@
     asset_dirs: ["assets"],
     resource_dirs: ["res"],
     static_libs: [
+        // TODO(b/330257000): will be removed when binder RPC is used
+        "android.system.virtualizationservice_internal-java",
         "androidx-constraintlayout_constraintlayout",
         "androidx.window_window",
         "apache-commons-compress",
+        "avf_aconfig_flags_java",
         "com.google.android.material_material",
         "debian-service-grpclib-lite",
         "gson",
+        // TODO(b/331708504): will be removed when AVF framework handles surface
+        "libcrosvm_android_display_service-java",
         "VmTerminalApp.aidl-java",
         "MicrodroidTestHelper", // for DeviceProperties class
     ],
@@ -36,6 +41,7 @@
         //optimize: true,
         proguard_flags_files: ["proguard.flags"],
         shrink_resources: true,
+        keep_runtime_invisible_annotations: true,
     },
     apex_available: [
         "com.android.virt",
diff --git a/android/TerminalApp/AndroidManifest.xml b/android/TerminalApp/AndroidManifest.xml
index 726004c..c11b1a0 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">
@@ -46,6 +47,11 @@
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
+        <activity android:name=".DisplayActivity"
+            android:screenOrientation="landscape"
+            android:resizeableActivity="false"
+            android:theme="@style/FullscreenTheme"
+            android:configChanges="orientation|screenSize|keyboard|keyboardHidden|navigation|uiMode|screenLayout|smallestScreenSize" />
         <activity android:name=".SettingsActivity"
             android:label="@string/action_settings" />
         <activity android:name=".SettingsDiskResizeActivity"
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/DisplayActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/DisplayActivity.kt
new file mode 100644
index 0000000..290cf5a
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/DisplayActivity.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.os.Bundle
+import android.system.virtualmachine.VirtualMachineManager
+import android.view.SurfaceView
+import android.view.WindowInsets
+import android.view.WindowInsetsController
+
+class DisplayActivity : BaseActivity() {
+    private lateinit var displayProvider: DisplayProvider
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_display)
+        val mainView = findViewById<SurfaceView>(R.id.surface_view)
+        val cursorView = findViewById<SurfaceView>(R.id.cursor_surface_view)
+        makeFullscreen()
+        // Connect the views to the VM
+        displayProvider = DisplayProvider(mainView, cursorView)
+        val vmm =
+            applicationContext.getSystemService<VirtualMachineManager>(
+                VirtualMachineManager::class.java
+            )
+        val debianVm = vmm.get("debian")
+        if (debianVm != null) {
+            InputForwarder(
+                this,
+                debianVm,
+                findViewById(R.id.background_touch_view),
+                findViewById(R.id.surface_view),
+                findViewById(R.id.surface_view),
+            )
+        }
+    }
+
+    override fun onPause() {
+        super.onPause()
+        displayProvider.notifyDisplayIsGoingToInvisible()
+    }
+
+    private fun makeFullscreen() {
+        val w = window
+        w.setDecorFitsSystemWindows(false)
+        val insetsCtrl = w.insetsController
+        insetsCtrl?.hide(WindowInsets.Type.systemBars())
+        insetsCtrl?.setSystemBarsBehavior(
+            WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
+        )
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/DisplayProvider.kt b/android/TerminalApp/java/com/android/virtualization/terminal/DisplayProvider.kt
new file mode 100644
index 0000000..a04e056
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/DisplayProvider.kt
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.virtualization.terminal
+
+import android.crosvm.ICrosvmAndroidDisplayService
+import android.graphics.PixelFormat
+import android.os.ParcelFileDescriptor
+import android.os.RemoteException
+import android.os.ServiceManager
+import android.system.virtualizationservice_internal.IVirtualizationServiceInternal
+import android.util.Log
+import android.view.SurfaceControl
+import android.view.SurfaceHolder
+import android.view.SurfaceView
+import com.android.virtualization.terminal.DisplayProvider.CursorHandler
+import com.android.virtualization.terminal.MainActivity.Companion.TAG
+import java.io.IOException
+import java.lang.Exception
+import java.lang.RuntimeException
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+import libcore.io.IoBridge
+
+/** Provides Android-side surface from given SurfaceView to a VM instance as a display for that */
+internal class DisplayProvider(
+    private val mainView: SurfaceView,
+    private val cursorView: SurfaceView,
+) {
+    private val virtService: IVirtualizationServiceInternal by lazy {
+        val b = ServiceManager.waitForService("android.system.virtualizationservice")
+        IVirtualizationServiceInternal.Stub.asInterface(b)
+    }
+    private var cursorHandler: CursorHandler? = null
+
+    init {
+        mainView.setSurfaceLifecycle(SurfaceView.SURFACE_LIFECYCLE_FOLLOWS_ATTACHMENT)
+        mainView.holder.addCallback(Callback(SurfaceKind.MAIN))
+        cursorView.setSurfaceLifecycle(SurfaceView.SURFACE_LIFECYCLE_FOLLOWS_ATTACHMENT)
+        cursorView.holder.addCallback(Callback(SurfaceKind.CURSOR))
+        cursorView.holder.setFormat(PixelFormat.RGBA_8888)
+        // TODO: do we need this z-order?
+        cursorView.setZOrderMediaOverlay(true)
+    }
+
+    fun notifyDisplayIsGoingToInvisible() {
+        // When the display is going to be invisible (by putting in the background), save the frame
+        // of the main surface so that we can re-draw it next time the display becomes visible. This
+        // is to save the duration of time where nothing is drawn by VM.
+        try {
+            getDisplayService().saveFrameForSurface(false /* forCursor */)
+        } catch (e: RemoteException) {
+            throw RuntimeException("Failed to save frame for the main surface", e)
+        }
+    }
+
+    @Synchronized
+    private fun getDisplayService(): ICrosvmAndroidDisplayService {
+        try {
+            val b = virtService.waitDisplayService()
+            return ICrosvmAndroidDisplayService.Stub.asInterface(b)
+        } catch (e: Exception) {
+            throw RuntimeException("Error while getting display service", e)
+        }
+    }
+
+    enum class SurfaceKind {
+        MAIN,
+        CURSOR,
+    }
+
+    inner class Callback(private val surfaceKind: SurfaceKind) : SurfaceHolder.Callback {
+        fun isForCursor(): Boolean {
+            return surfaceKind == SurfaceKind.CURSOR
+        }
+
+        override fun surfaceCreated(holder: SurfaceHolder) {
+            try {
+                getDisplayService().setSurface(holder.getSurface(), isForCursor())
+            } catch (e: Exception) {
+                // TODO: don't consume this exception silently. For some unknown reason, setSurface
+                // call above throws IllegalArgumentException and that fails the surface
+                // configuration.
+                Log.e(TAG, "Failed to present surface $surfaceKind to VM", e)
+            }
+            try {
+                when (surfaceKind) {
+                    SurfaceKind.MAIN -> getDisplayService().drawSavedFrameForSurface(isForCursor())
+                    SurfaceKind.CURSOR -> {
+                        val stream = createNewCursorStream()
+                        getDisplayService().setCursorStream(stream)
+                    }
+                }
+            } catch (e: Exception) {
+                // TODO: don't consume exceptions here too
+                Log.e(TAG, "Failed to configure surface $surfaceKind", e)
+            }
+        }
+
+        override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
+            // TODO: support resizeable display. We could actually change the display size that the
+            // VM sees, or keep the size and render it by fitting it in the new surface.
+        }
+
+        override fun surfaceDestroyed(holder: SurfaceHolder) {
+            try {
+                getDisplayService().removeSurface(isForCursor())
+            } catch (e: RemoteException) {
+                throw RuntimeException("Error while destroying surface for $surfaceKind", e)
+            }
+        }
+    }
+
+    private fun createNewCursorStream(): ParcelFileDescriptor? {
+        cursorHandler?.interrupt()
+        var pfds: Array<ParcelFileDescriptor> =
+            try {
+                ParcelFileDescriptor.createSocketPair()
+            } catch (e: IOException) {
+                throw RuntimeException("Failed to create socketpair for cursor stream", e)
+            }
+        cursorHandler = CursorHandler(pfds[0]).also { it.start() }
+        return pfds[1]
+    }
+
+    /**
+     * Thread reading cursor coordinate from a stream, and updating the position of the cursor
+     * surface accordingly.
+     */
+    private inner class CursorHandler(private val stream: ParcelFileDescriptor) : Thread() {
+        private val cursor: SurfaceControl = this@DisplayProvider.cursorView.surfaceControl
+        private val transaction: SurfaceControl.Transaction = SurfaceControl.Transaction()
+
+        init {
+            val main = this@DisplayProvider.mainView.surfaceControl
+            transaction.reparent(cursor, main).apply()
+        }
+
+        override fun run() {
+            try {
+                val byteBuffer = ByteBuffer.allocate(8 /* (x: u32, y: u32) */)
+                byteBuffer.order(ByteOrder.LITTLE_ENDIAN)
+                while (true) {
+                    if (interrupted()) {
+                        Log.d(TAG, "CursorHandler thread interrupted!")
+                        return
+                    }
+                    byteBuffer.clear()
+                    val bytes =
+                        IoBridge.read(
+                            stream.fileDescriptor,
+                            byteBuffer.array(),
+                            0,
+                            byteBuffer.array().size,
+                        )
+                    if (bytes == -1) {
+                        Log.e(TAG, "cannot read from cursor stream, stop the handler")
+                        return
+                    }
+                    val x = (byteBuffer.getInt() and -0x1).toFloat()
+                    val y = (byteBuffer.getInt() and -0x1).toFloat()
+                    transaction.setPosition(cursor, x, y).apply()
+                }
+            } catch (e: IOException) {
+                Log.e(TAG, "failed to run CursorHandler", e)
+            }
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InputForwarder.kt b/android/TerminalApp/java/com/android/virtualization/terminal/InputForwarder.kt
new file mode 100644
index 0000000..117ce94
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InputForwarder.kt
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.virtualization.terminal
+
+import android.content.Context
+import android.hardware.input.InputManager
+import android.os.Handler
+import android.system.virtualmachine.VirtualMachine
+import android.util.Log
+import android.view.InputDevice
+import android.view.KeyEvent
+import android.view.MotionEvent
+import android.view.View
+import com.android.virtualization.terminal.MainActivity.Companion.TAG
+
+/** Forwards input events (touch, mouse, ...) from Android to VM */
+internal class InputForwarder(
+    private val context: Context,
+    vm: VirtualMachine,
+    touchReceiver: View,
+    mouseReceiver: View,
+    keyReceiver: View,
+) {
+    private val virtualMachine: VirtualMachine = vm
+    private var inputDeviceListener: InputManager.InputDeviceListener? = null
+    private var isTabletMode = false
+
+    init {
+        val config = vm.config.customImageConfig
+
+        checkNotNull(config)
+
+        if (config.useTouch() == true) {
+            setupTouchReceiver(touchReceiver)
+        }
+        if (config.useMouse() || config.useTrackpad()) {
+            setupMouseReceiver(mouseReceiver)
+        }
+        if (config.useKeyboard()) {
+            setupKeyReceiver(keyReceiver)
+        }
+        if (config.useSwitches()) {
+            // Any view's handler is fine.
+            setupTabletModeHandler(touchReceiver.getHandler())
+        }
+    }
+
+    fun cleanUp() {
+        if (inputDeviceListener != null) {
+            val im = context.getSystemService<InputManager>(InputManager::class.java)
+            im.unregisterInputDeviceListener(inputDeviceListener)
+            inputDeviceListener = null
+        }
+    }
+
+    private fun setupTouchReceiver(receiver: View) {
+        receiver.setOnTouchListener(
+            View.OnTouchListener { v: View?, event: MotionEvent? ->
+                virtualMachine.sendMultiTouchEvent(event)
+            }
+        )
+    }
+
+    private fun setupMouseReceiver(receiver: View) {
+        receiver.requestUnbufferedDispatch(InputDevice.SOURCE_ANY)
+        receiver.setOnCapturedPointerListener { v: View?, event: MotionEvent? ->
+            val eventSource = event!!.source
+            if ((eventSource and InputDevice.SOURCE_CLASS_POSITION) != 0) {
+                return@setOnCapturedPointerListener virtualMachine.sendTrackpadEvent(event)
+            }
+            virtualMachine.sendMouseEvent(event)
+        }
+    }
+
+    private fun setupKeyReceiver(receiver: View) {
+        receiver.setOnKeyListener { v: View?, code: Int, event: KeyEvent? ->
+            // TODO: this is guest-os specific. It shouldn't be handled here.
+            if (isVolumeKey(code)) {
+                return@setOnKeyListener false
+            }
+            virtualMachine.sendKeyEvent(event)
+        }
+    }
+
+    private fun setupTabletModeHandler(handler: Handler?) {
+        val im = context.getSystemService<InputManager?>(InputManager::class.java)
+        inputDeviceListener =
+            object : InputManager.InputDeviceListener {
+                override fun onInputDeviceAdded(deviceId: Int) {
+                    setTabletModeConditionally()
+                }
+
+                override fun onInputDeviceRemoved(deviceId: Int) {
+                    setTabletModeConditionally()
+                }
+
+                override fun onInputDeviceChanged(deviceId: Int) {
+                    setTabletModeConditionally()
+                }
+            }
+        im!!.registerInputDeviceListener(inputDeviceListener, handler)
+    }
+
+    fun setTabletModeConditionally() {
+        val tabletModeNeeded = !hasPhysicalKeyboard()
+        if (tabletModeNeeded != isTabletMode) {
+            val mode = if (tabletModeNeeded) "tablet mode" else "desktop mode"
+            Log.d(TAG, "switching to $mode")
+            isTabletMode = tabletModeNeeded
+            virtualMachine.sendTabletModeEvent(tabletModeNeeded)
+        }
+    }
+
+    companion object {
+        private fun isVolumeKey(keyCode: Int): Boolean {
+            return keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+                keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
+                keyCode == KeyEvent.KEYCODE_VOLUME_MUTE
+        }
+
+        private fun hasPhysicalKeyboard(): Boolean {
+            for (id in InputDevice.getDeviceIds()) {
+                val d = InputDevice.getDevice(id)
+                if (!d!!.isVirtual && d.isEnabled && d.isFullKeyboard) {
+                    return true
+                }
+            }
+            return false
+        }
+    }
+}
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 bf2f573..1daeadb 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.kt
@@ -35,12 +35,14 @@
 import android.os.SystemProperties
 import android.os.Trace
 import android.provider.Settings
+import android.util.DisplayMetrics
 import android.util.Log
 import android.view.KeyEvent
 import android.view.Menu
 import android.view.MenuItem
 import android.view.View
 import android.view.ViewGroup
+import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
 import android.webkit.ClientCertRequest
 import android.webkit.SslErrorHandler
@@ -56,6 +58,7 @@
 import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
 import com.android.internal.annotations.VisibleForTesting
 import com.android.microdroid.test.common.DeviceProperties
+import com.android.system.virtualmachine.flags.Flags.terminalGuiSupport
 import com.android.virtualization.terminal.CertificateUtils.createOrGetKey
 import com.android.virtualization.terminal.CertificateUtils.writeCertificateToFile
 import com.android.virtualization.terminal.ErrorActivity.Companion.start
@@ -87,6 +90,7 @@
     private val bootCompleted = ConditionVariable()
     private lateinit var manageExternalStorageActivityResultLauncher: ActivityResultLauncher<Intent>
     private lateinit var modifierKeysController: ModifierKeysController
+    private var displayMenu: MenuItem? = null
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -209,7 +213,10 @@
                     view: WebView?,
                     request: WebResourceRequest?,
                 ): Boolean {
-                    return false
+                    val intent = Intent(Intent.ACTION_VIEW, request?.url)
+                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                    startActivity(intent)
+                    return true
                 }
 
                 override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
@@ -253,6 +260,10 @@
                                     Trace.endAsyncSection("executeTerminal", 0)
                                     findViewById<View?>(R.id.boot_progress).visibility = View.GONE
                                     terminalContainer.visibility = View.VISIBLE
+                                    if (terminalGuiSupport()) {
+                                        displayMenu?.setVisible(true)
+                                        displayMenu?.setEnabled(true)
+                                    }
                                     bootCompleted.open()
                                     modifierKeysController.update()
                                     terminalView.mapTouchToMouseEvent()
@@ -293,6 +304,8 @@
             info,
             executorService,
             object : NsdManager.ServiceInfoCallback {
+                var loaded: Boolean = false
+
                 override fun onServiceInfoCallbackRegistrationFailed(errorCode: Int) {}
 
                 override fun onServiceInfoCallbackUnregistered() {}
@@ -300,13 +313,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()) })
+                    }
                 }
             },
         )
@@ -337,6 +352,11 @@
 
     override fun onCreateOptionsMenu(menu: Menu?): Boolean {
         menuInflater.inflate(R.menu.main_menu, menu)
+        displayMenu =
+            menu?.findItem(R.id.menu_item_display).also {
+                it?.setVisible(terminalGuiSupport())
+                it?.setEnabled(false)
+            }
         return true
     }
 
@@ -346,6 +366,10 @@
             val intent = Intent(this, SettingsActivity::class.java)
             this.startActivity(intent)
             return true
+        } else if (id == R.id.menu_item_display) {
+            val intent = Intent(this, DisplayActivity::class.java)
+            this.startActivity(intent)
+            return true
         }
         return super.onOptionsItemSelected(item)
     }
@@ -409,7 +433,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))
@@ -435,7 +459,7 @@
                 .build()
 
         Trace.beginAsyncSection("executeTerminal", 0)
-        run(this, this, notification)
+        run(this, this, notification, getDisplayInfo())
         connectToTerminalService()
     }
 
@@ -489,4 +513,18 @@
                 R.id.btn_pgdn to KeyEvent.KEYCODE_PAGE_DOWN,
             )
     }
+
+    fun getDisplayInfo(): DisplayInfo {
+        val wm = getSystemService<WindowManager>(WindowManager::class.java)
+        val metrics = wm.currentWindowMetrics
+        val dispBounds = metrics.bounds
+
+        // For now, display activity runs as landscape mode
+        val height = Math.min(dispBounds.right, dispBounds.bottom)
+        val width = Math.max(dispBounds.right, dispBounds.bottom)
+        var dpi = (DisplayMetrics.DENSITY_DEFAULT * metrics.density).toInt()
+        var refreshRate = display.refreshRate.toInt()
+
+        return DisplayInfo(width, height, dpi, refreshRate)
+    }
 }
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..ecb01c0 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.kt
@@ -29,6 +29,7 @@
 import android.os.IBinder
 import android.os.Looper
 import android.os.Parcel
+import android.os.Parcelable
 import android.os.ResultReceiver
 import android.os.Trace
 import android.system.virtualmachine.VirtualMachine
@@ -36,6 +37,7 @@
 import android.system.virtualmachine.VirtualMachineException
 import android.util.Log
 import android.widget.Toast
+import com.android.system.virtualmachine.flags.Flags.terminalGuiSupport
 import com.android.virtualization.terminal.MainActivity.Companion.TAG
 import com.android.virtualization.terminal.Runner.Companion.create
 import com.android.virtualization.terminal.VmLauncherService.VmLauncherServiceCallback
@@ -102,7 +104,8 @@
         val json = ConfigJson.from(this, image.configPath)
         val configBuilder = json.toConfigBuilder(this)
         val customImageConfigBuilder = json.toCustomImageConfigBuilder(this)
-        if (overrideConfigIfNecessary(customImageConfigBuilder)) {
+        val displaySize = intent.getParcelableExtra(EXTRA_DISPLAY_INFO, DisplayInfo::class.java)
+        if (overrideConfigIfNecessary(customImageConfigBuilder, displaySize)) {
             configBuilder.setCustomImageConfig(customImageConfigBuilder.build())
         }
         val config = configBuilder.build()
@@ -149,6 +152,8 @@
             info,
             executorService!!,
             object : NsdManager.ServiceInfoCallback {
+                var started: Boolean = false
+
                 override fun onServiceInfoCallbackRegistrationFailed(errorCode: Int) {}
 
                 override fun onServiceInfoCallbackUnregistered() {}
@@ -156,9 +161,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 +190,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)
@@ -192,7 +200,8 @@
     }
 
     private fun overrideConfigIfNecessary(
-        builder: VirtualMachineCustomImageConfig.Builder
+        builder: VirtualMachineCustomImageConfig.Builder,
+        displayInfo: DisplayInfo?,
     ): Boolean {
         var changed = false
         // TODO: check if ANGLE is enabled for the app.
@@ -212,6 +221,25 @@
             changed = true
         }
 
+        // Set the initial display size
+        // TODO(jeongik): set up the display size on demand
+        if (terminalGuiSupport() && displayInfo != null) {
+            builder
+                .setDisplayConfig(
+                    VirtualMachineCustomImageConfig.DisplayConfig.Builder()
+                        .setWidth(displayInfo.width)
+                        .setHeight(displayInfo.height)
+                        .setHorizontalDpi(displayInfo.dpi)
+                        .setVerticalDpi(displayInfo.dpi)
+                        .setRefreshRate(displayInfo.refreshRate)
+                        .build()
+                )
+                .useKeyboard(true)
+                .useMouse(true)
+                .useTouch(true)
+            changed = true
+        }
+
         val image = InstalledImage.getDefault(this)
         if (image.hasBackup()) {
             val backup = image.backupFile
@@ -301,7 +329,7 @@
         private const val EXTRA_NOTIFICATION = "EXTRA_NOTIFICATION"
         private const val ACTION_START_VM_LAUNCHER_SERVICE =
             "android.virtualization.START_VM_LAUNCHER_SERVICE"
-
+        const val EXTRA_DISPLAY_INFO = "EXTRA_DISPLAY_INFO"
         const val ACTION_STOP_VM_LAUNCHER_SERVICE: String =
             "android.virtualization.STOP_VM_LAUNCHER_SERVICE"
 
@@ -317,6 +345,7 @@
             context: Context,
             callback: VmLauncherServiceCallback?,
             notification: Notification?,
+            displayInfo: DisplayInfo,
         ) {
             val i = getMyIntent(context)
             val resultReceiver: ResultReceiver =
@@ -334,6 +363,7 @@
                 }
             i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver))
             i.putExtra(EXTRA_NOTIFICATION, notification)
+            i.putExtra(EXTRA_DISPLAY_INFO, displayInfo)
             context.startForegroundService(i)
         }
 
@@ -351,3 +381,29 @@
         }
     }
 }
+
+data class DisplayInfo(val width: Int, val height: Int, val dpi: Int, val refreshRate: Int) :
+    Parcelable {
+    constructor(
+        source: Parcel
+    ) : this(source.readInt(), source.readInt(), source.readInt(), source.readInt())
+
+    override fun describeContents(): Int = 0
+
+    override fun writeToParcel(dest: Parcel, flags: Int) {
+        dest.writeInt(width)
+        dest.writeInt(height)
+        dest.writeInt(dpi)
+        dest.writeInt(refreshRate)
+    }
+
+    companion object {
+        @JvmField
+        val CREATOR =
+            object : Parcelable.Creator<DisplayInfo> {
+                override fun createFromParcel(source: Parcel): DisplayInfo = DisplayInfo(source)
+
+                override fun newArray(size: Int) = arrayOfNulls<DisplayInfo>(size)
+            }
+    }
+}
diff --git a/android/TerminalApp/proguard.flags b/android/TerminalApp/proguard.flags
index 88b8a9c..04a2140 100644
--- a/android/TerminalApp/proguard.flags
+++ b/android/TerminalApp/proguard.flags
@@ -4,7 +4,10 @@
 -keepattributes Signature
 
 # For using GSON @Expose annotation
--keepattributes *Annotation*
+-keepattributes RuntimeVisibleAnnotations,
+                RuntimeVisibleParameterAnnotations,
+                RuntimeVisibleTypeAnnotations,
+                AnnotationDefault
 
 # Gson specific classes
 -dontwarn sun.misc.**
diff --git a/android/TerminalApp/res/drawable/ic_display.xml b/android/TerminalApp/res/drawable/ic_display.xml
new file mode 100644
index 0000000..86bdb5d
--- /dev/null
+++ b/android/TerminalApp/res/drawable/ic_display.xml
@@ -0,0 +1,26 @@
+<?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.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M240,840L240,760L280,720L160,720Q127,720 103.5,696.5Q80,673 80,640L80,200Q80,167 103.5,143.5Q127,120 160,120L800,120Q833,120 856.5,143.5Q880,167 880,200L880,640Q880,673 856.5,696.5Q833,720 800,720L680,720L720,760L720,840L240,840ZM160,640L800,640Q800,640 800,640Q800,640 800,640L800,200Q800,200 800,200Q800,200 800,200L160,200Q160,200 160,200Q160,200 160,200L160,640Q160,640 160,640Q160,640 160,640ZM160,640Q160,640 160,640Q160,640 160,640L160,200Q160,200 160,200Q160,200 160,200L160,200Q160,200 160,200Q160,200 160,200L160,640Q160,640 160,640Q160,640 160,640Z" />
+</vector>
\ No newline at end of file
diff --git a/android/TerminalApp/res/layout/activity_display.xml b/android/TerminalApp/res/layout/activity_display.xml
new file mode 100644
index 0000000..2d7d847
--- /dev/null
+++ b/android/TerminalApp/res/layout/activity_display.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--  Copyright 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".DisplayActivity">
+    <View
+        android:id="@+id/background_touch_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        />
+    <!-- the size should be match_parent -->
+    <SurfaceView
+        android:id="@+id/surface_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        android:focusedByDefault="true"
+        android:defaultFocusHighlightEnabled="true">
+        <requestFocus />
+    </SurfaceView>
+    <!-- A cursor size in virtio-gpu spec is always 64x64 -->
+    <SurfaceView
+        android:id="@+id/cursor_surface_view"
+        android:layout_width="64px"
+        android:layout_height="64px">
+    </SurfaceView>
+
+</merge>
\ No newline at end of file
diff --git a/android/TerminalApp/res/menu/main_menu.xml b/android/TerminalApp/res/menu/main_menu.xml
index 42ba85d..dbb788c 100644
--- a/android/TerminalApp/res/menu/main_menu.xml
+++ b/android/TerminalApp/res/menu/main_menu.xml
@@ -20,4 +20,9 @@
         android:icon="@drawable/ic_settings"
         android:title="@string/action_settings"
         app:showAsAction="always"/>
+    <item android:id="@+id/menu_item_display"
+        android:icon="@drawable/ic_display"
+        android:enabled="false"
+        android:title="@string/action_display"
+        app:showAsAction="always"/>
 </menu>
diff --git a/android/TerminalApp/res/values-af/strings.xml b/android/TerminalApp/res/values-af/strings.xml
index eae5281..b395cf2 100644
--- a/android/TerminalApp/res/values-af/strings.xml
+++ b/android/TerminalApp/res/values-af/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Kon nie installeer nie omdat wi-fi nie beskikbaar is nie"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Kon nie installeer nie. Probeer asseblief weer"</string>
     <string name="action_settings" msgid="5729342767795123227">"Instellings"</string>
+    <string name="action_display" msgid="8487008779926038139">"Vertoon"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Maak terminaal gereed"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stop tans terminaal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminaal het omgeval"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminaal maak toe"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Verplig toemaak"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> is geaktiveer"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Take wat lank neem"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Stelselgebeurtenisse"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-am/strings.xml b/android/TerminalApp/res/values-am/strings.xml
index f76eab8..6b2610d 100644
--- a/android/TerminalApp/res/values-am/strings.xml
+++ b/android/TerminalApp/res/values-am/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi ስለማይገኝ መጫን አልተሳካም"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"መጫን አልተሳካም። እባክዎ እንደገና ይሞክሩ"</string>
     <string name="action_settings" msgid="5729342767795123227">"ቅንብሮች"</string>
+    <string name="action_display" msgid="8487008779926038139">"ማሳያ"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ተርሚናልን በማዘጋጀት ላይ"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ተርሚናልን በማቆም ላይ"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ተርሚናል ተበላሽቷል"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ተርሚናል በመዝጋት ላይ ነው"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"በግድ ዝጋ"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ነቅቷል"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"ረዥም የሚያሄዱ ተግባሮች"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"የሥርዓት ክስተቶች"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ar/strings.xml b/android/TerminalApp/res/values-ar/strings.xml
index c01460d..d67feb6 100644
--- a/android/TerminalApp/res/values-ar/strings.xml
+++ b/android/TerminalApp/res/values-ar/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"تعذَّر التثبيت لأنّ شبكة Wi-Fi غير متاحة"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"تعذَّر التثبيت. يُرجى إعادة المحاولة"</string>
     <string name="action_settings" msgid="5729342767795123227">"الإعدادات"</string>
+    <string name="action_display" msgid="8487008779926038139">"الشاشة"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"جارٍ تحضير Terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"جارٍ إيقاف Terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"تعطَّل Terminal"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"جارٍ إغلاق الوحدة الطرفية"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"فرض الإغلاق"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"تم تفعيل <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"المهام الطويلة المدى"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"أحداث النظام"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-as/strings.xml b/android/TerminalApp/res/values-as/strings.xml
index a773fad..d9ba74c 100644
--- a/android/TerminalApp/res/values-as/strings.xml
+++ b/android/TerminalApp/res/values-as/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"ৱাই-ফাই উপলব্ধ নোহোৱাৰ কাৰণে ইনষ্টল কৰিব পৰা নগ’ল"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ইনষ্টল কৰিব পৰা নগ’ল। অনুগ্ৰহ কৰি পুনৰ চেষ্টা কৰক"</string>
     <string name="action_settings" msgid="5729342767795123227">"ছেটিং"</string>
+    <string name="action_display" msgid="8487008779926038139">"ডিছপ্লে’"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"টাৰ্মিনেল সাজু কৰি থকা হৈছে"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"টাৰ্মিনেল বন্ধ কৰি থকা হৈছে"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"টাৰ্মিনেল ক্ৰেশ্ব হৈছে"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"টাৰ্মিনেলটো বন্ধ কৰি থকা হৈছে"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"বলেৰে বন্ধ কৰক"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> সক্ষম কৰা আছে"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"দীঘলীয়া সময় জুৰি চলা কাৰ্য"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"ছিষ্টেমৰ ঘটনা"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-az/strings.xml b/android/TerminalApp/res/values-az/strings.xml
index 0e52500..94edf81 100644
--- a/android/TerminalApp/res/values-az/strings.xml
+++ b/android/TerminalApp/res/values-az/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi əlçatan olmadığı üçün quraşdırmaq alınmadı"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Quraşdırmaq alınmadı. Yenidən cəhd edin"</string>
     <string name="action_settings" msgid="5729342767795123227">"Ayarlar"</string>
+    <string name="action_display" msgid="8487008779926038139">"Displey"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminal hazırlanır"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminal dayandırılır"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal çökdü"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal bağlanır"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Məcburi bağlanma"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> aktivləşdirilib"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Uzunmüddətli tapşırıqlar"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistem tədbirləri"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-b+sr+Latn/strings.xml b/android/TerminalApp/res/values-b+sr+Latn/strings.xml
index fdbd9c0..490bc0a 100644
--- a/android/TerminalApp/res/values-b+sr+Latn/strings.xml
+++ b/android/TerminalApp/res/values-b+sr+Latn/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Instaliranje nije uspelo jer WiFi nije dostupan"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Instaliranje nije uspelo. Probajte ponovo"</string>
     <string name="action_settings" msgid="5729342767795123227">"Podešavanja"</string>
+    <string name="action_display" msgid="8487008779926038139">"Ekran"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminal se priprema"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminal se zaustavlja"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal je otkazao"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal se zatvara"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Prinudno zatvori"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> je omogućen"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dugotrajni zadaci"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistemski događaji"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-be/strings.xml b/android/TerminalApp/res/values-be/strings.xml
index 77a6538..236ffc8 100644
--- a/android/TerminalApp/res/values-be/strings.xml
+++ b/android/TerminalApp/res/values-be/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Не ўдалося ўсталяваць, бо сетка Wi-Fi недаступная"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Не ўдалося ўсталяваць. Паўтарыце спробу."</string>
     <string name="action_settings" msgid="5729342767795123227">"Налады"</string>
+    <string name="action_display" msgid="8487008779926038139">"Экран"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Ідзе падрыхтоўка тэрмінала"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Спыненне тэрмінала"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Збой тэрмінала"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Тэрмінал закрываецца"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Закрыць прымусова"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Модуль <xliff:g id="ID_1">VirGL</xliff:g> уключаны"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Працяглыя задачы"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Сістэмныя падзеі"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-bg/strings.xml b/android/TerminalApp/res/values-bg/strings.xml
index d9c16df..40943a6 100644
--- a/android/TerminalApp/res/values-bg/strings.xml
+++ b/android/TerminalApp/res/values-bg/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Инсталирането не бе успешно, защото не е налице Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Инсталирането не бе успешно. Моля, опитайте отново"</string>
     <string name="action_settings" msgid="5729342767795123227">"Настройки"</string>
+    <string name="action_display" msgid="8487008779926038139">"Екран"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Терминалът се подготвя"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Терминалът спира"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Терминалът претърпя срив"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Терминалът се затваря"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Принудително затваряне"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> е активирано"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Продължителни задачи"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Системни събития"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-bn/strings.xml b/android/TerminalApp/res/values-bn/strings.xml
index b25bc02..a2d9095 100644
--- a/android/TerminalApp/res/values-bn/strings.xml
+++ b/android/TerminalApp/res/values-bn/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"ওয়াই-ফাই উপলভ্য না থাকায় ইনস্টল করা যায়নি"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ইনস্টল করা যায়নি। আবার চেষ্টা করুন"</string>
     <string name="action_settings" msgid="5729342767795123227">"সেটিংস"</string>
+    <string name="action_display" msgid="8487008779926038139">"ডিসপ্লে"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"টার্মিনাল তৈরি করা হচ্ছে"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"টার্মিনাল বন্ধ করা হচ্ছে"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"টার্মিনাল ক্র্যাশ করেছে"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"টার্মিনাল বন্ধ হচ্ছে"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"জোর করে বন্ধ করুন"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> চালু করা আছে"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"দীর্ঘ সময় ধরে চালানো টাস্ক"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"সিস্টেম ইভেন্ট"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-bs/strings.xml b/android/TerminalApp/res/values-bs/strings.xml
index 8dcfe6f..fd4a460 100644
--- a/android/TerminalApp/res/values-bs/strings.xml
+++ b/android/TerminalApp/res/values-bs/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Instaliranje nije uspjelo jer WiFi nije dostupan"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Instaliranje nije uspjelo. Pokušajte ponovo"</string>
     <string name="action_settings" msgid="5729342767795123227">"Postavke"</string>
+    <string name="action_display" msgid="8487008779926038139">"Prikaz"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Priprema terminala"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Zaustavljanje terminala"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal je pao"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal je zatvoren"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Prisilno zatvori"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Omogućeno: <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dugotrajni zadaci"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Događaji sistema"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ca/strings.xml b/android/TerminalApp/res/values-ca/strings.xml
index 0737ffe..1180208 100644
--- a/android/TerminalApp/res/values-ca/strings.xml
+++ b/android/TerminalApp/res/values-ca/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"No s\'ha pogut instal·lar perquè la Wi‑Fi no està disponible"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"No s\'ha pogut instal·lar. Torna-ho a provar."</string>
     <string name="action_settings" msgid="5729342767795123227">"Configuració"</string>
+    <string name="action_display" msgid="8487008779926038139">"Pantalla"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"S\'està preparant el terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"S\'està aturant el terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"El terminal s\'ha bloquejat"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"El terminal s\'està tancant"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Força el tancament"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> està activat"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tasques de llarga durada"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Esdeveniments del sistema"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-cs/strings.xml b/android/TerminalApp/res/values-cs/strings.xml
index 2ab202e..a164818 100644
--- a/android/TerminalApp/res/values-cs/strings.xml
+++ b/android/TerminalApp/res/values-cs/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Instalace se nezdařila, protože není k dispozici Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Instalace se nezdařila. Zkuste to znovu"</string>
     <string name="action_settings" msgid="5729342767795123227">"Nastavení"</string>
+    <string name="action_display" msgid="8487008779926038139">"Displej"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Probíhá příprava terminálu"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Ukončování terminálu"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminál selhal"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminál se zavírá"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Vynutit ukončení"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Modul <xliff:g id="ID_1">VirGL</xliff:g> je aktivován"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dlouho spuštěné úlohy"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systémové události"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-da/strings.xml b/android/TerminalApp/res/values-da/strings.xml
index 6ef382f..f3a499b 100644
--- a/android/TerminalApp/res/values-da/strings.xml
+++ b/android/TerminalApp/res/values-da/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Installationen mislykkedes, fordi Wi-Fi ikke er tilgængeligt"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Installationen mislykkedes. Prøv igen"</string>
     <string name="action_settings" msgid="5729342767795123227">"Indstillinger"</string>
+    <string name="action_display" msgid="8487008779926038139">"Skærm"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Forbereder terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stopper terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminalen er gået ned"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminalen lukker"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Tving til at lukke"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> er aktiveret"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Længerevarende opgaver"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systemhændelser"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-de/strings.xml b/android/TerminalApp/res/values-de/strings.xml
index deb3db3..107f275 100644
--- a/android/TerminalApp/res/values-de/strings.xml
+++ b/android/TerminalApp/res/values-de/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Die Installation ist fehlgeschlagen, weil kein WLAN verfügbar ist"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Die Installation ist fehlgeschlagen. Bitte versuche es noch einmal."</string>
     <string name="action_settings" msgid="5729342767795123227">"Einstellungen"</string>
+    <string name="action_display" msgid="8487008779926038139">"Display"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminal wird vorbereitet"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminal wird beendet"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal ist abgestürzt"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal wird geschlossen"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Schließen erzwingen"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ist aktiviert"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Aufgaben mit langer Ausführungszeit"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systemereignisse"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-el/strings.xml b/android/TerminalApp/res/values-el/strings.xml
index 78cf235..bcb7256 100644
--- a/android/TerminalApp/res/values-el/strings.xml
+++ b/android/TerminalApp/res/values-el/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Η εγκατάσταση απέτυχε, επειδή το Wi-Fi δεν είναι διαθέσιμο"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Η εγκατάσταση απέτυχε. Δοκιμάστε ξανά"</string>
     <string name="action_settings" msgid="5729342767795123227">"Ρυθμίσεις"</string>
+    <string name="action_display" msgid="8487008779926038139">"Προβολή"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Προετοιμασία τερματικού σε εξέλιξη"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Διακοπή τερματικού σε εξέλιξη"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Το τερματικό παρουσίασε σφάλμα"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Το τερματικό κλείνει"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Αναγκαστικό κλείσιμο"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Το <xliff:g id="ID_1">VirGL</xliff:g> είναι ενεργοποιημένο"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Εργασίες μεγάλης διάρκειας"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Συμβάντα συστήματος"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-en-rAU/strings.xml b/android/TerminalApp/res/values-en-rAU/strings.xml
index 805257f..0403b74 100644
--- a/android/TerminalApp/res/values-en-rAU/strings.xml
+++ b/android/TerminalApp/res/values-en-rAU/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Failed to install because Wi-Fi is not available"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Failed to install. Please try again"</string>
     <string name="action_settings" msgid="5729342767795123227">"Settings"</string>
+    <string name="action_display" msgid="8487008779926038139">"Display"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparing terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stopping terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal crashed"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal is closing"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Force close"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> is enabled"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Long-running tasks"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"System events"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-en-rCA/strings.xml b/android/TerminalApp/res/values-en-rCA/strings.xml
index f208e38..5842cb2 100644
--- a/android/TerminalApp/res/values-en-rCA/strings.xml
+++ b/android/TerminalApp/res/values-en-rCA/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Failed to install because Wi-Fi is not available"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Failed to install. Please try again"</string>
     <string name="action_settings" msgid="5729342767795123227">"Settings"</string>
+    <string name="action_display" msgid="8487008779926038139">"Display"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparing terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stopping terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal crashed"</string>
@@ -87,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal is closing"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Force close"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> is enabled"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Long running tasks"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"System events"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-en-rGB/strings.xml b/android/TerminalApp/res/values-en-rGB/strings.xml
index 805257f..0403b74 100644
--- a/android/TerminalApp/res/values-en-rGB/strings.xml
+++ b/android/TerminalApp/res/values-en-rGB/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Failed to install because Wi-Fi is not available"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Failed to install. Please try again"</string>
     <string name="action_settings" msgid="5729342767795123227">"Settings"</string>
+    <string name="action_display" msgid="8487008779926038139">"Display"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparing terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stopping terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal crashed"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal is closing"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Force close"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> is enabled"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Long-running tasks"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"System events"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-en-rIN/strings.xml b/android/TerminalApp/res/values-en-rIN/strings.xml
index 805257f..0403b74 100644
--- a/android/TerminalApp/res/values-en-rIN/strings.xml
+++ b/android/TerminalApp/res/values-en-rIN/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Failed to install because Wi-Fi is not available"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Failed to install. Please try again"</string>
     <string name="action_settings" msgid="5729342767795123227">"Settings"</string>
+    <string name="action_display" msgid="8487008779926038139">"Display"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparing terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stopping terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal crashed"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal is closing"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Force close"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> is enabled"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Long-running tasks"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"System events"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-es-rUS/strings.xml b/android/TerminalApp/res/values-es-rUS/strings.xml
index ba758ac..e25e5c5 100644
--- a/android/TerminalApp/res/values-es-rUS/strings.xml
+++ b/android/TerminalApp/res/values-es-rUS/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"La instalación falló porque no hay una conexión Wi-Fi disponible"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"No se pudo instalar; vuelve a intentarlo"</string>
     <string name="action_settings" msgid="5729342767795123227">"Configuración"</string>
+    <string name="action_display" msgid="8487008779926038139">"Pantalla"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparando la terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Deteniendo la terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Se produjo un error en la terminal"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Se está cerrando la terminal"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Forzar cierre"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Se habilitó <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tareas extensas"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Eventos del sistema"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-es/strings.xml b/android/TerminalApp/res/values-es/strings.xml
index 5a2629c..5a9a3c6 100644
--- a/android/TerminalApp/res/values-es/strings.xml
+++ b/android/TerminalApp/res/values-es/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"No se ha podido instalar porque no hay conexión Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"No se ha podido instalar. Vuelve a intentarlo."</string>
     <string name="action_settings" msgid="5729342767795123227">"Ajustes"</string>
+    <string name="action_display" msgid="8487008779926038139">"Pantalla"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparando terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Deteniendo terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Fallo del terminal"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"El terminal se está cerrando"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Forzar cierre"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> se ha habilitado"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tareas de larga duración"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Eventos del sistema"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-et/strings.xml b/android/TerminalApp/res/values-et/strings.xml
index e64729c..30916ca 100644
--- a/android/TerminalApp/res/values-et/strings.xml
+++ b/android/TerminalApp/res/values-et/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Installimine ebaõnnestus, kuna WiFi pole saadaval"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Installimine ebaõnnestus. Proovige uuesti"</string>
     <string name="action_settings" msgid="5729342767795123227">"Seaded"</string>
+    <string name="action_display" msgid="8487008779926038139">"Kuvamine"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminali ettevalmistamine"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminali peatamine"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal jooksis kokku"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal suletakse"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Rakenda sulgemine"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> on lubatud"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Pikalt kestvad ülesanded"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Süsteemisündmused"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-eu/strings.xml b/android/TerminalApp/res/values-eu/strings.xml
index fde1d1d..19284a2 100644
--- a/android/TerminalApp/res/values-eu/strings.xml
+++ b/android/TerminalApp/res/values-eu/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Ezin izan da instalatu, wifi-sarerik erabilgarri ez dagoelako"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Ezin izan da instalatu. Saiatu berriro"</string>
     <string name="action_settings" msgid="5729342767795123227">"Ezarpenak"</string>
+    <string name="action_display" msgid="8487008779926038139">"Bistaratzea"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminala prestatzen"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminala geldiarazten"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminalak huts egin du"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal ixten ari da"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Behartu ixtera"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> gaituta dago"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Luze exekutatzen diren zereginak"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistemako gertaerak"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-fa/strings.xml b/android/TerminalApp/res/values-fa/strings.xml
index b040c24..d4ebb2b 100644
--- a/android/TerminalApp/res/values-fa/strings.xml
+++ b/android/TerminalApp/res/values-fa/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"نصب نشد چون Wi-Fi دردسترس نیست"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"نصب نشد. لطفاً دوباره امتحان کنید"</string>
     <string name="action_settings" msgid="5729342767795123227">"تنظیمات"</string>
+    <string name="action_display" msgid="8487008779926038139">"نمایشگر"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"درحال آماده‌سازی پایانه"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"پایانه درحال توقف است"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"پایانه ازکار افتاد"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"پایانه درحال بسته شدن است"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"بستن اجباری"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"‫<xliff:g id="ID_1">VirGL</xliff:g> فعال شد"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"تکالیف بلندمدت"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"رویدادهای سیستم"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-fi/strings.xml b/android/TerminalApp/res/values-fi/strings.xml
index 5dcfadf..526ae93 100644
--- a/android/TerminalApp/res/values-fi/strings.xml
+++ b/android/TerminalApp/res/values-fi/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Asennus epäonnistui, koska Wi-Fi ei ole käytettävissä"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Asennus epäonnistui. Yritä uudelleen"</string>
     <string name="action_settings" msgid="5729342767795123227">"Asetukset"</string>
+    <string name="action_display" msgid="8487008779926038139">"Näyttö"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Valmistellaan päätettä"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Pysäytetään terminaalia"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminaali kaatui"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal sulkeutuu"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Pakota sulkeutumaan"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> on käytössä"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Pitkäkestoiset tehtävät"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Järjestelmätapahtumat"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-fr-rCA/strings.xml b/android/TerminalApp/res/values-fr-rCA/strings.xml
index a320c62..47e1d41 100644
--- a/android/TerminalApp/res/values-fr-rCA/strings.xml
+++ b/android/TerminalApp/res/values-fr-rCA/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Échec de l\'installation parce que le Wi-Fi n\'est pas disponible"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Échec de l\'installation. Veuillez réessayer"</string>
     <string name="action_settings" msgid="5729342767795123227">"Paramètres"</string>
+    <string name="action_display" msgid="8487008779926038139">"Affichage"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Préparation du terminal en cours…"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Arrêt du terminal en cours…"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Le terminal a planté"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Le terminal se fermera"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Forcer la fermeture"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> est activé"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tâches de longue durée"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Événements système"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-fr/strings.xml b/android/TerminalApp/res/values-fr/strings.xml
index edb91b4..83a2ce4 100644
--- a/android/TerminalApp/res/values-fr/strings.xml
+++ b/android/TerminalApp/res/values-fr/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Échec de l\'installation, car le Wi-Fi n\'est pas disponible"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Échec de l\'installation. Veuillez réessayer."</string>
     <string name="action_settings" msgid="5729342767795123227">"Paramètres"</string>
+    <string name="action_display" msgid="8487008779926038139">"Écran"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Préparation du terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Arrêt du terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Le terminal a planté"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal se ferme"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Forcer la fermeture"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> est activé"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tâches de longue durée"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Événements système"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-gl/strings.xml b/android/TerminalApp/res/values-gl/strings.xml
index c1d4f82..61b71ae 100644
--- a/android/TerminalApp/res/values-gl/strings.xml
+++ b/android/TerminalApp/res/values-gl/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Produciuse un erro durante a instalación porque non hai ningunha wifi dispoñible"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Produciuse un erro durante a instalación. Téntao de novo"</string>
     <string name="action_settings" msgid="5729342767795123227">"Configuración"</string>
+    <string name="action_display" msgid="8487008779926038139">"Visualización"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparando terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Parando terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Produciuse un fallo no terminal"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"A aplicación Terminal estase pechando"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Forzar peche"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Activouse <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tarefas de longa duración"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Eventos do sistema"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-gu/strings.xml b/android/TerminalApp/res/values-gu/strings.xml
index b1a452f..9136302 100644
--- a/android/TerminalApp/res/values-gu/strings.xml
+++ b/android/TerminalApp/res/values-gu/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"વાઇ-ફાઇ ઉપલબ્ધ ન હોવાથી ઇન્સ્ટૉલ કરવામાં નિષ્ફળ રહ્યાં"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ઇન્સ્ટૉલ કરવામાં નિષ્ફળ રહ્યાં. કૃપા કરીને ફરી પ્રયાસ કરો"</string>
     <string name="action_settings" msgid="5729342767795123227">"સેટિંગ"</string>
+    <string name="action_display" msgid="8487008779926038139">"ડિસ્પ્લે"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ટર્મિનલ તૈયાર કરી રહ્યાં છીએ"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ટર્મિનલ બંધ કરી રહ્યાં છીએ"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ટર્મિનલ ક્રૅશ થયું"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ટર્મિનલ ઍપ બંધ થઈ રહી છે"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"ફરજિયાત બંધ કરો"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ચાલુ કરેલું છે"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"લાંબો સમય ચાલનારા કાર્યો"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"સિસ્ટમ ઇવેન્ટ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-hi/strings.xml b/android/TerminalApp/res/values-hi/strings.xml
index af2ddaa..bd5756b 100644
--- a/android/TerminalApp/res/values-hi/strings.xml
+++ b/android/TerminalApp/res/values-hi/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"वाई-फ़ाई उपलब्ध न होने की वजह से, इंस्टॉल नहीं किया जा सका"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"इंस्टॉल नहीं किया जा सका. कृपया फिर से कोशिश करें"</string>
     <string name="action_settings" msgid="5729342767795123227">"सेटिंग"</string>
+    <string name="action_display" msgid="8487008779926038139">"डिसप्ले"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"टर्मिनल तैयार किया जा रहा है"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"टर्मिनल को रोका जा रहा है"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"टर्मिनल क्रैश हो गया"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"टर्मिनल ऐप्लिकेशन बंद हो रहा है"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"ज़बरदस्ती बंद करें"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> चालू है"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"लंबे समय तक चलने वाले टास्क"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"सिस्टम इवेंट"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-hr/strings.xml b/android/TerminalApp/res/values-hr/strings.xml
index 87d4798..27e51e3 100644
--- a/android/TerminalApp/res/values-hr/strings.xml
+++ b/android/TerminalApp/res/values-hr/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Instaliranje nije uspjelo jer Wi-Fi nije dostupan"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Instaliranje nije uspjelo. Pokušajte ponovo"</string>
     <string name="action_settings" msgid="5729342767795123227">"Postavke"</string>
+    <string name="action_display" msgid="8487008779926038139">"Prikaz"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Priprema terminala"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Zaustavljanje terminala"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal se srušio"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal se zatvara"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Prisilno zatvori"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Omogućeno je: <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dugotrajni zadaci"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Događaji sustava"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-hu/strings.xml b/android/TerminalApp/res/values-hu/strings.xml
index e1b17e6..046081e 100644
--- a/android/TerminalApp/res/values-hu/strings.xml
+++ b/android/TerminalApp/res/values-hu/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Nem sikerült a telepítés, mert nincs Wi-Fi-kapcsolat"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Nem sikerült a telepítés. Próbálkozzon újra."</string>
     <string name="action_settings" msgid="5729342767795123227">"Beállítások"</string>
+    <string name="action_display" msgid="8487008779926038139">"Megjelenítés"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"A terminál előkészítése…"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"A terminál leállítása…"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"A terminál összeomlott"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"A terminál bezárul"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Bezárás kényszerítése"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"A(z) <xliff:g id="ID_1">VirGL</xliff:g> engedélyezve van"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Hosszan futó feladatok"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Rendszeresemények"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-hy/strings.xml b/android/TerminalApp/res/values-hy/strings.xml
index 06ae4cb..6026fae 100644
--- a/android/TerminalApp/res/values-hy/strings.xml
+++ b/android/TerminalApp/res/values-hy/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Չհաջողվեց տեղադրել, քանի որ Wi-Fi ցանցը հասանելի չէ"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Չհաջողվեց տեղադրել: Նորից փորձեք"</string>
     <string name="action_settings" msgid="5729342767795123227">"Կարգավորումներ"</string>
+    <string name="action_display" msgid="8487008779926038139">"Էկրան"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Տերմինալի նախապատրաստում"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Տերմինալը կանգնեցվում է"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Տերմինալը խափանվել է"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Տերմինալը փակվում է"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Ստիպողաբար փակել"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g>-ը միացված է"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Երկար աշխատող առաջադրանքներ"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Համակարգի իրադարձություններ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-in/strings.xml b/android/TerminalApp/res/values-in/strings.xml
index 1a844b1..a1fe894 100644
--- a/android/TerminalApp/res/values-in/strings.xml
+++ b/android/TerminalApp/res/values-in/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Gagal menginstal karena Wi-Fi tidak tersedia"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Gagal menginstal. Coba lagi"</string>
     <string name="action_settings" msgid="5729342767795123227">"Setelan"</string>
+    <string name="action_display" msgid="8487008779926038139">"Tampilan"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Menyiapkan terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Menghentikan terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal error"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal ditutup"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Tutup paksa"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> diaktifkan"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tugas yang berjalan lama"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Peristiwa sistem"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-is/strings.xml b/android/TerminalApp/res/values-is/strings.xml
index 638da38..9bb0df4 100644
--- a/android/TerminalApp/res/values-is/strings.xml
+++ b/android/TerminalApp/res/values-is/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Uppsetning tókst ekki vegna þess að Wi-Fi er ekki tiltækt"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Uppsetning tókst ekki. Reyndu aftur"</string>
     <string name="action_settings" msgid="5729342767795123227">"Stillingar"</string>
+    <string name="action_display" msgid="8487008779926038139">"Skjár"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Undirbýr útstöð"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stöðvar tengi"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Tengi hrundi"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal er að loka"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Þvinga fram lokun"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Kveikt er á <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Langvarandi verkefni"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Kerfistilvik"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-it/strings.xml b/android/TerminalApp/res/values-it/strings.xml
index 5660cc3..a8848ed 100644
--- a/android/TerminalApp/res/values-it/strings.xml
+++ b/android/TerminalApp/res/values-it/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Impossibile installare: Wi-Fi non disponibile"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Installazione non riuscita. Riprova"</string>
     <string name="action_settings" msgid="5729342767795123227">"Impostazioni"</string>
+    <string name="action_display" msgid="8487008779926038139">"Display"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparazione terminale in corso…"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Arresto del terminale in corso…"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Arresto anomalo del terminale"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Chiusura del terminale in corso…"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Termina"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> è abilitata"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Attività di lunga durata"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Eventi di sistema"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-iw/strings.xml b/android/TerminalApp/res/values-iw/strings.xml
index 3ea2227..6156a1c 100644
--- a/android/TerminalApp/res/values-iw/strings.xml
+++ b/android/TerminalApp/res/values-iw/strings.xml
@@ -20,7 +20,7 @@
     <string name="terminal_display" msgid="4810127497644015237">"תצוגת טרמינל"</string>
     <string name="terminal_input" msgid="4602512831433433551">"סמן"</string>
     <string name="empty_line" msgid="5012067143408427178">"שורה ריקה"</string>
-    <string name="double_tap_to_edit_text" msgid="2344363097580051316">"כדי להקליד טקסט צריך להקיש הקשה כפולה"</string>
+    <string name="double_tap_to_edit_text" msgid="2344363097580051316">"כדי להקליד טקסט צריך ללחוץ לחיצה כפולה"</string>
     <string name="installer_title_text" msgid="500663060973466805">"התקנה של טרמינל Linux"</string>
     <string name="installer_desc_text_format" msgid="5935117404303982823">"כדי להפעיל את טרמינל Linux, צריך להוריד נתונים בנפח של בערך <xliff:g id="EXPECTED_SIZE">%1$s</xliff:g> דרך הרשת.\nלהמשיך?"</string>
     <string name="installer_wait_for_wifi_checkbox_text" msgid="5812378362605046639">"הורדה רק באמצעות Wi-Fi"</string>
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"ההתקנה נכשלה כי אין חיבור ל-Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ההתקנה נכשלה. אפשר לנסות שוב."</string>
     <string name="action_settings" msgid="5729342767795123227">"הגדרות"</string>
+    <string name="action_display" msgid="8487008779926038139">"מסך"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"הטרמינל בהכנה"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"המערכת עוצרת את הטרמינל"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"הטרמינל קרס"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"הטרמינל בתהליך סגירה"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"אילוץ סגירה"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"‫<xliff:g id="ID_1">VirGL</xliff:g> מופעל"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"משימות ממושכות"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"אירועי מערכת"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ja/strings.xml b/android/TerminalApp/res/values-ja/strings.xml
index bcc3378..d28c957 100644
--- a/android/TerminalApp/res/values-ja/strings.xml
+++ b/android/TerminalApp/res/values-ja/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi が利用できないためインストールできませんでした"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"インストールできませんでした。もう一度お試しください"</string>
     <string name="action_settings" msgid="5729342767795123227">"設定"</string>
+    <string name="action_display" msgid="8487008779926038139">"ディスプレイ"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ターミナルを準備しています"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ターミナルを停止しています"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ターミナルがクラッシュしました"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ターミナルを閉じています"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"強制終了"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g>は有効です"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"長時間実行タスク"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"システム イベント"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ka/strings.xml b/android/TerminalApp/res/values-ka/strings.xml
index 51960f6..5eb5bbf 100644
--- a/android/TerminalApp/res/values-ka/strings.xml
+++ b/android/TerminalApp/res/values-ka/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi მიუწვდომელია, ამიტომ ინსტალაცია ვერ მოხერხდა"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ვერ მოახერხდა ინსტალაცია. გთხოვთ, ცადოთ ხელახლა"</string>
     <string name="action_settings" msgid="5729342767795123227">"პარამეტრები"</string>
+    <string name="action_display" msgid="8487008779926038139">"ეკრანი"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"მიმდინარეობს ტერმინალის მომზადება"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"მიმდინარეობს ტერმინალის შეწყვეტა"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ტერმინალი გაჭედილია"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ტერმინალი იხურება"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"იძულებით დახურვა"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ჩართულია"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"ხანგრძლივად გაშვებული ამოცანები"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"სისტემური მოვლენები"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-kk/strings.xml b/android/TerminalApp/res/values-kk/strings.xml
index ea12254..c40ba60 100644
--- a/android/TerminalApp/res/values-kk/strings.xml
+++ b/android/TerminalApp/res/values-kk/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Орнатылмады, себебі Wi-Fi желісі жоқ."</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Орнату мүмкін болмады. Қайталап көріңіз."</string>
     <string name="action_settings" msgid="5729342767795123227">"Параметрлер"</string>
+    <string name="action_display" msgid="8487008779926038139">"Дисплей"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Терминал дайындалып жатыр."</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Терминал тоқтатылып жатыр."</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Терминал бұзылды."</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Терминал жабылып жатыр"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Қолмен жабу"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> қосылды."</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Ұзақ орындалатын тапсырмалар"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Жүйе оқиғалары"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-km/strings.xml b/android/TerminalApp/res/values-km/strings.xml
index d85ead9..b5b3ffa 100644
--- a/android/TerminalApp/res/values-km/strings.xml
+++ b/android/TerminalApp/res/values-km/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"មិនអាចដំឡើងបានទេ ដោយសារមិនមាន Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"មិនអាច​ដំឡើងបានទេ។ សូមព្យាយាមម្ដងទៀត"</string>
     <string name="action_settings" msgid="5729342767795123227">"ការកំណត់"</string>
+    <string name="action_display" msgid="8487008779926038139">"បង្ហាញ"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"កំពុងរៀបចំទែមីណាល់"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"កំពុងបញ្ឈប់ទែមីណាល់"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ទែមីណាល់បានគាំង"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ទែមីណាល់កំពុងបិទ"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"បង្ខំ​ឱ្យ​បិទ"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ត្រូវបានបើក"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"កិច្ចការដែលដំណើរការរយៈពេលយូរ"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"ព្រឹត្តិការណ៍ប្រព័ន្ធ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-kn/strings.xml b/android/TerminalApp/res/values-kn/strings.xml
index 8010e73..46b2d24 100644
--- a/android/TerminalApp/res/values-kn/strings.xml
+++ b/android/TerminalApp/res/values-kn/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"ವೈ-ಫೈ ಲಭ್ಯವಿಲ್ಲದ ಕಾರಣ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ವಿಫಲವಾಗಿದೆ. ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="action_settings" msgid="5729342767795123227">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="action_display" msgid="8487008779926038139">"ಡಿಸ್‌ಪ್ಲೇ"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ಟರ್ಮಿನಲ್‌ ಅನ್ನು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ಟರ್ಮಿನಲ್ ಅನ್ನು ನಿಲ್ಲಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ಟರ್ಮಿನಲ್ ಕ್ರ್ಯಾಶ್ ಆಗಿದೆ"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ಟರ್ಮಿನಲ್ ಮುಚ್ಚಲಾಗುತ್ತಿದೆ"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"ಬಲವಂತವಾಗಿ ಮುಚ್ಚಿ"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"ದೀರ್ಘಾವಧಿಯ ಕಾರ್ಯಗಳು"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"ಸಿಸ್ಟಮ್ ಈವೆಂಟ್‌ಗಳು"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ko/strings.xml b/android/TerminalApp/res/values-ko/strings.xml
index 173cade..ab523e2 100644
--- a/android/TerminalApp/res/values-ko/strings.xml
+++ b/android/TerminalApp/res/values-ko/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi를 사용할 수 없어 설치하지 못했습니다."</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"설치할 수 없습니다. 다시 시도해 보세요."</string>
     <string name="action_settings" msgid="5729342767795123227">"설정"</string>
+    <string name="action_display" msgid="8487008779926038139">"디스플레이"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"터미널 준비 중"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"터미널 중지 중"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"터미널 다운됨"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"터미널 앱 종료 중"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"강제 종료"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g>이(가) 사용 설정되었습니다."</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"장기 실행 태스크"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"시스템 이벤트"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ky/strings.xml b/android/TerminalApp/res/values-ky/strings.xml
index 21d0e2a..3e4a3e4 100644
--- a/android/TerminalApp/res/values-ky/strings.xml
+++ b/android/TerminalApp/res/values-ky/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi жеткиликсиз болгондуктан, орнотулбай калды"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Орнотулган жок. Кайталап көрүңүз"</string>
     <string name="action_settings" msgid="5729342767795123227">"Параметрлер"</string>
+    <string name="action_display" msgid="8487008779926038139">"Экран"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Терминал даярдалууда"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Терминал токтотулууда"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Терминал бузулду"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Терминал жабылып жатат"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Мажбурлап жабуу"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> иштетилди"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Узак тапшырмалар"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Тутумдук иш-чаралар"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-lo/strings.xml b/android/TerminalApp/res/values-lo/strings.xml
index 109a304..440d757 100644
--- a/android/TerminalApp/res/values-lo/strings.xml
+++ b/android/TerminalApp/res/values-lo/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"ຕິດຕັ້ງບໍ່ສຳເລັດເນື່ອງຈາກບໍ່ມີ Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ຕິດຕັ້ງບໍ່ສໍາເລັດ. ກະລຸນາລອງໃໝ່"</string>
     <string name="action_settings" msgid="5729342767795123227">"ການຕັ້ງຄ່າ"</string>
+    <string name="action_display" msgid="8487008779926038139">"ການສະແດງຜົນ"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ກຳລັງກະກຽມເທີມິນອນ"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ກຳລັງຢຸດເທີມິນອນ"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ເທີມິນອນຫຼົ້ມ"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ເທີມິນອນກຳລັງຈະປິດ"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"ບັງຄັບປິດ"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"ເປີດການນຳໃຊ້ <xliff:g id="ID_1">VirGL</xliff:g> ແລ້ວ"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"ວຽກທີ່ດຳເນີນເປັນເວລາດົນ"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"ກິດຈະກຳລະບົບ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-lt/strings.xml b/android/TerminalApp/res/values-lt/strings.xml
index beefadd..4abcd2d 100644
--- a/android/TerminalApp/res/values-lt/strings.xml
+++ b/android/TerminalApp/res/values-lt/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Nepavyko įdiegti, nes „Wi-Fi“ nepasiekiamas"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Nepavyko įdiegti. Bandykite dar kartą"</string>
     <string name="action_settings" msgid="5729342767795123227">"Nustatymai"</string>
+    <string name="action_display" msgid="8487008779926038139">"Ekranas"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Ruošiamas terminalas"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminalas sustabdomas"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminalas užstrigo"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminalas uždaromas"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Priverstinai uždaryti"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"„<xliff:g id="ID_1">VirGL</xliff:g>“ įgalinta"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Ilgai vykdomos užduotys"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistemos įvykiai"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-lv/strings.xml b/android/TerminalApp/res/values-lv/strings.xml
index d45aeb3..0d017d1 100644
--- a/android/TerminalApp/res/values-lv/strings.xml
+++ b/android/TerminalApp/res/values-lv/strings.xml
@@ -33,13 +33,14 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Instalēšana neizdevās, jo nav pieejams Wi‑Fi savienojums"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Neizdevās instalēt — mēģiniet vēlreiz"</string>
     <string name="action_settings" msgid="5729342767795123227">"Iestatījumi"</string>
+    <string name="action_display" msgid="8487008779926038139">"Displejs"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Notiek termināļa sagatavošana."</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Notiek termināļa apturēšana."</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminālis avarēja."</string>
     <string name="settings_disk_resize_title" msgid="8648082439414122069">"Diska lieluma mainīšana"</string>
     <string name="settings_disk_resize_sub_title" msgid="568100064927028058">"Saknes nodalījuma lieluma mainīšana"</string>
     <string name="settings_disk_resize_resize_message" msgid="5990475712303845087">"Diska lielums ir iestatīts."</string>
-    <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Piešķirtais lielums: <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
+    <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Piešķirts: <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Maksimālais lielums: <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Atcelt"</string>
     <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="6651018335906339973">"Lietot"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminālis tiek aizvērts"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Veikt piespiedu aizvēršanu"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ir iespējots"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Ilgstoši uzdevumi"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistēmas notikumi"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-mk/strings.xml b/android/TerminalApp/res/values-mk/strings.xml
index 99cc48c..3db6614 100644
--- a/android/TerminalApp/res/values-mk/strings.xml
+++ b/android/TerminalApp/res/values-mk/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Не можеше да се инсталира бидејќи не е достапна Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Не можеше да се инсталира. Обидете се повторно"</string>
     <string name="action_settings" msgid="5729342767795123227">"Поставки"</string>
+    <string name="action_display" msgid="8487008779926038139">"Екран"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Терминалот се подготвува"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Терминалот се сопира"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Терминалот падна"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Терминалот се затвора"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Затвори присилно"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Овозможено: <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Задачи што се извршуваат долго"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Системски настани"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ml/strings.xml b/android/TerminalApp/res/values-ml/strings.xml
index c2bab30..1117979 100644
--- a/android/TerminalApp/res/values-ml/strings.xml
+++ b/android/TerminalApp/res/values-ml/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"വൈഫൈ ലഭ്യമല്ലാത്തതിനാൽ ഇൻസ്‌റ്റാൾ ചെയ്യാനായില്ല"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ഇൻസ്റ്റാൾ ചെയ്യാനായില്ല. വീണ്ടും ശ്രമിക്കുക"</string>
     <string name="action_settings" msgid="5729342767795123227">"ക്രമീകരണം"</string>
+    <string name="action_display" msgid="8487008779926038139">"ഡിസ്‌പ്ലേ"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ടെർമിനൽ തയ്യാറാക്കുന്നു"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ടെർമിനൽ നിർത്തുന്നു"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ടെർമിനൽ ക്രാഷായി"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ടെർമിനൽ അടയ്ക്കുകയാണ്"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"നിർബന്ധിതമായി അടയ്ക്കുക"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> പ്രവർത്തനക്ഷമമാക്കി"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"ദീർഘസമയം റൺ ചെയ്യുന്ന ടാസ്ക്കുകൾ"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"സിസ്റ്റം ഇവന്റുകൾ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-mn/strings.xml b/android/TerminalApp/res/values-mn/strings.xml
index 4849006..4c8305b 100644
--- a/android/TerminalApp/res/values-mn/strings.xml
+++ b/android/TerminalApp/res/values-mn/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi боломжгүй тул суулгаж чадсангүй"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Суулгаж чадсангүй. Дахин оролдоно уу"</string>
     <string name="action_settings" msgid="5729342767795123227">"Тохиргоо"</string>
+    <string name="action_display" msgid="8487008779926038139">"Дэлгэц"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Терминалыг бэлтгэж байна"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Терминалыг зогсоож байна"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Терминал гэмтсэн"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Терминал хаагдаж байна"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Хүчээр хаах"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> идэвхэжсэн"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Удаан ажиллаж буй ажил"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Системийн үйл явдал"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-mr/strings.xml b/android/TerminalApp/res/values-mr/strings.xml
index 70a093e..eff919f 100644
--- a/android/TerminalApp/res/values-mr/strings.xml
+++ b/android/TerminalApp/res/values-mr/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"वाय-फाय उपलब्ध नसल्यामुळे इंस्टॉल करता आले नाही"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"इंस्टॉल करता आले नाही. कृपया पुन्हा प्रयत्न करा"</string>
     <string name="action_settings" msgid="5729342767795123227">"सेटिंग्ज"</string>
+    <string name="action_display" msgid="8487008779926038139">"डिस्प्ले"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"टर्मिनल तयार करत आहे"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"टर्मिनल थांबवत आहे"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"टर्मिनल क्रॅश झाले आहे"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"टर्मिनल बंद होत आहे"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"सक्तीने बंद करा"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> सुरू केले आहे"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"दीर्घवेळ रन होणाऱ्या टास्क"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"सिस्टीम इव्‍हेंट"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ms/strings.xml b/android/TerminalApp/res/values-ms/strings.xml
index a14d938..fb88ff1 100644
--- a/android/TerminalApp/res/values-ms/strings.xml
+++ b/android/TerminalApp/res/values-ms/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Gagal melakukan pemasangan kerana Wi-Fi tidak tersedia"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Gagal melakukan pemasangan. Sila cuba lagi"</string>
     <string name="action_settings" msgid="5729342767795123227">"Tetapan"</string>
+    <string name="action_display" msgid="8487008779926038139">"Paparan"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Menyediakan terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Menghentikan terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal ranap"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal ditutup"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Tutup paksa"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> didayakan"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tugasan yang memakan masa yang lama"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Peristiwa sistem"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-my/strings.xml b/android/TerminalApp/res/values-my/strings.xml
index eda6e90..08ca00c 100644
--- a/android/TerminalApp/res/values-my/strings.xml
+++ b/android/TerminalApp/res/values-my/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi မရနိုင်သောကြောင့် ထည့်သွင်း၍မရလိုက်ပါ"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ထည့်သွင်း၍ မရလိုက်ပါ။ ထပ်စမ်းကြည့်ပါ"</string>
     <string name="action_settings" msgid="5729342767795123227">"ဆက်တင်များ"</string>
+    <string name="action_display" msgid="8487008779926038139">"ဖန်သားပြင်"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"တာမီနယ်ကို ပြင်ဆင်နေသည်"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"တာမီနယ်ကို ရပ်နေသည်"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"တာမီနယ် ရပ်တန့်သွားသည်"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"တာမီနယ် ပိတ်နေသည်"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"မဖြစ်မနေပိတ်ရန်"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ဖွင့်ထားသည်"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"အချိန်ကြာသော လုပ်ဆောင်စရာများ"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"စနစ်ဖြစ်စဉ်များ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-nb/strings.xml b/android/TerminalApp/res/values-nb/strings.xml
index b2492db..2016678 100644
--- a/android/TerminalApp/res/values-nb/strings.xml
+++ b/android/TerminalApp/res/values-nb/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Kunne ikke installere fordi wifi ikke er tilgjengelig"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Installasjonen mislyktes. Prøv igjen"</string>
     <string name="action_settings" msgid="5729342767795123227">"Innstillinger"</string>
+    <string name="action_display" msgid="8487008779926038139">"Vis"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Forbereder terminalen"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stopper terminalen"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminalen krasjet"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminalen lukkes"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Tving avslutning"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> er aktivert"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Langvarige oppgaver"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systemhendelser"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ne/strings.xml b/android/TerminalApp/res/values-ne/strings.xml
index 714dcf3..9e3b9e6 100644
--- a/android/TerminalApp/res/values-ne/strings.xml
+++ b/android/TerminalApp/res/values-ne/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi उपलब्ध नभएकाले इन्स्टल गर्न सकिएन"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"इन्स्टल गर्न सकिएन। कृपया फेरि प्रयास गर्नुहोस्"</string>
     <string name="action_settings" msgid="5729342767795123227">"सेटिङ"</string>
+    <string name="action_display" msgid="8487008779926038139">"डिस्प्ले"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"टर्मिनल तयार पारिँदै छ"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"टर्मिनल रोकिँदै छ"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"टर्मिनल क्र्यास भयो"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"टर्मिनल एप बन्द हुँदै छ"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"बलपूर्वक बन्द गर्नुहोस्"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> अन गरिएको छ"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"लामो समयसम्म चलिरहने कार्यहरू"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"सिस्टमसम्बन्धी गतिविधिहरू"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-nl/strings.xml b/android/TerminalApp/res/values-nl/strings.xml
index 6c1e42a..eaea8a2 100644
--- a/android/TerminalApp/res/values-nl/strings.xml
+++ b/android/TerminalApp/res/values-nl/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Kan niet installeren omdat wifi niet beschikbaar is"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Installatie mislukt. Probeer het opnieuw."</string>
     <string name="action_settings" msgid="5729342767795123227">"Instellingen"</string>
+    <string name="action_display" msgid="8487008779926038139">"Scherm"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminal voorbereiden"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminal stoppen"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal gecrasht"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal wordt gesloten"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Geforceerd sluiten"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> staat aan"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Langlopende taken"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systeemgebeurtenissen"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-or/strings.xml b/android/TerminalApp/res/values-or/strings.xml
index 29855af..5383645 100644
--- a/android/TerminalApp/res/values-or/strings.xml
+++ b/android/TerminalApp/res/values-or/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"ୱାଇ-ଫାଇ ଉପଲବ୍ଧ ନଥିବା ଯୋଗୁଁ ଇନଷ୍ଟଲ କରିବାରେ ବିଫଳ ହୋଇଛି"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ଇନଷ୍ଟଲ କରିବାରେ ବିଫଳ ହୋଇଛି। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
     <string name="action_settings" msgid="5729342767795123227">"ସେଟିଂସ"</string>
+    <string name="action_display" msgid="8487008779926038139">"ଡିସପ୍ଲେ"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ଟର୍ମିନାଲକୁ ପ୍ରସ୍ତୁତ କରାଯାଉଛି"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminalକୁ ବନ୍ଦ କରାଯାଉଛି"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ଟର୍ମିନାଲ କ୍ରାସ ହୋଇଛି"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ଟର୍ମିନାଲ ବନ୍ଦ ହେବାକୁ ଯାଉଛି"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"ଫୋର୍ସ କ୍ଲୋଜ କରନ୍ତୁ"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g>କୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"ଅଧିକ ସମୟ ଚାଲୁଥିବା ଟାସ୍କ"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"ସିଷ୍ଟମ ଇଭେଣ୍ଟ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-pa/strings.xml b/android/TerminalApp/res/values-pa/strings.xml
index a4279ce..0ff2a0d 100644
--- a/android/TerminalApp/res/values-pa/strings.xml
+++ b/android/TerminalApp/res/values-pa/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"ਵਾਈ-ਫਾਈ ਉਪਲਬਧ ਨਾ ਹੋਣ ਕਰਕੇ ਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="action_settings" msgid="5729342767795123227">"ਸੈਟਿੰਗਾਂ"</string>
+    <string name="action_display" msgid="8487008779926038139">"ਡਿਸਪਲੇ"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ਟਰਮੀਨਲ ਨੂੰ ਤਿਆਰ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ਟਰਮੀਨਲ ਨੂੰ ਬੰਦ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ਟਰਮੀਨਲ ਕ੍ਰੈਸ਼ ਹੋ ਗਿਆ"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ਟਰਮੀਨਲ ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"ਜ਼ਬਰਦਸਤੀ ਬੰਦ ਕਰੋ"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ਚਾਲੂ ਹੈ"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਚੱਲਣ ਵਾਲੇ ਕਾਰਜ"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"ਸਿਸਟਮ ਇਵੈਂਟ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-pl/strings.xml b/android/TerminalApp/res/values-pl/strings.xml
index 924c14c..fe29d91 100644
--- a/android/TerminalApp/res/values-pl/strings.xml
+++ b/android/TerminalApp/res/values-pl/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Nie udało się zainstalować, ponieważ Wi-Fi jest niedostępne"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Nie udało się zainstalować. Spróbuj jeszcze raz"</string>
     <string name="action_settings" msgid="5729342767795123227">"Ustawienia"</string>
+    <string name="action_display" msgid="8487008779926038139">"Wyświetlacz"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Przygotowuję terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Zatrzymuję terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal uległ awarii"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal się zamyka"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Wymuś zamknięcie"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Układ <xliff:g id="ID_1">VirGL</xliff:g> jest włączony"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Długotrwałe zadania"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Zdarzenia systemowe"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-pt-rPT/strings.xml b/android/TerminalApp/res/values-pt-rPT/strings.xml
index 3a57ba6..8dece3d 100644
--- a/android/TerminalApp/res/values-pt-rPT/strings.xml
+++ b/android/TerminalApp/res/values-pt-rPT/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Falha ao instalar porque o Wi-Fi não está disponível"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Falha ao instalar. Tente novamente"</string>
     <string name="action_settings" msgid="5729342767795123227">"Definições"</string>
+    <string name="action_display" msgid="8487008779926038139">"Ecrã"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"A preparar o terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"A parar o terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"O terminal falhou"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"A app Terminal está a ser fechada"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Forçar fecho"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"A <xliff:g id="ID_1">VirGL</xliff:g> está ativada"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tarefas de longa duração"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Eventos do sistema"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-pt/strings.xml b/android/TerminalApp/res/values-pt/strings.xml
index 9d6a16f..ec0df78 100644
--- a/android/TerminalApp/res/values-pt/strings.xml
+++ b/android/TerminalApp/res/values-pt/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Falha ao instalar porque o Wi-Fi não está disponível"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Falha ao instalar. Tente de novo"</string>
     <string name="action_settings" msgid="5729342767795123227">"Configurações"</string>
+    <string name="action_display" msgid="8487008779926038139">"Tela"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Preparando o terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Interrompendo o terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"O terminal falhou"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"O terminal está fechando"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Forçar fechamento"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"O <xliff:g id="ID_1">VirGL</xliff:g> está ativado"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tarefas de longa duração"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Eventos do sistema"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ro/strings.xml b/android/TerminalApp/res/values-ro/strings.xml
index 779277e..fec9562 100644
--- a/android/TerminalApp/res/values-ro/strings.xml
+++ b/android/TerminalApp/res/values-ro/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Nu s-a putut instala deoarece nu este disponibilă o conexiune Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Nu s-a instalat. Încearcă din nou."</string>
     <string name="action_settings" msgid="5729342767795123227">"Setări"</string>
+    <string name="action_display" msgid="8487008779926038139">"Ecran"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Se pregătește terminalul"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Se oprește terminalul"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminalul s-a blocat"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminalul se închide"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Forțează închiderea"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> este activat"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Activități de durată"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Evenimente de sistem"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ru/strings.xml b/android/TerminalApp/res/values-ru/strings.xml
index ffdcaf6..eda9850 100644
--- a/android/TerminalApp/res/values-ru/strings.xml
+++ b/android/TerminalApp/res/values-ru/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Не удалось выполнить установку, так как сеть Wi-Fi недоступна."</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Сбой установки. Повторите попытку."</string>
     <string name="action_settings" msgid="5729342767795123227">"Настройки"</string>
+    <string name="action_display" msgid="8487008779926038139">"Экран"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Терминал подготавливается."</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Работа терминала останавливается."</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Произошел сбой терминала."</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Терминал закрывается"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Закрыть принудительно"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g>: включено."</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Длительные задачи"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Системные события"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-si/strings.xml b/android/TerminalApp/res/values-si/strings.xml
index cc67088..4ad9a5f 100644
--- a/android/TerminalApp/res/values-si/strings.xml
+++ b/android/TerminalApp/res/values-si/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi නොමැති නිසා ස්ථාපනය කිරීමට අසමත් විය"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ස්ථාපනය කිරීමට අසමත් විය. නැවත උත්සාහ කරන්න"</string>
     <string name="action_settings" msgid="5729342767795123227">"සැකසීම්"</string>
+    <string name="action_display" msgid="8487008779926038139">"සංදර්ශකය"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ටර්මිනලය සූදානම් කිරීම"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ටර්මිනලය නතර කිරීම"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ටර්මිනලය බිඳ වැටුණි"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ටර්මිනලය වැසෙමින් පවතී"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"බලෙන් වසන්න"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> සබලයි"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"දිගු කාලයක් ධාවනය වන කාර්යයන්"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"පද්ධති සිදුවීම්"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sk/strings.xml b/android/TerminalApp/res/values-sk/strings.xml
index 64abba6..a700b93 100644
--- a/android/TerminalApp/res/values-sk/strings.xml
+++ b/android/TerminalApp/res/values-sk/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Inštalácia sa nepodarila, pretože nie je k dispozícii Wi‑Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Nepodarilo sa nainštalovať. Skúste to znova."</string>
     <string name="action_settings" msgid="5729342767795123227">"Nastavenia"</string>
+    <string name="action_display" msgid="8487008779926038139">"Obrazovka"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminál sa pripravuje"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminál sa zastavuje"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminál spadol"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminál sa zatvára"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Vynútiť zavretie"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Procesor <xliff:g id="ID_1">VirGL</xliff:g> je aktivovaný"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dlho spustené úlohy"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systémové udalosti"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sl/strings.xml b/android/TerminalApp/res/values-sl/strings.xml
index 8d8dc3a..f6580aa 100644
--- a/android/TerminalApp/res/values-sl/strings.xml
+++ b/android/TerminalApp/res/values-sl/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Namestitev ni uspela, ker Wi-Fi ni na voljo"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Namestitev ni uspela. Poskusite znova."</string>
     <string name="action_settings" msgid="5729342767795123227">"Nastavitve"</string>
+    <string name="action_display" msgid="8487008779926038139">"Zaslon"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Pripravljanje terminala"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Ustavljanje terminala"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal se je zrušil"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal se zapira"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Vsili zapiranje"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> je omogočen"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Dolgotrajna opravila"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistemski dogodki"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sq/strings.xml b/android/TerminalApp/res/values-sq/strings.xml
index 871671d..6edfd85 100644
--- a/android/TerminalApp/res/values-sq/strings.xml
+++ b/android/TerminalApp/res/values-sq/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Instalimi dështoi për shkak se Wi-Fi nuk ofrohet"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Instalimi dështoi. Provo përsëri"</string>
     <string name="action_settings" msgid="5729342767795123227">"Cilësimet"</string>
+    <string name="action_display" msgid="8487008779926038139">"Ekrani"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminali po përgatitet"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminali po ndalohet"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminali u ndërpre aksidentalisht"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"\"Terminali\" po mbyllet"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Ndalo me forcë"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> është aktivizuar"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Detyrat afatgjata"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Ngjarjet e sistemit"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sr/strings.xml b/android/TerminalApp/res/values-sr/strings.xml
index 76e790d..eb9a58b 100644
--- a/android/TerminalApp/res/values-sr/strings.xml
+++ b/android/TerminalApp/res/values-sr/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Инсталирање није успело јер WiFi није доступан"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Инсталирање није успело. Пробајте поново"</string>
     <string name="action_settings" msgid="5729342767795123227">"Подешавања"</string>
+    <string name="action_display" msgid="8487008779926038139">"Екран"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Терминал се припрема"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Терминал се зауставља"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Терминал је отказао"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Терминал се затвара"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Принудно затвори"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> је омогућен"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Дуготрајни задаци"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Системски догађаји"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sv/strings.xml b/android/TerminalApp/res/values-sv/strings.xml
index 33b00d8..6ca94c3 100644
--- a/android/TerminalApp/res/values-sv/strings.xml
+++ b/android/TerminalApp/res/values-sv/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Det gick inte att installera eftersom att wifi inte är tillgängligt"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Installationen misslyckades. Försök igen"</string>
     <string name="action_settings" msgid="5729342767795123227">"Inställningar"</string>
+    <string name="action_display" msgid="8487008779926038139">"Skärm"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminalen förbereds"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Stoppar terminalen"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminalen kraschade"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminalen stängs av"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Tvinga avstängning"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> har aktiverats"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Långvariga uppgifter"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Systemhändelser"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sw/strings.xml b/android/TerminalApp/res/values-sw/strings.xml
index 2affb51..f0da173 100644
--- a/android/TerminalApp/res/values-sw/strings.xml
+++ b/android/TerminalApp/res/values-sw/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Imeshindwa kuweka kwenye kifaa kwa sababu Wi-Fi haipatikani"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Imeshindwa kuweka kwenye kifaa. Tafadhali jaribu tena"</string>
     <string name="action_settings" msgid="5729342767795123227">"Mipangilio"</string>
+    <string name="action_display" msgid="8487008779926038139">"Onyesho"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Inaandaa temino"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Inafunga temino"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Temino imeacha kufanya kazi"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Kituo kinafungwa"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Lazimisha kufunga"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> imewashwa"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Majukumu yanayodumu zaidi"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Matukio ya mfumo"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ta/strings.xml b/android/TerminalApp/res/values-ta/strings.xml
index a0e56d5..4942b27 100644
--- a/android/TerminalApp/res/values-ta/strings.xml
+++ b/android/TerminalApp/res/values-ta/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"வைஃபை கிடைக்காததால் நிறுவ முடியவில்லை"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"நிறுவ முடியவில்லை. மீண்டும் முயலவும்."</string>
     <string name="action_settings" msgid="5729342767795123227">"அமைப்புகள்"</string>
+    <string name="action_display" msgid="8487008779926038139">"டிஸ்ப்ளே"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"டெர்மினலைத் தயார்செய்கிறது"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"டெர்மினல் நிறுத்தப்படுகிறது"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"டெர்மினல் சிதைவடைந்தது"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"டெர்மினல் மூடப்படுகிறது"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"உடனே மூடு"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> இயக்கப்பட்டது"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"நீண்ட நேரம் இயங்கும் பணிகள்"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"சிஸ்டம் நிகழ்வுகள்"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-te/strings.xml b/android/TerminalApp/res/values-te/strings.xml
index 7eab5da..bce8c4d 100644
--- a/android/TerminalApp/res/values-te/strings.xml
+++ b/android/TerminalApp/res/values-te/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi అందుబాటులో లేని కారణంగా ఇన్‌స్టాల్ చేయడం విఫలమైంది"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ఇన్‌స్టాల్ చేయడం విఫలమైంది. దయచేసి మళ్లీ ట్రై చేయండి"</string>
     <string name="action_settings" msgid="5729342767795123227">"సెట్టింగ్‌లు"</string>
+    <string name="action_display" msgid="8487008779926038139">"డిస్‌ప్లే"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"టెర్మినల్‌ను సిద్ధం చేస్తోంది"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"టెర్మినల్‌ను ఆపివేస్తోంది"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"టెర్మినల్ క్రాష్ అయింది"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal మూసివేయబడుతోంది"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"బలవంతంగా మూసివేయండి"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> ప్రారంభించబడింది"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"ఎక్కువసేపు రన్ అయ్యే టాస్క్‌లు"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"సిస్టమ్ ఈవెంట్‌లు"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-th/strings.xml b/android/TerminalApp/res/values-th/strings.xml
index 77e0e5f..9fb2a92 100644
--- a/android/TerminalApp/res/values-th/strings.xml
+++ b/android/TerminalApp/res/values-th/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"ติดตั้งไม่สำเร็จเนื่องจากไม่มี Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"ติดตั้งไม่สำเร็จ โปรดลองอีกครั้ง"</string>
     <string name="action_settings" msgid="5729342767795123227">"การตั้งค่า"</string>
+    <string name="action_display" msgid="8487008779926038139">"การแสดงผล"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"กำลังเตรียมเทอร์มินัล"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"กำลังหยุดเทอร์มินัล"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"เทอร์มินัลขัดข้อง"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"เทอร์มินัลกำลังจะปิด"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"บังคับปิด"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"เปิดใช้งาน <xliff:g id="ID_1">VirGL</xliff:g> แล้ว"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"งานที่ใช้เวลานาน"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"เหตุการณ์ของระบบ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-tl/strings.xml b/android/TerminalApp/res/values-tl/strings.xml
index c11620e..5cdb3e7 100644
--- a/android/TerminalApp/res/values-tl/strings.xml
+++ b/android/TerminalApp/res/values-tl/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Hindi na-install dahil walang Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Hindi na-install. Pakisubukan ulit"</string>
     <string name="action_settings" msgid="5729342767795123227">"Mga Setting"</string>
+    <string name="action_display" msgid="8487008779926038139">"Display"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Inihahanda ang terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Hinihinto ang terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Nag-crash ang terminal"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Nagsasara ang terminal"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Sapilitang isara"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"Na-enable ang <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Mga gawaing matagal gawin"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Mga event ng system"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-tr/strings.xml b/android/TerminalApp/res/values-tr/strings.xml
index 3b2bf0b..780826a 100644
--- a/android/TerminalApp/res/values-tr/strings.xml
+++ b/android/TerminalApp/res/values-tr/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Kablosuz bağlantı olmadığından yükleme işlemi başarısız oldu"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Yüklenemedi. Lütfen tekrar deneyin"</string>
     <string name="action_settings" msgid="5729342767795123227">"Ayarlar"</string>
+    <string name="action_display" msgid="8487008779926038139">"Ekran"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminal hazırlanıyor"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminal durduruluyor"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal kilitlendi"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal kapanıyor"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Uygulamayı kapat"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> etkinleştirildi"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Uzun süredir çalışan görevler"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sistem etkinlikleri"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-uk/strings.xml b/android/TerminalApp/res/values-uk/strings.xml
index f3a4906..55bdcf3 100644
--- a/android/TerminalApp/res/values-uk/strings.xml
+++ b/android/TerminalApp/res/values-uk/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Не вдалося встановити, оскільки немає Wi-Fi-з’єднання"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Не вдалося встановити. Повторіть спробу."</string>
     <string name="action_settings" msgid="5729342767795123227">"Налаштування"</string>
+    <string name="action_display" msgid="8487008779926038139">"Відображення"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Підготовка термінала"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Зупинка термінала"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Збій термінала"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Термінал закривається"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Примусово закрити"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> увімкнено"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Довготривалі завдання"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Події системи"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ur/strings.xml b/android/TerminalApp/res/values-ur/strings.xml
index f0e5351..c1bf900 100644
--- a/android/TerminalApp/res/values-ur/strings.xml
+++ b/android/TerminalApp/res/values-ur/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"‫Wi-Fi دستیاب نہ ہونے کی وجہ سے انسٹال نہیں کیا جا سکا"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"انسٹال نہیں کیا جا سکا۔ براہ کرم دوبارہ کوشش کریں"</string>
     <string name="action_settings" msgid="5729342767795123227">"ترتیبات"</string>
+    <string name="action_display" msgid="8487008779926038139">"ڈسپلے"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"ٹرمینل تیار ہو رہا ہے"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"ٹرمینل کو روکا جا رہا ہے"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"ٹرمینل کریش ہو گیا"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"ٹرمینل بند ہو رہا ہے"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"زبردستی بند کریں"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"‫<xliff:g id="ID_1">VirGL</xliff:g> فعال ہے"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"لمبے وقت تک چلنے والے ٹاسکس"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"سسٹم ایونٹس"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-uz/strings.xml b/android/TerminalApp/res/values-uz/strings.xml
index 5c65633..8fecef9 100644
--- a/android/TerminalApp/res/values-uz/strings.xml
+++ b/android/TerminalApp/res/values-uz/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Wi-Fi mavjud emasligi sababli oʻrnatilmadi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Oʻrnatilmadi. Qayta urining"</string>
     <string name="action_settings" msgid="5729342767795123227">"Sozlamalar"</string>
+    <string name="action_display" msgid="8487008779926038139">"Ekran"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Terminal tayyorlanmoqda"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Terminal toʻxtatilmoqda"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal ishdan chiqdi"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal yopilmoqda"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Majburiy yopish"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> yoniq"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Uzoq davom etuvchi vazifalar"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Tizim tadbirlari"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-vi/strings.xml b/android/TerminalApp/res/values-vi/strings.xml
index 5013918..867d534 100644
--- a/android/TerminalApp/res/values-vi/strings.xml
+++ b/android/TerminalApp/res/values-vi/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Không cài đặt được do không có Wi-Fi"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Không cài đặt được. Vui lòng thử lại"</string>
     <string name="action_settings" msgid="5729342767795123227">"Cài đặt"</string>
+    <string name="action_display" msgid="8487008779926038139">"Màn hình"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Đang chuẩn bị Terminal"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Đang dừng Terminal"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Terminal gặp sự cố"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Terminal đang đóng"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Buộc đóng"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> đã được bật"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Tác vụ chạy trong thời gian dài"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Sự kiện hệ thống"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zh-rCN/strings.xml b/android/TerminalApp/res/values-zh-rCN/strings.xml
index 4d424ed..2c4d653 100644
--- a/android/TerminalApp/res/values-zh-rCN/strings.xml
+++ b/android/TerminalApp/res/values-zh-rCN/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"由于 WLAN 不可用,安装失败"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"安装失败,请重试"</string>
     <string name="action_settings" msgid="5729342767795123227">"设置"</string>
+    <string name="action_display" msgid="8487008779926038139">"显示"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"正在准备终端"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"正在停止终端"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"终端已崩溃"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"终端即将关闭"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"强行关闭"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> 已启用"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"长时间运行的任务"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"系统事件"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zh-rHK/strings.xml b/android/TerminalApp/res/values-zh-rHK/strings.xml
index 317ec3a..062dc2d 100644
--- a/android/TerminalApp/res/values-zh-rHK/strings.xml
+++ b/android/TerminalApp/res/values-zh-rHK/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"由於沒有可用的 Wi-Fi,因此無法安裝"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"無法安裝,請再試一次"</string>
     <string name="action_settings" msgid="5729342767795123227">"設定"</string>
+    <string name="action_display" msgid="8487008779926038139">"顯示"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"正在準備終端機"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"正在停止終端機"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"終端機當機"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"終端機正在關閉"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"強制關閉"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"已啟用 <xliff:g id="ID_1">VirGL</xliff:g>"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"長時間執行的工作"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"系統活動"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zh-rTW/strings.xml b/android/TerminalApp/res/values-zh-rTW/strings.xml
index d3576d5..352784c 100644
--- a/android/TerminalApp/res/values-zh-rTW/strings.xml
+++ b/android/TerminalApp/res/values-zh-rTW/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"無法連上 Wi-Fi,因此無法安裝"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"無法安裝,請再試一次"</string>
     <string name="action_settings" msgid="5729342767795123227">"設定"</string>
+    <string name="action_display" msgid="8487008779926038139">"螢幕"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"正在準備終端機"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"正在停止終端機"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"終端機當機"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"終端機正在關閉"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"強制關閉"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"<xliff:g id="ID_1">VirGL</xliff:g> 已啟用"</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"長時間執行的工作"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"系統事件"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zu/strings.xml b/android/TerminalApp/res/values-zu/strings.xml
index 8b81522..641fea0 100644
--- a/android/TerminalApp/res/values-zu/strings.xml
+++ b/android/TerminalApp/res/values-zu/strings.xml
@@ -33,6 +33,7 @@
     <string name="installer_error_no_wifi" msgid="1180164894845030969">"Yehlulekile ukufaka ngoba i-Wi-Fi ayitholakali"</string>
     <string name="installer_error_unknown" msgid="5657920711470180224">"Yehlulekile ukufaka. Sicela uzame futhi"</string>
     <string name="action_settings" msgid="5729342767795123227">"Amasethingi"</string>
+    <string name="action_display" msgid="8487008779926038139">"Veza"</string>
     <string name="vm_creation_message" msgid="6594953532721367502">"Ilungiselela itheminali"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Itheminali yokumisa"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Itheminali iphahlazekile"</string>
@@ -48,8 +49,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>
-    <!-- no translation found for settings_port_forwarding_active_ports_content (1818090784030797758) -->
-    <skip />
+    <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>
@@ -61,8 +61,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>
-    <!-- no translation found for settings_port_forwarding_notification_content (779450349212040908) -->
-    <skip />
+    <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>
@@ -89,4 +88,6 @@
     <string name="service_notification_close_title" msgid="1442526433361428844">"Itheminali iyavalwa"</string>
     <string name="service_notification_force_quit_action" msgid="3462226330416157775">"Phoqelela ukuvala"</string>
     <string name="virgl_enabled" msgid="5242525588039698086">"I-<xliff:g id="ID_1">VirGL</xliff:g> inikwe amandla."</string>
+    <string name="notification_channel_long_running_name" msgid="7916541360369402952">"Imisebenzi esebenza isikhathi eside"</string>
+    <string name="notification_channel_system_events_name" msgid="1004951444029742137">"Imicimbi yesistimu"</string>
 </resources>
diff --git a/android/TerminalApp/res/values/strings.xml b/android/TerminalApp/res/values/strings.xml
index d3440d3..44009c3 100644
--- a/android/TerminalApp/res/values/strings.xml
+++ b/android/TerminalApp/res/values/strings.xml
@@ -55,6 +55,9 @@
     <!-- Action bar icon name for the settings view CHAR LIMIT=none] -->
     <string name="action_settings">Settings</string>
 
+    <!-- Action bar icon name for showing the display activity CHAR LIMIT=none] -->
+    <string name="action_display">Display</string>
+
     <!-- Toast message to notify that preparing terminal to start [CHAR LIMIT=none] -->
     <string name="vm_creation_message">Preparing terminal</string>
     <!-- Toast message to notify that terminal is stopping [CHAR LIMIT=none] -->
@@ -172,4 +175,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/TerminalApp/res/values/styles.xml b/android/TerminalApp/res/values/styles.xml
index 3fb8e7d..13f070f 100644
--- a/android/TerminalApp/res/values/styles.xml
+++ b/android/TerminalApp/res/values/styles.xml
@@ -27,4 +27,15 @@
     <style name="VmTerminalAppTheme" parent="@style/Theme.Material3.DayNight.NoActionBar">
         <item name="android:windowLightStatusBar" tools:targetApi="m">?android:attr/isLightTheme</item>
     </style>
+    <style name="FullscreenTheme" parent="@style/Theme.Material3.DayNight.NoActionBar">
+        <item name="android:navigationBarColor">
+            @android:color/transparent
+        </item>
+        <item name="android:statusBarColor">
+            @android:color/transparent
+        </item>
+        <item name="android:windowLayoutInDisplayCutoutMode">
+            always
+        </item>
+    </style>
 </resources>
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 57779bf..33f3be1 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -2033,7 +2033,7 @@
     Owned(T),
 }
 
-impl<'a, T> AsRef<T> for BorrowedOrOwned<'a, T> {
+impl<T> AsRef<T> for BorrowedOrOwned<'_, T> {
     fn as_ref(&self) -> &T {
         match self {
             Self::Borrowed(b) => b,
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 096d3b5..df53bc6 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -1110,6 +1110,9 @@
     command.arg("--mem").arg(memory_mib.to_string());
 
     if let Some(cpus) = config.cpus {
+        #[cfg(target_arch = "aarch64")]
+        command.arg("--cpus").arg(cpus.to_string() + ",sve=[auto=true]");
+        #[cfg(not(target_arch = "aarch64"))]
         command.arg("--cpus").arg(cpus.to_string());
     }
 
@@ -1121,7 +1124,12 @@
                     command.arg("--virt-cpufreq");
                 }
             }
+            #[cfg(target_arch = "aarch64")]
+            command.arg("--cpus").arg("sve=[auto=true]");
         } else if let Some(cpus) = get_num_cpus() {
+            #[cfg(target_arch = "aarch64")]
+            command.arg("--cpus").arg(cpus.to_string() + ",sve=[auto=true]");
+            #[cfg(not(target_arch = "aarch64"))]
             command.arg("--cpus").arg(cpus.to_string());
         } else {
             bail!("Could not determine the number of CPUs in the system");
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 a426d22..d75c3f6 100755
--- a/build/debian/build.sh
+++ b/build/debian/build.sh
@@ -5,6 +5,8 @@
 # - Add Android-specific packages via a new class
 # - Use a stable release from debian-cloud-images
 
+SCRIPT_DIR="$(cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
+
 show_help() {
 	echo "Usage: sudo $0 [OPTION]... [FILE]"
 	echo "Builds a debian image and save it to FILE. [sudo is required]"
@@ -170,7 +172,7 @@
 }
 
 build_rust_as_deb() {
-	pushd "$(dirname "$0")/../../guest/$1" > /dev/null
+	pushd "$SCRIPT_DIR/../../guest/$1" > /dev/null
 	cargo deb \
 		--target "${arch}-unknown-linux-gnu" \
 		--output "${debian_cloud_image}/localdebs"
@@ -180,7 +182,7 @@
 build_ttyd() {
 	local ttyd_version=1.7.7
 	local url="https://github.com/tsl0922/ttyd/archive/refs/tags/${ttyd_version}.tar.gz"
-	cp -r "$(dirname "$0")/ttyd" "${workdir}/ttyd"
+	cp -r "$SCRIPT_DIR/ttyd" "${workdir}/ttyd"
 
 	pushd "${workdir}" > /dev/null
 	wget "${url}" -O - | tar xz
@@ -199,13 +201,13 @@
 copy_android_config() {
 	local src
 	local dst
-	src="$(dirname "$0")/fai_config"
+	src="$SCRIPT_DIR/fai_config"
 	dst="${config_space}"
 
 	cp -R "${src}"/* "${dst}"
-	cp "$(dirname "$0")/image.yaml" "${resources_dir}"
+	cp "$SCRIPT_DIR/image.yaml" "${resources_dir}"
 
-	cp -R "$(dirname "$0")/localdebs/" "${debian_cloud_image}/"
+	cp -R "$SCRIPT_DIR/localdebs/" "${debian_cloud_image}/"
 	build_ttyd
 	build_rust_as_deb forwarder_guest
 	build_rust_as_deb forwarder_guest_launcher
@@ -218,35 +220,55 @@
 		return
 	fi
 
+	local deb_base_url="https://deb.debian.org/debian"
+	local deb_security_base_url="https://security.debian.org/debian-security"
+
+	local pool_dir="pool/main/l/linux"
+	local ksrc_base_url="${deb_base_url}/${pool_dir}"
+	local ksrc_security_base_url="${deb_security_base_url}/${pool_dir}"
+
 	# NOTE: 6.1 is the latest LTS kernel for which Debian's kernel build scripts
 	#       work on Python 3.10, the default version on our Ubuntu 22.04 builders.
-	local debian_kver="6.1.119-1"
-	local custom_flavour="avf"
-	local ksrc_base_url="https://deb.debian.org/debian/pool/main/l/linux"
+	#
+	#       We track the latest Debian stable kernel version for the 6.1 branch,
+	#       which can be found at:
+	#       https://packages.debian.org/stable/linux-source-6.1
+	local debian_kver="6.1.123-1"
 
-	local dsc_url="${ksrc_base_url}/linux_${debian_kver}.dsc"
-	local debian_ksrc_url="${ksrc_base_url}/linux_${debian_kver}.debian.tar.xz"
-	local orig_ksrc_url="${ksrc_base_url}/linux_${debian_kver%-*}.orig.tar.xz"
+	local dsc_file="linux_${debian_kver}.dsc"
+	local orig_ksrc_file="linux_${debian_kver%-*}.orig.tar.xz"
+	local debian_ksrc_file="linux_${debian_kver}.debian.tar.xz"
 
 	# 0. Grab the kernel sources, and the latest debian keyrings
 	mkdir -p "${workdir}/kernel"
 	pushd "${workdir}/kernel" > /dev/null
-	wget "$dsc_url"
-	wget "$orig_ksrc_url"
-	wget "$debian_ksrc_url"
+
+	wget "${ksrc_security_base_url}/${dsc_file}" || \
+	wget "${ksrc_base_url}/${dsc_file}"
+
+	wget "${ksrc_security_base_url}/${orig_ksrc_file}" || \
+	wget "${ksrc_base_url}/${orig_ksrc_file}"
+
+	wget "${ksrc_security_base_url}/${debian_ksrc_file}" || \
+	wget "${ksrc_base_url}/${debian_ksrc_file}"
+
 	rsync -az --progress keyring.debian.org::keyrings/keyrings/ /usr/share/keyrings/
 
 	# 1. Verify, extract and merge patches into the original kernel sources
 	dpkg-source --require-strong-checksums \
 	            --require-valid-signature \
-	            --extract linux_${debian_kver}.dsc
+	            --extract "${dsc_file}"
 	pushd "linux-${debian_kver%-*}" > /dev/null
-	# TODO: Copy our own kernel patches to debian/patches
-	#       and add patch file names in the desired order to debian/patches/series
+
+	local kpatches_src="$SCRIPT_DIR/kernel_patches"
+	cp -r "${kpatches_src}/avf" debian/patches/
+	cat "${kpatches_src}/series" >> debian/patches/series
 	./debian/rules orig
 
-	local abi_kver="$(sed -nE 's;Package: linux-support-(.*);\1;p' debian/control)"
+	local custom_flavour="avf"
 	local debarch_flavour="${custom_flavour}-${debian_arch}"
+
+	local abi_kver="$(sed -nE 's;Package: linux-support-(.*);\1;p' debian/control)"
 	local abi_flavour="${abi_kver}-${debarch_flavour}"
 
 	# 2. Define our custom flavour and regenerate control file
@@ -296,7 +318,7 @@
 
 generate_output_package() {
 	fdisk -l "${raw_disk_image}"
-	local vm_config="$(realpath $(dirname "$0"))/vm_config.json.${arch}"
+	local vm_config="$SCRIPT_DIR/vm_config.json.${arch}"
 	local root_partition_num=1
 	local bios_partition_num=14
 	local efi_partition_num=15
diff --git a/build/debian/build_in_container.sh b/build/debian/build_in_container.sh
index 967f5ab..e3adcae 100755
--- a/build/debian/build_in_container.sh
+++ b/build/debian/build_in_container.sh
@@ -58,4 +58,4 @@
   -v "$ANDROID_BUILD_TOP/packages/modules/Virtualization:/root/Virtualization" \
   --workdir /root/Virtualization/build/debian \
   ubuntu:22.04 \
-  bash -c "/root/Virtualization/build/debian/build.sh -a $arch $release_flag $kernel_flag $save_workdir_flag $shell_condition bash"
+  bash -c "./build.sh -a $arch $release_flag $kernel_flag $save_workdir_flag $shell_condition bash"
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/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 98b558b..bf51fdb 100644
--- a/build/debian/fai_config/package_config/AVF
+++ b/build/debian/fai_config/package_config/AVF
@@ -8,3 +8,5 @@
 forwarder-guest
 forwarder-guest-launcher
 shutdown-runner
+weston
+xwayland
diff --git a/build/debian/kernel_patches/avf/arm64-balloon.patch b/build/debian/kernel_patches/avf/arm64-balloon.patch
new file mode 100644
index 0000000..3877ebb
--- /dev/null
+++ b/build/debian/kernel_patches/avf/arm64-balloon.patch
@@ -0,0 +1,550 @@
+From 71b755110581e7cab93f839c4617735fc682c679 Mon Sep 17 00:00:00 2001
+From: Keir Fraser <keirf@google.com>
+Date: Tue, 10 Dec 2024 08:28:12 +0000
+Subject: [PATCH 1/6] KVM: arm64: Define guest hypercalls
+
+---
+ include/linux/arm-smccc.h | 56 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 56 insertions(+)
+
+diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
+index 220c8c60e021..02dc0957ec2d 100644
+--- a/include/linux/arm-smccc.h
++++ b/include/linux/arm-smccc.h
+@@ -112,6 +112,14 @@
+ /* KVM "vendor specific" services */
+ #define ARM_SMCCC_KVM_FUNC_FEATURES		0
+ #define ARM_SMCCC_KVM_FUNC_PTP			1
++#define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO		2
++#define ARM_SMCCC_KVM_FUNC_MEM_SHARE		3
++#define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE		4
++#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD_INFO	5
++#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD_ENROLL	6
++#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD_MAP	7
++#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD_UNMAP	8
++#define ARM_SMCCC_KVM_FUNC_MEM_RELINQUISH	9
+ #define ARM_SMCCC_KVM_FUNC_FEATURES_2		127
+ #define ARM_SMCCC_KVM_NUM_FUNCS			128
+
+@@ -134,6 +142,54 @@
+ 			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
+ 			   ARM_SMCCC_KVM_FUNC_PTP)
+
++#define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID			\
++	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
++			   ARM_SMCCC_SMC_64,				\
++			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
++			   ARM_SMCCC_KVM_FUNC_HYP_MEMINFO)
++
++#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID			\
++	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
++			   ARM_SMCCC_SMC_64,				\
++			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
++			   ARM_SMCCC_KVM_FUNC_MEM_SHARE)
++
++#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID			\
++	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
++			   ARM_SMCCC_SMC_64,				\
++			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
++			   ARM_SMCCC_KVM_FUNC_MEM_UNSHARE)
++
++#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_RELINQUISH_FUNC_ID			\
++	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
++			   ARM_SMCCC_SMC_64,				\
++			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
++			   ARM_SMCCC_KVM_FUNC_MEM_RELINQUISH)
++
++#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_INFO_FUNC_ID		\
++	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
++			   ARM_SMCCC_SMC_64,				\
++			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
++			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD_INFO)
++
++#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_ENROLL_FUNC_ID		\
++	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
++			   ARM_SMCCC_SMC_64,				\
++			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
++			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD_ENROLL)
++
++#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_MAP_FUNC_ID			\
++	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
++			   ARM_SMCCC_SMC_64,				\
++			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
++			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD_MAP)
++
++#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_UNMAP_FUNC_ID		\
++	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
++			   ARM_SMCCC_SMC_64,				\
++			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
++			   ARM_SMCCC_KVM_FUNC_MMIO_GUARD_UNMAP)
++
+ /* ptp_kvm counter type ID */
+ #define KVM_PTP_VIRT_COUNTER			0
+ #define KVM_PTP_PHYS_COUNTER			1
+--
+2.47.0.338.g60cca15819-goog
+
+
+From 14104b188b1ce2b2e227a9f5426fc8cb4d777461 Mon Sep 17 00:00:00 2001
+From: Keir Fraser <keirf@google.com>
+Date: Thu, 26 May 2022 14:22:34 +0000
+Subject: [PATCH 2/6] ANDROID: Define mem_relinquish interface for releasing
+ memory to a hypervisor.
+
+On PKVM/ARM64 this uses the ARM SMCCC relinquish hypercall when available.
+
+Bug: 240239989
+Change-Id: Ifa85b641a48f348a2364cf8c6b06b6417f1eeedb
+Signed-off-by: Keir Fraser <keirf@google.com>
+Signed-off-by: Quentin Perret <qperret@google.com>
+---
+ arch/Kconfig                            |  3 ++
+ arch/arm64/Kconfig                      |  1 +
+ arch/arm64/include/asm/hypervisor.h     |  7 +++
+ arch/arm64/include/asm/mem_relinquish.h | 12 +++++
+ arch/arm64/kernel/setup.c               |  6 +++
+ arch/arm64/mm/Makefile                  |  1 +
+ arch/arm64/mm/mem_relinquish.c          | 58 +++++++++++++++++++++++++
+ drivers/firmware/smccc/kvm_guest.c      |  2 +
+ include/linux/mem_relinquish.h          | 20 +++++++++
+ 9 files changed, 110 insertions(+)
+ create mode 100644 arch/arm64/include/asm/mem_relinquish.h
+ create mode 100644 arch/arm64/mm/mem_relinquish.c
+ create mode 100644 include/linux/mem_relinquish.h
+
+diff --git a/arch/Kconfig b/arch/Kconfig
+index 8f138e580d1a..b5fb130a07e2 100644
+--- a/arch/Kconfig
++++ b/arch/Kconfig
+@@ -1316,6 +1316,9 @@ config RELR
+ config ARCH_HAS_MEM_ENCRYPT
+ 	bool
+
++config ARCH_HAS_MEM_RELINQUISH
++	bool
++
+ config ARCH_HAS_CC_PLATFORM
+ 	bool
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index 505c8a1ccbe0..935c16e89677 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -31,6 +31,7 @@ config ARM64
+ 	select ARCH_HAS_KCOV
+ 	select ARCH_HAS_KEEPINITRD
+ 	select ARCH_HAS_MEMBARRIER_SYNC_CORE
++	select ARCH_HAS_MEM_RELINQUISH
+ 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
+ 	select ARCH_HAS_PTE_DEVMAP
+ 	select ARCH_HAS_PTE_SPECIAL
+diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h
+index 0ae427f352c8..88f42d688eb0 100644
+--- a/arch/arm64/include/asm/hypervisor.h
++++ b/arch/arm64/include/asm/hypervisor.h
+@@ -5,6 +5,13 @@
+ #include <asm/xen/hypervisor.h>
+
+ void kvm_init_hyp_services(void);
++void kvm_arm_init_hyp_services(void);
+ bool kvm_arm_hyp_service_available(u32 func_id);
+
++#ifdef CONFIG_MEMORY_BALLOON
++void kvm_init_memrelinquish_services(void);
++#else
++static inline void kvm_init_memrelinquish_services(void) {}
++#endif
++
+ #endif
+diff --git a/arch/arm64/include/asm/mem_relinquish.h b/arch/arm64/include/asm/mem_relinquish.h
+new file mode 100644
+index 000000000000..a4ace9e6e413
+--- /dev/null
++++ b/arch/arm64/include/asm/mem_relinquish.h
+@@ -0,0 +1,12 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2022 Google LLC
++ * Author: Keir Fraser <keirf@google.com>
++ */
++
++#ifndef __ASM_MEM_RELINQUISH_H
++#define __ASM_MEM_RELINQUISH_H
++
++void page_relinquish(struct page *page);
++
++#endif	/* __ASM_MEM_RELINQUISH_H */
+diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
+index fea3223704b6..f55477b6c02e 100644
+--- a/arch/arm64/kernel/setup.c
++++ b/arch/arm64/kernel/setup.c
+@@ -40,6 +40,7 @@
+ #include <asm/elf.h>
+ #include <asm/cpufeature.h>
+ #include <asm/cpu_ops.h>
++#include <asm/hypervisor.h>
+ #include <asm/kasan.h>
+ #include <asm/numa.h>
+ #include <asm/sections.h>
+@@ -438,3 +439,8 @@ static int __init register_arm64_panic_block(void)
+ 	return 0;
+ }
+ device_initcall(register_arm64_panic_block);
++
++void kvm_arm_init_hyp_services(void)
++{
++	kvm_init_memrelinquish_services();
++}
+diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
+index ff1e800ba7a1..f6c1f3511907 100644
+--- a/arch/arm64/mm/Makefile
++++ b/arch/arm64/mm/Makefile
+@@ -3,6 +3,7 @@ obj-y				:= dma-mapping.o extable.o fault.o init.o \
+ 				   cache.o copypage.o flush.o \
+ 				   ioremap.o mmap.o pgd.o mmu.o \
+ 				   context.o proc.o pageattr.o
++obj-$(CONFIG_MEMORY_BALLOON)	+= mem_relinquish.o
+ obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
+ obj-$(CONFIG_PTDUMP_CORE)	+= ptdump.o
+ obj-$(CONFIG_PTDUMP_DEBUGFS)	+= ptdump_debugfs.o
+diff --git a/arch/arm64/mm/mem_relinquish.c b/arch/arm64/mm/mem_relinquish.c
+new file mode 100644
+index 000000000000..c95bcbb14d92
+--- /dev/null
++++ b/arch/arm64/mm/mem_relinquish.c
+@@ -0,0 +1,58 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2022 Google LLC
++ * Author: Keir Fraser <keirf@google.com>
++ */
++
++#include <linux/arm-smccc.h>
++#include <linux/memory.h>
++#include <linux/mm.h>
++#include <linux/types.h>
++
++#include <asm/hypervisor.h>
++
++static unsigned long memshare_granule_sz;
++
++void kvm_init_memrelinquish_services(void)
++{
++	int i;
++	struct arm_smccc_res res;
++	const u32 funcs[] = {
++		ARM_SMCCC_KVM_FUNC_HYP_MEMINFO,
++		ARM_SMCCC_KVM_FUNC_MEM_RELINQUISH,
++	};
++
++	for (i = 0; i < ARRAY_SIZE(funcs); ++i) {
++		if (!kvm_arm_hyp_service_available(funcs[i]))
++			return;
++	}
++
++	arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID,
++			     0, 0, 0, &res);
++	if (res.a0 > PAGE_SIZE) /* Includes error codes */
++		return;
++
++	memshare_granule_sz = res.a0;
++}
++
++void page_relinquish(struct page *page)
++{
++	phys_addr_t phys, end;
++	u32 func_id = ARM_SMCCC_VENDOR_HYP_KVM_MEM_RELINQUISH_FUNC_ID;
++
++	if (!memshare_granule_sz)
++		return;
++
++	phys = page_to_phys(page);
++	end = phys + PAGE_SIZE;
++
++	while (phys < end) {
++		struct arm_smccc_res res;
++
++		arm_smccc_1_1_invoke(func_id, phys, 0, 0, &res);
++		BUG_ON(res.a0 != SMCCC_RET_SUCCESS);
++
++		phys += memshare_granule_sz;
++	}
++}
++EXPORT_SYMBOL_GPL(page_relinquish);
+diff --git a/drivers/firmware/smccc/kvm_guest.c b/drivers/firmware/smccc/kvm_guest.c
+index 89a68e7eeaa6..0b6a1b2a0857 100644
+--- a/drivers/firmware/smccc/kvm_guest.c
++++ b/drivers/firmware/smccc/kvm_guest.c
+@@ -39,6 +39,8 @@ void __init kvm_init_hyp_services(void)
+
+ 	pr_info("hypervisor services detected (0x%08lx 0x%08lx 0x%08lx 0x%08lx)\n",
+ 		 res.a3, res.a2, res.a1, res.a0);
++
++	kvm_arm_init_hyp_services();
+ }
+
+ bool kvm_arm_hyp_service_available(u32 func_id)
+diff --git a/include/linux/mem_relinquish.h b/include/linux/mem_relinquish.h
+new file mode 100644
+index 000000000000..6b7bf861d92d
+--- /dev/null
++++ b/include/linux/mem_relinquish.h
+@@ -0,0 +1,20 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2022 Google LLC
++ * Author: Keir Fraser <keirf@google.com>
++ */
++
++#ifndef __MEM_RELINQUISH_H__
++#define __MEM_RELINQUISH_H__
++
++#ifdef CONFIG_ARCH_HAS_MEM_RELINQUISH
++
++#include <asm/mem_relinquish.h>
++
++#else	/* !CONFIG_ARCH_HAS_MEM_RELINQUISH */
++
++static inline void page_relinquish(struct page *page) { }
++
++#endif	/* CONFIG_ARCH_HAS_MEM_RELINQUISH */
++
++#endif	/* __MEM_RELINQUISH_H__ */
+--
+2.47.0.338.g60cca15819-goog
+
+
+From 4de68c3d8410bef6a5544caf3835eba8357e08d1 Mon Sep 17 00:00:00 2001
+From: Keir Fraser <keirf@google.com>
+Date: Wed, 9 Nov 2022 13:53:28 +0000
+Subject: [PATCH 3/6] ANDROID: KVM: arm64: memory balloon: Notify hyp when
+ ballooning
+
+When running as a protected VM, the hypervisor isolates the VM's
+memory pages from the host. Returning ownership of a VM page
+therefore requires hypervisor involvement, and acknowledgement from
+the protected VM that it is voluntarily cooperating.
+
+To this end, notify pages via the new relinquish hypercall when they
+are entered into the memory balloon.
+
+Bug: 240239989
+Change-Id: Ic89b45312a7478ddff081a934d99e693eded92dc
+Signed-off-by: Keir Fraser <keirf@google.com>
+Signed-off-by: Quentin Perret <qperret@google.com>
+---
+ include/linux/balloon_compaction.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/include/linux/balloon_compaction.h b/include/linux/balloon_compaction.h
+index 5ca2d5699620..318cfe8b57a6 100644
+--- a/include/linux/balloon_compaction.h
++++ b/include/linux/balloon_compaction.h
+@@ -43,6 +43,7 @@
+ #include <linux/err.h>
+ #include <linux/fs.h>
+ #include <linux/list.h>
++#include <linux/mem_relinquish.h>
+
+ /*
+  * Balloon device information descriptor.
+@@ -95,6 +96,7 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon,
+ 	__SetPageMovable(page, &balloon_mops);
+ 	set_page_private(page, (unsigned long)balloon);
+ 	list_add(&page->lru, &balloon->pages);
++	page_relinquish(page);
+ }
+
+ /*
+@@ -139,6 +141,7 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon,
+ {
+ 	__SetPageOffline(page);
+ 	list_add(&page->lru, &balloon->pages);
++	page_relinquish(page);
+ }
+
+ static inline void balloon_page_delete(struct page *page)
+--
+2.47.0.338.g60cca15819-goog
+
+
+From f34713f8af1fe2ed50297743315606f880fcbd03 Mon Sep 17 00:00:00 2001
+From: Keir Fraser <keirf@google.com>
+Date: Thu, 18 Aug 2022 10:41:35 +0000
+Subject: [PATCH 4/6] ANDROID: KVM: arm64: balloon: Notify hyp before reporting
+ free pages to host
+
+When running as a protected VM, the hypervisor isolates the VM's
+memory pages from the host. Returning ownership of a VM page therefore
+requires hypervisor involvement, and acknowledgement from the
+protected VM that it is voluntarily cooperating.
+
+To this end, notify pages via the new relinquish hypercall when they
+are being reported to the host as free and available for temporary
+reclaim.
+
+Bug: 240239989
+Change-Id: I8718e468be63c3aacb2f79ff141fbcedd6d19b56
+Signed-off-by: Keir Fraser <keirf@google.com>
+Signed-off-by: Quentin Perret <qperret@google.com>
+---
+ mm/page_reporting.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/mm/page_reporting.c b/mm/page_reporting.c
+index 382958eef8a9..5c4b1fb73187 100644
+--- a/mm/page_reporting.c
++++ b/mm/page_reporting.c
+@@ -7,6 +7,7 @@
+ #include <linux/module.h>
+ #include <linux/delay.h>
+ #include <linux/scatterlist.h>
++#include <linux/mem_relinquish.h>
+
+ #include "page_reporting.h"
+ #include "internal.h"
+@@ -120,7 +121,7 @@ page_reporting_cycle(struct page_reporting_dev_info *prdev, struct zone *zone,
+ 	unsigned int page_len = PAGE_SIZE << order;
+ 	struct page *page, *next;
+ 	long budget;
+-	int err = 0;
++	int i, err = 0;
+
+ 	/*
+ 	 * Perform early check, if free area is empty there is
+@@ -175,6 +176,10 @@ page_reporting_cycle(struct page_reporting_dev_info *prdev, struct zone *zone,
+ 			--(*offset);
+ 			sg_set_page(&sgl[*offset], page, page_len, 0);
+
++			/* Notify hyp that these pages are reclaimable. */
++			for (i = 0; i < (1<<order); i++)
++				page_relinquish(page+i);
++
+ 			continue;
+ 		}
+
+--
+2.47.0.338.g60cca15819-goog
+
+
+From 429502a582c1c900681a82fb94f9078d0569c731 Mon Sep 17 00:00:00 2001
+From: Keir Fraser <keirf@google.com>
+Date: Thu, 18 Aug 2022 11:20:25 +0000
+Subject: [PATCH 5/6] ANDROID: virtio_balloon: Do not translate reported pages
+ through DMA API
+
+The free-page reporting and hinting queues do not pass arrays of page
+addresses (like the basic inflate queue) but instead pass the free page
+ranges as buffers. This does not work well with DMA API: The host wants
+to know the GPA, not an IOVA.
+
+For these two virtqueues, disable DMA API and pass through buffers untranslated.
+
+Bug: 240239989
+Change-Id: I2d13a8b7e8f6775819de7fe96f4579afa08b1300
+Signed-off-by: Keir Fraser <keirf@google.com>
+[ qperret@: Fixed minor context conflict in virtio.h ]
+Signed-off-by: Quentin Perret <qperret@google.com>
+---
+ drivers/virtio/virtio_balloon.c |  8 ++++++--
+ drivers/virtio/virtio_ring.c    | 10 ++++++++++
+ include/linux/virtio.h          |  2 ++
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
+index 3f78a3a1eb75..4c85349024c1 100644
+--- a/drivers/virtio/virtio_balloon.c
++++ b/drivers/virtio/virtio_balloon.c
+@@ -553,11 +553,15 @@ static int init_vqs(struct virtio_balloon *vb)
+ 		virtqueue_kick(vb->stats_vq);
+ 	}
+
+-	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
++	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) {
+ 		vb->free_page_vq = vqs[VIRTIO_BALLOON_VQ_FREE_PAGE];
++		virtqueue_disable_dma_api_for_buffers(vb->free_page_vq);
++	}
+
+-	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING))
++	if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_REPORTING)) {
+ 		vb->reporting_vq = vqs[VIRTIO_BALLOON_VQ_REPORTING];
++		virtqueue_disable_dma_api_for_buffers(vb->reporting_vq);
++	}
+
+ 	return 0;
+ }
+diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
+index 2e7689bb933b..3eca7140bd80 100644
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -2863,4 +2863,14 @@ const struct vring *virtqueue_get_vring(struct virtqueue *vq)
+ }
+ EXPORT_SYMBOL_GPL(virtqueue_get_vring);
+
++/*
++ * Prevents use of DMA API for buffers passed via the specified virtqueue.
++ * DMA API may still be used for the vrings themselves.
++ */
++void virtqueue_disable_dma_api_for_buffers(struct virtqueue *vq)
++{
++	to_vvq(vq)->use_dma_api = false;
++}
++EXPORT_SYMBOL_GPL(virtqueue_disable_dma_api_for_buffers);
++
+ MODULE_LICENSE("GPL");
+diff --git a/include/linux/virtio.h b/include/linux/virtio.h
+index dcab9c7e8784..34e936343ae4 100644
+--- a/include/linux/virtio.h
++++ b/include/linux/virtio.h
+@@ -96,6 +96,8 @@ dma_addr_t virtqueue_get_used_addr(struct virtqueue *vq);
+ int virtqueue_resize(struct virtqueue *vq, u32 num,
+ 		     void (*recycle)(struct virtqueue *vq, void *buf));
+
++void virtqueue_disable_dma_api_for_buffers(struct virtqueue *vq);
++
+ /**
+  * struct virtio_device - representation of a device using virtio
+  * @index: unique position on the virtio bus
+--
+2.47.0.338.g60cca15819-goog
+
+
+From 49de3a1d0bb478858eb66a5b853f0d0a5b1909dc Mon Sep 17 00:00:00 2001
+From: Keir Fraser <keirf@google.com>
+Date: Thu, 17 Nov 2022 14:59:38 +0000
+Subject: [PATCH 6/6] ANDROID: virtio_balloon: Do not clear
+ VIRTIO_F_ACCESS_PLATFORM
+
+This essentially reverts commit e41b1355508debe45fda33
+"virtio_balloon: disable VIOMMU support".
+
+Although the virtio_balloon driver does not translate through a
+VIOMMU (or bounce buffer) the pages that it sends to the device,
+it *does* need to perform these translations on the virtio rings
+themselves.
+
+This fixes virtio_balloon initialisation inside a PKVM/ARM64
+protected virtual machine.
+
+Bug: 240239989
+Change-Id: I2a84eec870fd638223b231e5c4d1c27216dc40a2
+Signed-off-by: Keir Fraser <keirf@google.com>
+Signed-off-by: Quentin Perret <qperret@google.com>
+---
+ drivers/virtio/virtio_balloon.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
+index 4c85349024c1..72fe24005bc0 100644
+--- a/drivers/virtio/virtio_balloon.c
++++ b/drivers/virtio/virtio_balloon.c
+@@ -1097,7 +1097,6 @@ static int virtballoon_validate(struct virtio_device *vdev)
+ 	else if (!virtio_has_feature(vdev, VIRTIO_BALLOON_F_PAGE_POISON))
+ 		__virtio_clear_bit(vdev, VIRTIO_BALLOON_F_REPORTING);
+
+-	__virtio_clear_bit(vdev, VIRTIO_F_ACCESS_PLATFORM);
+ 	return 0;
+ }
+
+--
+2.47.0.338.g60cca15819-goog
diff --git a/build/debian/kernel_patches/series b/build/debian/kernel_patches/series
new file mode 100644
index 0000000..573a1fb
--- /dev/null
+++ b/build/debian/kernel_patches/series
@@ -0,0 +1,2 @@
+# AVF patches
+avf/arm64-balloon.patch
diff --git a/docs/microdroid_vendor_modules.md b/docs/microdroid_vendor_modules.md
index 6ead195..11ce611 100644
--- a/docs/microdroid_vendor_modules.md
+++ b/docs/microdroid_vendor_modules.md
@@ -78,7 +78,7 @@
 `/apex/com.android.virt/bin/vm run-microdroid` CLI commands, e.g.:
 
 ```
-adb shell /apex/com.android.virt/bin/vm/run-microdroid \
+adb shell /apex/com.android.virt/bin/vm run-microdroid \
   --debug full \
   --vendor /vendor/etc/avf/microdroid/microdroid_vendor.img
 ```
@@ -103,7 +103,7 @@
 Microdroid vendor partition, e.g.:
 
 ```
-adb shell /apex/com.android.virt/bin/vm/run-microdroid \
+adb shell /apex/com.android.virt/bin/vm run-microdroid \
   --debug full \
   --protected \
   --vendor /vendor/etc/avf/microdroid/microdroid_vendor.img
diff --git a/guest/apkdmverity/src/main.rs b/guest/apkdmverity/src/main.rs
index d2f88ae..2fc964b 100644
--- a/guest/apkdmverity/src/main.rs
+++ b/guest/apkdmverity/src/main.rs
@@ -27,6 +27,7 @@
 use apkverify::{HashAlgorithm, V4Signature};
 use clap::{arg, Arg, ArgAction, Command};
 use dm::loopdevice;
+use dm::loopdevice::LoopConfigOptions;
 use dm::util;
 use dm::verity::{DmVerityHashAlgorithm, DmVerityTargetBuilder};
 use itertools::Itertools;
@@ -109,9 +110,13 @@
         }
         (
             loopdevice::attach(
-                &apk, 0, apk_size, /* direct_io */ true, /* writable */ false,
+                &apk,
+                0,
+                apk_size,
+                &LoopConfigOptions { direct_io: true, ..Default::default() },
             )
-            .context("Failed to attach APK to a loop device")?,
+            .context("Failed to attach APK to a loop device")?
+            .path,
             apk_size,
         )
     };
@@ -125,10 +130,9 @@
     // Due to unknown reason(b/191344832), we can't enable "direct IO" for the IDSIG file (backing
     // the hash). For now we don't use "direct IO" but it seems OK since the IDSIG file is very
     // small and the benefit of direct-IO would be negliable.
-    let hash_device = loopdevice::attach(
-        &idsig, offset, size, /* direct_io */ false, /* writable */ false,
-    )
-    .context("Failed to attach idsig to a loop device")?;
+    let hash_device = loopdevice::attach(&idsig, offset, size, &LoopConfigOptions::default())
+        .context("Failed to attach idsig to a loop device")?
+        .path;
 
     // Build a dm-verity target spec from the information from the idsig file. The apk and the
     // idsig files are used as the data device and the hash device, respectively.
@@ -347,18 +351,17 @@
         // of the data device is done in the scopeguard for the return value of `enable_verity`
         // below. Only the idsig_loop_device needs detatching.
         let apk_loop_device = loopdevice::attach(
-            &apk_path, 0, apk_size, /* direct_io */ true, /* writable */ false,
+            &apk_path,
+            0,
+            apk_size,
+            &LoopConfigOptions { direct_io: true, ..Default::default() },
         )
-        .unwrap();
+        .unwrap()
+        .path;
         let idsig_loop_device = scopeguard::guard(
-            loopdevice::attach(
-                &idsig_path,
-                0,
-                idsig_size,
-                /* direct_io */ false,
-                /* writable */ false,
-            )
-            .unwrap(),
+            loopdevice::attach(&idsig_path, 0, idsig_size, &LoopConfigOptions::default())
+                .unwrap()
+                .path,
             |dev| loopdevice::detach(dev).unwrap(),
         );
 
diff --git a/guest/authfs/src/common.rs b/guest/authfs/src/common.rs
index 6556fde..fc5af89 100644
--- a/guest/authfs/src/common.rs
+++ b/guest/authfs/src/common.rs
@@ -18,7 +18,7 @@
 pub const CHUNK_SIZE: u64 = 4096;
 
 pub fn divide_roundup(dividend: u64, divisor: u64) -> u64 {
-    (dividend + divisor - 1) / divisor
+    dividend.div_ceil(divisor)
 }
 
 /// Given `offset` and `length`, generates (offset, size) tuples that together form the same length,
diff --git a/guest/authfs/src/fsverity/metadata/metadata.rs b/guest/authfs/src/fsverity/metadata/metadata.rs
index 54d0145..2e78190 100644
--- a/guest/authfs/src/fsverity/metadata/metadata.rs
+++ b/guest/authfs/src/fsverity/metadata/metadata.rs
@@ -131,8 +131,7 @@
     };
 
     // merkle tree is at the next 4K boundary
-    let merkle_tree_offset =
-        (metadata_file.stream_position()? + CHUNK_SIZE - 1) / CHUNK_SIZE * CHUNK_SIZE;
+    let merkle_tree_offset = (metadata_file.stream_position()?).div_ceil(CHUNK_SIZE) * CHUNK_SIZE;
 
     Ok(Box::new(FSVerityMetadata { header, digest, signature, metadata_file, merkle_tree_offset }))
 }
diff --git a/guest/authfs/src/fusefs.rs b/guest/authfs/src/fusefs.rs
index fa4076d..9e49046 100644
--- a/guest/authfs/src/fusefs.rs
+++ b/guest/authfs/src/fusefs.rs
@@ -816,7 +816,7 @@
                     // FUSE ioctl is limited, thus we can't implement fs-verity ioctls without a
                     // kernel change (see b/196635431). Until it's possible, use
                     // xattr to expose what we need as an authfs specific API.
-                    if name != CStr::from_bytes_with_nul(b"authfs.fsverity.digest\0").unwrap() {
+                    if name != c"authfs.fsverity.digest" {
                         return Err(io::Error::from_raw_os_error(libc::ENODATA));
                     }
 
diff --git a/guest/forwarder_guest/.gitignore b/guest/forwarder_guest/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/guest/forwarder_guest/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/guest/forwarder_guest_launcher/.gitignore b/guest/forwarder_guest_launcher/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/guest/forwarder_guest_launcher/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/guest/microdroid_launcher/Android.bp b/guest/microdroid_launcher/Android.bp
index 42c18cb..893ee98 100644
--- a/guest/microdroid_launcher/Android.bp
+++ b/guest/microdroid_launcher/Android.bp
@@ -12,5 +12,10 @@
         "libdl_android",
         "liblog",
     ],
+    static_libs: [
+        "libapexutil",
+        "libprotobuf-cpp-lite",
+        "lib_apex_manifest_proto_lite",
+    ],
     header_libs: ["vm_payload_headers"],
 }
diff --git a/guest/microdroid_launcher/main.cpp b/guest/microdroid_launcher/main.cpp
index 5ae9956..8e3d4e4 100644
--- a/guest/microdroid_launcher/main.cpp
+++ b/guest/microdroid_launcher/main.cpp
@@ -16,7 +16,9 @@
 
 #include <android-base/logging.h>
 #include <android-base/result.h>
+#include <android-base/strings.h>
 #include <android/dlext.h>
+#include <apexutil.h>
 #include <dlfcn.h>
 
 #include <cstdlib>
@@ -25,8 +27,11 @@
 
 #include "vm_main.h"
 
+using android::apex::GetActivePackages;
 using android::base::Error;
+using android::base::Join;
 using android::base::Result;
+using android::base::StringReplace;
 
 extern "C" {
 enum {
@@ -43,6 +48,8 @@
 extern bool android_link_namespaces(struct android_namespace_t* from,
                                     struct android_namespace_t* to,
                                     const char* shared_libs_sonames);
+
+extern struct android_namespace_t* android_get_exported_namespace(const char* name);
 } // extern "C"
 
 static Result<void*> load(const std::string& libname);
@@ -108,6 +115,32 @@
         return Error() << "Failed to link namespace: " << dlerror();
     }
 
+    // Make libraries provided by APEXes available to the payload
+    for (const auto& [_path, manifest] : GetActivePackages("/apex")) {
+        std::string namespace_name = StringReplace(manifest.name(), ".", "_", /* all */ true);
+        android_namespace_t* apex_ns = android_get_exported_namespace(namespace_name.c_str());
+        if (apex_ns == nullptr) {
+            // This means the namespace is configured as 'visible=false'. We can't link to an
+            // invisible namespace.
+            continue;
+        }
+
+        std::vector<std::string> libs = {manifest.providenativelibs().begin(),
+                                         manifest.providenativelibs().end()};
+        if (libs.size() == 0) {
+            continue;
+        }
+        std::string shared_lib_sonames = Join(libs, ':');
+
+        if (!android_link_namespaces(new_ns, apex_ns, shared_lib_sonames.c_str())) {
+            return Error() << "Failed to link APEX namespace " << namespace_name << ": "
+                           << dlerror();
+        }
+
+        LOG(INFO) << "Linked APEX namespace " << namespace_name << " with shared libs "
+                  << shared_lib_sonames;
+    }
+
     const android_dlextinfo info = {
             .flags = ANDROID_DLEXT_USE_NAMESPACE,
             .library_namespace = new_ns,
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 30c4299..8d02d97 100644
--- a/guest/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
+++ b/guest/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
@@ -130,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/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 c4a9111..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 {
@@ -116,6 +117,10 @@
             .or_service_specific_exception(-1)?;
         Ok(())
     }
+
+    fn isNewInstance(&self) -> binder::Result<bool> {
+        Ok(self.is_new_instance)
+    }
 }
 
 impl Interface for VmPayloadService {}
@@ -126,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<()> {
@@ -147,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 5489751..5999122 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;
@@ -99,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() {
@@ -116,11 +118,13 @@
         let session = SkVmSession::new(vm_service, &explicit_dice, policy)?;
         let mut skp_secret = Zeroizing::new([0u8; SECRET_SIZE]);
         if let Some(secret) = session.get_secret(id)? {
-            *skp_secret = secret
+            *skp_secret = secret;
+            *state = VmInstanceState::PreviouslySeen;
         } else {
             log::warn!("No entry found in Secretkeeper for this VM instance, creating new secret.");
             *skp_secret = rand::random();
             session.store_secret(id, skp_secret.clone())?;
+            *state = VmInstanceState::NewlyCreated;
         }
         Ok(Self::V2 {
             instance_id: id,
diff --git a/guest/pvmfw/Android.bp b/guest/pvmfw/Android.bp
index da056d6..4ef57a6 100644
--- a/guest/pvmfw/Android.bp
+++ b/guest/pvmfw/Android.bp
@@ -113,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/src/ops.rs b/guest/pvmfw/avb/src/ops.rs
index 62bf239..780e23b 100644
--- a/guest/pvmfw/avb/src/ops.rs
+++ b/guest/pvmfw/avb/src/ops.rs
@@ -60,6 +60,14 @@
         &mut self,
         partition_name: &CStr,
     ) -> SlotVerifyResult<SlotVerifyData<'a>> {
+        // Note that this call manages to verify the initrd images using hashes contained in the
+        // (unique) VBMeta from the end of self.kernel because if
+        //
+        // - read_from_partition("vbmeta") returns AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION and
+        // - we do NOT pass AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION to slot_verify()
+        //
+        // then libavb (specifically, avb_slot_verify()) falls back to retrieving VBMeta from the
+        // footer of the "boot" partition i.e. self.kernel (see PartitionName::Kernel).
         slot_verify(
             self,
             &[partition_name],
diff --git a/guest/pvmfw/avb/tests/api_test.rs b/guest/pvmfw/avb/tests/api_test.rs
index 23e05d4..df33830 100644
--- a/guest/pvmfw/avb/tests/api_test.rs
+++ b/guest/pvmfw/avb/tests/api_test.rs
@@ -23,7 +23,6 @@
 use std::{
     fs,
     mem::{offset_of, size_of},
-    ptr,
 };
 use utils::*;
 
@@ -357,6 +356,32 @@
 }
 
 #[test]
+fn tampered_normal_initrd_fails_verification() -> Result<()> {
+    let mut initrd = load_latest_initrd_normal()?;
+    initrd[1] = !initrd[1]; // Flip the bits
+
+    assert_payload_verification_with_initrd_fails(
+        &load_latest_signed_kernel()?,
+        &initrd,
+        &load_trusted_public_key()?,
+        SlotVerifyError::Verification(None).into(),
+    )
+}
+
+#[test]
+fn tampered_debug_initrd_fails_verification() -> Result<()> {
+    let mut initrd = load_latest_initrd_debug()?;
+    initrd[1] = !initrd[1]; // Flip the bits
+
+    assert_payload_verification_with_initrd_fails(
+        &load_latest_signed_kernel()?,
+        &initrd,
+        &load_trusted_public_key()?,
+        SlotVerifyError::Verification(None).into(),
+    )
+}
+
+#[test]
 fn tampered_vbmeta_fails_verification() -> Result<()> {
     let mut kernel = load_latest_signed_kernel()?;
     let footer = extract_avb_footer(&kernel)?;
@@ -414,9 +439,9 @@
     // vbmeta_header is unaligned; copy flags to local variable
     let vbmeta_header_flags = vbmeta_header.flags;
     assert_eq!(0, vbmeta_header_flags, "The disable flag should not be set in the latest kernel.");
-    let flags_addr = ptr::addr_of!(vbmeta_header.flags) as *const u8;
+    let flags_addr = (&raw const vbmeta_header.flags).cast::<u8>();
     // SAFETY: It is safe as both raw pointers `flags_addr` and `vbmeta_header` are not null.
-    let flags_offset = unsafe { flags_addr.offset_from(ptr::addr_of!(vbmeta_header) as *const u8) };
+    let flags_offset = unsafe { flags_addr.offset_from((&raw const vbmeta_header).cast::<u8>()) };
     let flags_offset = usize::try_from(footer.vbmeta_offset)? + usize::try_from(flags_offset)?;
 
     // Act.
diff --git a/guest/pvmfw/src/device_assignment.rs b/guest/pvmfw/src/device_assignment.rs
index bb2e6ce..fb485fe 100644
--- a/guest/pvmfw/src/device_assignment.rs
+++ b/guest/pvmfw/src/device_assignment.rs
@@ -166,7 +166,7 @@
     tokens: Vec<&'a [u8]>,
 }
 
-impl<'a> fmt::Debug for DtPathTokens<'a> {
+impl fmt::Debug for DtPathTokens<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut list = f.debug_list();
         for token in &self.tokens {
diff --git a/guest/pvmfw/src/dice.rs b/guest/pvmfw/src/dice.rs
index a72c1fc..f49fedb 100644
--- a/guest/pvmfw/src/dice.rs
+++ b/guest/pvmfw/src/dice.rs
@@ -92,7 +92,8 @@
         let mode = to_dice_mode(data.debug_level);
         // We use rollback_index from vbmeta as the security_version field in dice certificate.
         let security_version = data.rollback_index;
-        let rkp_vm_marker = data.has_capability(Capability::RemoteAttest);
+        let rkp_vm_marker = data.has_capability(Capability::RemoteAttest)
+            || data.has_capability(Capability::TrustySecurityVm);
 
         Ok(Self { code_hash, auth_hash, mode, security_version, rkp_vm_marker })
     }
@@ -156,9 +157,7 @@
     fn generate_config_descriptor(&self, instance_hash: Option<Hash>) -> Result<Vec<u8>> {
         let mut config = Vec::with_capacity(4);
         config.push((cbor!(COMPONENT_NAME_KEY)?, cbor!("vm_entry")?));
-        if cfg!(dice_changes) {
-            config.push((cbor!(SECURITY_VERSION_KEY)?, cbor!(self.security_version)?));
-        }
+        config.push((cbor!(SECURITY_VERSION_KEY)?, cbor!(self.security_version)?));
         if self.rkp_vm_marker {
             config.push((cbor!(RKP_VM_MARKER_KEY)?, Value::Null))
         }
@@ -185,6 +184,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;
@@ -244,19 +244,12 @@
         assert_eq!(config_map.get(&COMPONENT_NAME_KEY).unwrap().as_text().unwrap(), "vm_entry");
         assert_eq!(config_map.get(&COMPONENT_VERSION_KEY), None);
         assert_eq!(config_map.get(&RESETTABLE_KEY), None);
-        if cfg!(dice_changes) {
-            assert_eq!(
-                config_map.get(&SECURITY_VERSION_KEY).unwrap().as_integer().unwrap(),
-                42.into()
-            );
-        } else {
-            assert_eq!(config_map.get(&SECURITY_VERSION_KEY), None);
-        }
+        assert_eq!(config_map.get(&SECURITY_VERSION_KEY).unwrap().as_integer().unwrap(), 42.into());
         assert_eq!(config_map.get(&RKP_VM_MARKER_KEY), None);
     }
 
     #[test]
-    fn config_descriptor_with_rkp_vm() {
+    fn rkp_vm_config_descriptor_has_rkp_vm_marker() {
         let vb_data =
             VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
         let inputs = PartialInputs::new(&vb_data).unwrap();
@@ -266,6 +259,16 @@
     }
 
     #[test]
+    fn security_vm_config_descriptor_has_rkp_vm_marker() {
+        let vb_data =
+            VerifiedBootData { capabilities: vec![Capability::TrustySecurityVm], ..BASE_VB_DATA };
+        let inputs = PartialInputs::new(&vb_data).unwrap();
+        let config_map = decode_config_descriptor(&inputs, Some(HASH));
+
+        assert!(config_map.get(&RKP_VM_MARKER_KEY).unwrap().is_null());
+    }
+
+    #[test]
     fn config_descriptor_with_instance_hash() {
         let vb_data =
             VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
@@ -426,14 +429,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 29212f9..fac9a9a 100644
--- a/guest/pvmfw/src/fdt.rs
+++ b/guest/pvmfw/src/fdt.rs
@@ -112,6 +112,24 @@
     Ok(None)
 }
 
+/// Read /avf/untrusted/instance-id, if present.
+pub fn read_instance_id(fdt: &Fdt) -> libfdt::Result<Option<&[u8]>> {
+    read_avf_untrusted_prop(fdt, c"instance-id")
+}
+
+/// Read /avf/untrusted/defer-rollback-protection, if present.
+pub fn read_defer_rollback_protection(fdt: &Fdt) -> libfdt::Result<Option<&[u8]>> {
+    read_avf_untrusted_prop(fdt, c"defer-rollback-protection")
+}
+
+fn read_avf_untrusted_prop<'a>(fdt: &'a Fdt, prop: &CStr) -> libfdt::Result<Option<&'a [u8]>> {
+    if let Some(node) = fdt.node(c"/avf/untrusted")? {
+        node.getprop(prop)
+    } else {
+        Ok(None)
+    }
+}
+
 fn patch_initrd_range(fdt: &mut Fdt, initrd_range: &Range<usize>) -> libfdt::Result<()> {
     let start = u32::try_from(initrd_range.start).unwrap();
     let end = u32::try_from(initrd_range.end).unwrap();
@@ -536,7 +554,7 @@
     }
 }
 
-impl<'a, const N: usize> Iterator for CellChunkIterator<'a, N> {
+impl<const N: usize> Iterator for CellChunkIterator<'_, N> {
     type Item = [u32; N];
     fn next(&mut self) -> Option<Self::Item> {
         let mut ret: Self::Item = [0; N];
diff --git a/guest/pvmfw/src/instance.rs b/guest/pvmfw/src/instance.rs
index bb07f74..bbc58ed 100644
--- a/guest/pvmfw/src/instance.rs
+++ b/guest/pvmfw/src/instance.rs
@@ -26,7 +26,10 @@
 use diced_open_dice::Hidden;
 use log::trace;
 use uuid::Uuid;
-use virtio_drivers::transport::{pci::bus::PciRoot, DeviceType, Transport};
+use virtio_drivers::transport::{
+    pci::bus::{ConfigurationAccess, PciRoot},
+    DeviceType, Transport,
+};
 use vmbase::util::ceiling_div;
 use vmbase::virtio::pci::{PciTransportIterator, VirtIOBlk};
 use vmbase::virtio::HalImpl;
@@ -99,7 +102,7 @@
 /// pvmfw in the instance.img as well as index corresponding to empty header which can be used to
 /// record instance data with `record_instance_entry`.
 pub(crate) fn get_recorded_entry(
-    pci_root: &mut PciRoot,
+    pci_root: &mut PciRoot<impl ConfigurationAccess>,
     secret: &[u8],
 ) -> Result<(Option<EntryBody>, Partition, usize)> {
     let mut instance_img = find_instance_img(pci_root)?;
@@ -175,8 +178,8 @@
     }
 }
 
-fn find_instance_img(pci_root: &mut PciRoot) -> Result<Partition> {
-    for transport in PciTransportIterator::<HalImpl>::new(pci_root)
+fn find_instance_img(pci_root: &mut PciRoot<impl ConfigurationAccess>) -> Result<Partition> {
+    for transport in PciTransportIterator::<HalImpl, _>::new(pci_root)
         .filter(|t| DeviceType::Block == t.device_type())
     {
         let device =
diff --git a/guest/pvmfw/src/main.rs b/guest/pvmfw/src/main.rs
index 0a3dca6..afa64e0 100644
--- a/guest/pvmfw/src/main.rs
+++ b/guest/pvmfw/src/main.rs
@@ -35,22 +35,20 @@
 use crate::bcc::Bcc;
 use crate::dice::PartialInputs;
 use crate::entry::RebootReason;
-use crate::fdt::{modify_for_next_stage, sanitize_device_tree};
+use crate::fdt::{modify_for_next_stage, read_instance_id, sanitize_device_tree};
 use crate::rollback::perform_rollback_protection;
 use alloc::borrow::Cow;
 use alloc::boxed::Box;
 use bssl_avf::Digester;
 use diced_open_dice::{bcc_handover_parse, DiceArtifacts, DiceContext, Hidden, VM_KEY_ALGORITHM};
-use libfdt::{Fdt, FdtNode};
+use libfdt::Fdt;
 use log::{debug, error, info, trace, warn};
 use pvmfw_avb::verify_payload;
 use pvmfw_avb::DebugLevel;
 use pvmfw_embedded_key::PUBLIC_KEY;
-use vmbase::fdt::pci::{PciError, PciInfo};
 use vmbase::heap;
-use vmbase::memory::{flush, init_shared_pool, SIZE_4KB};
+use vmbase::memory::{flush, SIZE_4KB};
 use vmbase::rand;
-use vmbase::virtio::pci;
 
 fn main<'a>(
     untrusted_fdt: &mut Fdt,
@@ -77,8 +75,6 @@
     })?;
     trace!("BCC: {bcc_handover:x?}");
 
-    let cdi_seal = bcc_handover.cdi_seal();
-
     let bcc = Bcc::new(bcc_handover.bcc()).map_err(|e| {
         error!("{e}");
         RebootReason::InvalidBcc
@@ -102,19 +98,8 @@
     }
 
     let guest_page_size = verified_boot_data.page_size.unwrap_or(SIZE_4KB);
-    let fdt_info = sanitize_device_tree(untrusted_fdt, vm_dtbo, vm_ref_dt, guest_page_size)?;
+    let _ = sanitize_device_tree(untrusted_fdt, vm_dtbo, vm_ref_dt, guest_page_size)?;
     let fdt = untrusted_fdt; // DT has now been sanitized.
-    let pci_info = PciInfo::from_fdt(fdt).map_err(handle_pci_error)?;
-    debug!("PCI: {:#x?}", pci_info);
-    // Set up PCI bus for VirtIO devices.
-    let mut pci_root = pci::initialize(pci_info).map_err(|e| {
-        error!("Failed to initialize PCI: {e}");
-        RebootReason::InternalError
-    })?;
-    init_shared_pool(fdt_info.swiotlb_info.fixed_range()).map_err(|e| {
-        error!("Failed to initialize shared pool: {e}");
-        RebootReason::InternalError
-    })?;
 
     let next_bcc_size = guest_page_size;
     let next_bcc = heap::aligned_boxed_slice(next_bcc_size, guest_page_size).ok_or_else(|| {
@@ -129,13 +114,12 @@
         RebootReason::InternalError
     })?;
 
-    let instance_hash = Some(salt_from_instance_id(fdt)?);
+    let instance_hash = salt_from_instance_id(fdt)?;
     let (new_instance, salt, defer_rollback_protection) = perform_rollback_protection(
         fdt,
         &verified_boot_data,
         &dice_inputs,
-        &mut pci_root,
-        cdi_seal,
+        bcc_handover.cdi_seal(),
         instance_hash,
     )?;
     trace!("Got salt for instance: {salt:x?}");
@@ -204,8 +188,14 @@
 
 // Get the "salt" which is one of the input for DICE derivation.
 // This provides differentiation of secrets for different VM instances with same payloads.
-fn salt_from_instance_id(fdt: &Fdt) -> Result<Hidden, RebootReason> {
-    let id = instance_id(fdt)?;
+fn salt_from_instance_id(fdt: &Fdt) -> Result<Option<Hidden>, RebootReason> {
+    let Some(id) = read_instance_id(fdt).map_err(|e| {
+        error!("Failed to get instance-id in DT: {e}");
+        RebootReason::InvalidFdt
+    })?
+    else {
+        return Ok(None);
+    };
     let salt = Digester::sha512()
         .digest(&[&b"InstanceId:"[..], id].concat())
         .map_err(|e| {
@@ -214,46 +204,5 @@
         })?
         .try_into()
         .map_err(|_| RebootReason::InternalError)?;
-    Ok(salt)
-}
-
-fn instance_id(fdt: &Fdt) -> Result<&[u8], RebootReason> {
-    let node = avf_untrusted_node(fdt)?;
-    let id = node.getprop(c"instance-id").map_err(|e| {
-        error!("Failed to get instance-id in DT: {e}");
-        RebootReason::InvalidFdt
-    })?;
-    id.ok_or_else(|| {
-        error!("Missing instance-id");
-        RebootReason::InvalidFdt
-    })
-}
-
-fn avf_untrusted_node(fdt: &Fdt) -> Result<FdtNode, RebootReason> {
-    let node = fdt.node(c"/avf/untrusted").map_err(|e| {
-        error!("Failed to get /avf/untrusted node: {e}");
-        RebootReason::InvalidFdt
-    })?;
-    node.ok_or_else(|| {
-        error!("/avf/untrusted node is missing in DT");
-        RebootReason::InvalidFdt
-    })
-}
-
-/// Logs the given PCI error and returns the appropriate `RebootReason`.
-fn handle_pci_error(e: PciError) -> RebootReason {
-    error!("{}", e);
-    match e {
-        PciError::FdtErrorPci(_)
-        | PciError::FdtNoPci
-        | PciError::FdtErrorReg(_)
-        | PciError::FdtMissingReg
-        | PciError::FdtRegEmpty
-        | PciError::FdtRegMissingSize
-        | PciError::CamWrongSize(_)
-        | PciError::FdtErrorRanges(_)
-        | PciError::FdtMissingRanges
-        | PciError::RangeAddressMismatch { .. }
-        | PciError::NoSuitableRange => RebootReason::InvalidFdt,
-    }
+    Ok(Some(salt))
 }
diff --git a/guest/pvmfw/src/rollback.rs b/guest/pvmfw/src/rollback.rs
index f7723d7..e51b6d5 100644
--- a/guest/pvmfw/src/rollback.rs
+++ b/guest/pvmfw/src/rollback.rs
@@ -16,16 +16,20 @@
 
 use crate::dice::PartialInputs;
 use crate::entry::RebootReason;
+use crate::fdt::read_defer_rollback_protection;
 use crate::instance::EntryBody;
 use crate::instance::Error as InstanceError;
 use crate::instance::{get_recorded_entry, record_instance_entry};
 use diced_open_dice::Hidden;
-use libfdt::{Fdt, FdtNode};
+use libfdt::Fdt;
 use log::{error, info};
 use pvmfw_avb::Capability;
 use pvmfw_avb::VerifiedBootData;
-use virtio_drivers::transport::pci::bus::PciRoot;
+use virtio_drivers::transport::pci::bus::{ConfigurationAccess, PciRoot};
+use vmbase::fdt::{pci::PciInfo, SwiotlbInfo};
+use vmbase::memory::init_shared_pool;
 use vmbase::rand;
+use vmbase::virtio::pci;
 
 /// Performs RBP based on the input payload, current DICE chain, and host-controlled platform.
 ///
@@ -37,23 +41,21 @@
     fdt: &Fdt,
     verified_boot_data: &VerifiedBootData,
     dice_inputs: &PartialInputs,
-    pci_root: &mut PciRoot,
     cdi_seal: &[u8],
     instance_hash: Option<Hidden>,
 ) -> Result<(bool, Hidden, bool), RebootReason> {
-    if should_defer_rollback_protection(fdt)?
-        && verified_boot_data.has_capability(Capability::SecretkeeperProtection)
+    if let Some(fixed) = get_fixed_rollback_protection(verified_boot_data) {
+        // Prevent attackers from impersonating well-known images.
+        perform_fixed_index_rollback_protection(verified_boot_data, fixed)?;
+        Ok((false, instance_hash.unwrap(), false))
+    } else if (should_defer_rollback_protection(fdt)?
+        && verified_boot_data.has_capability(Capability::SecretkeeperProtection))
+        || verified_boot_data.has_capability(Capability::TrustySecurityVm)
     {
         perform_deferred_rollback_protection(verified_boot_data)?;
         Ok((false, instance_hash.unwrap(), true))
-    } else if verified_boot_data.has_capability(Capability::RemoteAttest) {
-        perform_fixed_index_rollback_protection(verified_boot_data)?;
-        Ok((false, instance_hash.unwrap(), false))
-    } else if verified_boot_data.has_capability(Capability::TrustySecurityVm) {
-        skip_rollback_protection()?;
-        Ok((false, instance_hash.unwrap(), false))
     } else {
-        perform_legacy_rollback_protection(dice_inputs, pci_root, cdi_seal, instance_hash)
+        perform_legacy_rollback_protection(fdt, dice_inputs, cdi_seal, instance_hash)
     }
 }
 
@@ -71,11 +73,19 @@
     }
 }
 
+fn get_fixed_rollback_protection(verified_boot_data: &VerifiedBootData) -> Option<u64> {
+    if verified_boot_data.has_capability(Capability::RemoteAttest) {
+        Some(service_vm_version::VERSION)
+    } else {
+        None
+    }
+}
+
 fn perform_fixed_index_rollback_protection(
     verified_boot_data: &VerifiedBootData,
+    fixed_index: u64,
 ) -> 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}");
@@ -85,24 +95,20 @@
     }
 }
 
-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(
+    fdt: &Fdt,
     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 mut pci_root = initialize_instance_img_device(fdt)?;
+    let (recorded_entry, mut instance_img, header_index) =
+        get_recorded_entry(&mut 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);
@@ -155,24 +161,36 @@
 }
 
 fn should_defer_rollback_protection(fdt: &Fdt) -> Result<bool, RebootReason> {
-    let node = avf_untrusted_node(fdt)?;
-    let defer_rbp = node
-        .getprop(c"defer-rollback-protection")
-        .map_err(|e| {
-            error!("Failed to get defer-rollback-protection property in DT: {e}");
-            RebootReason::InvalidFdt
-        })?
-        .is_some();
-    Ok(defer_rbp)
-}
-
-fn avf_untrusted_node(fdt: &Fdt) -> Result<FdtNode, RebootReason> {
-    let node = fdt.node(c"/avf/untrusted").map_err(|e| {
-        error!("Failed to get /avf/untrusted node: {e}");
+    let defer_rbp = read_defer_rollback_protection(fdt).map_err(|e| {
+        error!("Failed to get defer-rollback-protection property in DT: {e}");
         RebootReason::InvalidFdt
     })?;
-    node.ok_or_else(|| {
-        error!("/avf/untrusted node is missing in DT");
+    Ok(defer_rbp.is_some())
+}
+
+/// Set up PCI bus and VirtIO-blk device containing the instance.img partition.
+fn initialize_instance_img_device(
+    fdt: &Fdt,
+) -> Result<PciRoot<impl ConfigurationAccess>, RebootReason> {
+    let pci_info = PciInfo::from_fdt(fdt).map_err(|e| {
+        error!("Failed to detect PCI from DT: {e}");
         RebootReason::InvalidFdt
-    })
+    })?;
+    let swiotlb_range = SwiotlbInfo::new_from_fdt(fdt)
+        .map_err(|e| {
+            error!("Failed to detect swiotlb from DT: {e}");
+            RebootReason::InvalidFdt
+        })?
+        .and_then(|info| info.fixed_range());
+
+    let pci_root = pci::initialize(pci_info).map_err(|e| {
+        error!("Failed to initialize PCI: {e}");
+        RebootReason::InternalError
+    })?;
+    init_shared_pool(swiotlb_range).map_err(|e| {
+        error!("Failed to initialize shared pool: {e}");
+        RebootReason::InternalError
+    })?;
+
+    Ok(pci_root)
 }
diff --git a/guest/rialto/src/communication.rs b/guest/rialto/src/communication.rs
index 1b94912..6f5a59e 100644
--- a/guest/rialto/src/communication.rs
+++ b/guest/rialto/src/communication.rs
@@ -67,7 +67,7 @@
                 match event {
                     VsockEventType::Connected => return Ok(()),
                     VsockEventType::Disconnected { .. } => {
-                        return Err(SocketError::ConnectionFailed.into())
+                        return Err(SocketError::NotConnected.into())
                     }
                     // We shouldn't receive the following event before the connection is
                     // established.
@@ -141,7 +141,7 @@
     fn poll(&mut self) -> virtio_drivers::Result<Option<VsockEventType>> {
         if let Some(event) = self.poll_event_from_peer()? {
             match event {
-                VsockEventType::Disconnected { .. } => Err(SocketError::ConnectionFailed.into()),
+                VsockEventType::Disconnected { .. } => Err(SocketError::NotConnected.into()),
                 VsockEventType::Connected | VsockEventType::ConnectionRequest => {
                     Err(SocketError::InvalidOperation.into())
                 }
diff --git a/guest/rialto/src/main.rs b/guest/rialto/src/main.rs
index 04d18be..c3d3604 100644
--- a/guest/rialto/src/main.rs
+++ b/guest/rialto/src/main.rs
@@ -38,7 +38,10 @@
 use service_vm_requests::{process_request, RequestContext};
 use virtio_drivers::{
     device::socket::{VsockAddr, VMADDR_CID_HOST},
-    transport::{pci::bus::PciRoot, DeviceType, Transport},
+    transport::{
+        pci::bus::{ConfigurationAccess, PciRoot},
+        DeviceType, Transport,
+    },
     Hal,
 };
 use vmbase::{
@@ -123,7 +126,6 @@
     let pci_info = PciInfo::from_fdt(fdt)?;
     debug!("PCI: {pci_info:#x?}");
     let mut pci_root = pci::initialize(pci_info).map_err(Error::PciInitializationFailed)?;
-    debug!("PCI root: {pci_root:#x?}");
     let socket_device = find_socket_device::<HalImpl>(&mut pci_root)?;
     debug!("Found socket device: guest cid = {:?}", socket_device.guest_cid());
     let vendor_hashtree_root_digest = read_vendor_hashtree_root_digest(fdt)?;
@@ -143,8 +145,10 @@
     Ok(())
 }
 
-fn find_socket_device<T: Hal>(pci_root: &mut PciRoot) -> Result<VirtIOSocket<T>> {
-    PciTransportIterator::<T>::new(pci_root)
+fn find_socket_device<T: Hal>(
+    pci_root: &mut PciRoot<impl ConfigurationAccess>,
+) -> Result<VirtIOSocket<T>> {
+    PciTransportIterator::<T, _>::new(pci_root)
         .find(|t| DeviceType::Socket == t.device_type())
         .map(VirtIOSocket::<T>::new)
         .transpose()
diff --git a/guest/rialto/tests/test.rs b/guest/rialto/tests/test.rs
index c94a0e3..d68c568 100644
--- a/guest/rialto/tests/test.rs
+++ b/guest/rialto/tests/test.rs
@@ -54,13 +54,9 @@
 const INSTANCE_IMG_PATH: &str = "/data/local/tmp/rialto_test/arm64/instance.img";
 const TEST_CERT_CHAIN_PATH: &str = "testdata/rkp_cert_chain.der";
 
-#[cfg(dice_changes)]
 #[test]
 fn process_requests_in_protected_vm() -> Result<()> {
     if hypervisor_props::is_protected_vm_supported()? {
-        // The test is skipped if the feature flag |dice_changes| is not enabled, because when
-        // the flag is off, the DICE chain is truncated in the pvmfw, and the service VM cannot
-        // verify the chain due to the missing entries in the chain.
         check_processing_requests(VmType::ProtectedVm, None)
     } else {
         warn!("pVMs are not supported on device, skipping test");
diff --git a/guest/trusty/security_vm/launcher/Android.bp b/guest/trusty/security_vm/launcher/Android.bp
index fea8873..ff628fd 100644
--- a/guest/trusty/security_vm/launcher/Android.bp
+++ b/guest/trusty/security_vm/launcher/Android.bp
@@ -18,56 +18,3 @@
         false: false,
     }),
 }
-
-prebuilt_etc {
-    name: "lk_trusty.elf",
-    system_ext_specific: true,
-    relative_install_path: "vm/trusty_vm",
-    filename: "lk_trusty.elf",
-    arch: {
-        x86_64: {
-            src: ":trusty_security_vm_signed",
-        },
-        arm64: {
-            src: ":trusty_security_vm_signed",
-        },
-    },
-    src: ":empty_file",
-}
-
-filegroup {
-    name: "trusty_vm_sign_key",
-    srcs: [":avb_testkey_rsa4096"],
-}
-
-// python -c "import hashlib; print(hashlib.sha256(b'trusty_security_vm_salt').hexdigest())"
-trusty_security_vm_salt = "75a71e967c1a1e0f805cca20465e7acf83e6a04e567a67c426d8b5a94f8d61c5"
-
-TRUSTY_SECURITY_VM_VERSION = 1
-
-avb_add_hash_footer {
-    name: "trusty_security_vm_signed",
-    filename: "trusty_security_vm_signed",
-    partition_name: "boot",
-    private_key: ":trusty_vm_sign_key",
-    salt: trusty_security_vm_salt,
-    rollback_index: TRUSTY_SECURITY_VM_VERSION,
-    props: [
-        {
-            name: "com.android.virt.cap",
-            value: "trusty_security_vm",
-        },
-    ],
-    src: ":empty_file",
-    enabled: false,
-    arch: {
-        x86_64: {
-            src: ":trusty-lk.elf",
-            enabled: true,
-        },
-        arm64: {
-            src: ":trusty-test-lk.elf",
-            enabled: true,
-        },
-    },
-}
diff --git a/guest/trusty/security_vm/vm/Android.bp b/guest/trusty/security_vm/vm/Android.bp
new file mode 100644
index 0000000..ee64095
--- /dev/null
+++ b/guest/trusty/security_vm/vm/Android.bp
@@ -0,0 +1,136 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+prebuilt_etc {
+    name: "lk_trusty.elf",
+    system_ext_specific: true,
+    relative_install_path: "vm/trusty_vm",
+    filename: "lk_trusty.elf",
+    arch: {
+        x86_64: {
+            src: ":trusty_security_vm_signed",
+        },
+        arm64: {
+            src: ":security_vm_elf",
+        },
+    },
+    src: ":empty_file",
+}
+
+cc_binary {
+    name: "security_vm_elf",
+    srcs: [
+        ":security_vm_signed_obj",
+    ],
+    linker_scripts: [
+        "security_vm_sections.ld",
+    ],
+    ldflags: [
+        // Prevent the `trusty_security_vm_signed` segment from being garbage collected.
+        "-Wl,--no-gc-sections",
+        // Prevent the build ID segments from being added, as it would corrupt the integrity
+        // of the original signed image.
+        "-Wl,--build-id=none",
+        // Use a standard page size of 4096, smaller than the default 16384, to avoid padding
+        // with extra bytes.
+        "-Wl,-z,max-page-size=4096",
+    ],
+    nocrt: true,
+    no_libcrt: true,
+    static_executable: true,
+    system_shared_libs: [],
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    strip: {
+        none: true,
+    },
+}
+
+cc_genrule {
+    name: "security_vm.S",
+    arch: {
+        arm64: {
+            srcs: [":trusty_security_vm_signed"],
+        },
+    },
+    out: ["security_vm.S"],
+    cmd: "(" +
+        "    echo '.section .security_vm_signed.bin';" +
+        "    echo '.globl security_vm_signed';" +
+        "    echo 'security_vm_signed:';" +
+        "    echo '.incbin \"'$(in)'\"';" +
+        ") > $(out)",
+    visibility: ["//visibility:private"],
+}
+
+cc_object {
+    name: "security_vm_signed_obj",
+    srcs: [
+        ":security_vm.S",
+    ],
+    static_libs: ["trusty_security_vm_signed"],
+    crt: false,
+    system_shared_libs: [],
+    enabled: false,
+    target: {
+        android_arm64: {
+            enabled: true,
+        },
+    },
+    visibility: ["//visibility:private"],
+}
+
+filegroup {
+    name: "trusty_vm_sign_key",
+    srcs: [":avb_testkey_rsa4096"],
+}
+
+// python -c "import hashlib; print(hashlib.sha256(b'trusty_security_vm_salt').hexdigest())"
+trusty_security_vm_salt = "75a71e967c1a1e0f805cca20465e7acf83e6a04e567a67c426d8b5a94f8d61c5"
+
+TRUSTY_SECURITY_VM_VERSION = 1
+
+avb_add_hash_footer {
+    name: "trusty_security_vm_signed",
+    filename: "trusty_security_vm_signed",
+    partition_name: "boot",
+    private_key: ":trusty_vm_sign_key",
+    salt: trusty_security_vm_salt,
+    rollback_index: TRUSTY_SECURITY_VM_VERSION,
+    props: [
+        {
+            name: "com.android.virt.cap",
+            value: "trusty_security_vm",
+        },
+    ],
+    src: ":empty_file",
+    enabled: false,
+    arch: {
+        x86_64: {
+            src: ":trusty-lk.elf",
+            enabled: true,
+        },
+        arm64: {
+            src: ":trusty_security_vm_unsigned",
+            enabled: true,
+        },
+    },
+}
+
+// TODO(b/379646659): Take the binary generated by trusty instead of extracting
+// it from ELF here.
+raw_binary {
+    name: "trusty_security_vm_unsigned",
+    src: ":trusty-test-lk.elf",
+    enabled: false,
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+}
diff --git a/guest/trusty/security_vm/vm/security_vm_sections.ld b/guest/trusty/security_vm/vm/security_vm_sections.ld
new file mode 100644
index 0000000..63e5f5d
--- /dev/null
+++ b/guest/trusty/security_vm/vm/security_vm_sections.ld
@@ -0,0 +1,25 @@
+/*
+ * 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
+ *
+ *     https://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.
+ */
+
+ENTRY(security_vm_signed)
+
+SECTIONS
+{
+    . = 0x0;
+    .text : {
+        *(.security_vm_signed.bin)
+    }
+}
diff --git a/guest/vmbase_example/Android.bp b/guest/vmbase_example/Android.bp
index ab21191..30d72bd 100644
--- a/guest/vmbase_example/Android.bp
+++ b/guest/vmbase_example/Android.bp
@@ -12,6 +12,7 @@
         "libdiced_open_dice_nostd",
         "liblibfdt_nostd",
         "liblog_rust_nostd",
+        "libspin_nostd",
         "libvirtio_drivers",
         "libvmbase",
     ],
@@ -39,6 +40,9 @@
         "-E",
         "-P",
         "-xassembler-with-cpp", // allow C preprocessor directives
+        // Soong passes an implicit -c before -E. Suppress the warning about -c
+        // being unused.
+        "-Wno-unused-command-line-argument",
     ],
     srcs: [":vmbase_image.ld.S.mm"],
     visibility: ["//visibility:private"],
diff --git a/guest/vmbase_example/src/main.rs b/guest/vmbase_example/src/main.rs
index f5b41bd..b7d2f95 100644
--- a/guest/vmbase_example/src/main.rs
+++ b/guest/vmbase_example/src/main.rs
@@ -26,9 +26,9 @@
 use crate::layout::print_addresses;
 use crate::pci::check_pci;
 use alloc::{vec, vec::Vec};
-use core::ptr::addr_of_mut;
 use libfdt::Fdt;
 use log::{debug, error, info, trace, warn, LevelFilter};
+use spin::mutex::SpinMutex;
 use vmbase::{
     bionic, configure_heap,
     fdt::pci::PciInfo,
@@ -39,8 +39,8 @@
 };
 
 static INITIALISED_DATA: [u32; 4] = [1, 2, 3, 4];
-static mut ZEROED_DATA: [u32; 10] = [0; 10];
-static mut MUTABLE_DATA: [u32; 4] = [1, 2, 3, 4];
+static ZEROED_DATA: SpinMutex<[u32; 10]> = SpinMutex::new([0; 10]);
+static MUTABLE_DATA: SpinMutex<[u32; 4]> = SpinMutex::new([1, 2, 3, 4]);
 
 generate_image_header!();
 main!(main);
@@ -103,22 +103,16 @@
 
 fn check_data() {
     info!("INITIALISED_DATA: {:?}", INITIALISED_DATA.as_ptr());
-    // SAFETY: We only print the addresses of the static mutable variable, not actually access it.
-    info!("ZEROED_DATA: {:?}", unsafe { ZEROED_DATA.as_ptr() });
-    // SAFETY: We only print the addresses of the static mutable variable, not actually access it.
-    info!("MUTABLE_DATA: {:?}", unsafe { MUTABLE_DATA.as_ptr() });
 
     assert_eq!(INITIALISED_DATA[0], 1);
     assert_eq!(INITIALISED_DATA[1], 2);
     assert_eq!(INITIALISED_DATA[2], 3);
     assert_eq!(INITIALISED_DATA[3], 4);
 
-    // SAFETY: Nowhere else in the program accesses this static mutable variable, so there is no
-    // chance of concurrent access.
-    let zeroed_data = unsafe { &mut *addr_of_mut!(ZEROED_DATA) };
-    // SAFETY: Nowhere else in the program accesses this static mutable variable, so there is no
-    // chance of concurrent access.
-    let mutable_data = unsafe { &mut *addr_of_mut!(MUTABLE_DATA) };
+    let zeroed_data = &mut *ZEROED_DATA.lock();
+    let mutable_data = &mut *MUTABLE_DATA.lock();
+    info!("ZEROED_DATA: {:?}", zeroed_data.as_ptr());
+    info!("MUTABLE_DATA: {:?}", mutable_data.as_ptr());
 
     for element in zeroed_data.iter() {
         assert_eq!(*element, 0);
diff --git a/guest/vmbase_example/src/pci.rs b/guest/vmbase_example/src/pci.rs
index 32ab9f6..1e87682 100644
--- a/guest/vmbase_example/src/pci.rs
+++ b/guest/vmbase_example/src/pci.rs
@@ -20,7 +20,10 @@
 use virtio_drivers::{
     device::console::VirtIOConsole,
     transport::{
-        pci::{bus::PciRoot, PciTransport},
+        pci::{
+            bus::{ConfigurationAccess, PciRoot},
+            PciTransport,
+        },
         DeviceType, Transport,
     },
     BufferDirection, Error, Hal, PhysAddr, PAGE_SIZE,
@@ -33,11 +36,11 @@
 /// The size in sectors of the test block device we expect.
 const EXPECTED_SECTOR_COUNT: usize = 4;
 
-pub fn check_pci(pci_root: &mut PciRoot) {
+pub fn check_pci(pci_root: &mut PciRoot<impl ConfigurationAccess>) {
     let mut checked_virtio_device_count = 0;
     let mut block_device_count = 0;
     let mut socket_device_count = 0;
-    for mut transport in PciTransportIterator::<HalImpl>::new(pci_root) {
+    for mut transport in PciTransportIterator::<HalImpl, _>::new(pci_root) {
         info!(
             "Detected virtio PCI device with device type {:?}, features {:#018x}",
             transport.device_type(),
@@ -104,7 +107,10 @@
 fn check_virtio_console_device(transport: PciTransport) {
     let mut console = VirtIOConsole::<HalImpl, PciTransport>::new(transport)
         .expect("Failed to create VirtIO console driver");
-    info!("Found console device: {:?}", console.info());
+    info!(
+        "Found console device with size {:?}",
+        console.size().expect("Failed to get size of VirtIO console device")
+    );
     for &c in b"Hello VirtIO console\n" {
         console.send(c).expect("Failed to send character to VirtIO console device");
     }
diff --git a/libs/apkverify/src/hashtree.rs b/libs/apkverify/src/hashtree.rs
index 00d8292..54e879b 100644
--- a/libs/apkverify/src/hashtree.rs
+++ b/libs/apkverify/src/hashtree.rs
@@ -84,7 +84,7 @@
             let mut level0 = Cursor::new(&mut hash_tree[cur.start..cur.end]);
 
             let mut a_block = vec![0; block_size];
-            let mut num_blocks = (input_size + block_size - 1) / block_size;
+            let mut num_blocks = input_size.div_ceil(block_size);
             while num_blocks > 0 {
                 input.read_exact(&mut a_block)?;
                 let h = hash_one_block(&a_block, salt, block_size, algorithm)?;
@@ -138,7 +138,7 @@
         if input_size <= block_size {
             break;
         }
-        let num_blocks = (input_size + block_size - 1) / block_size;
+        let num_blocks = input_size.div_ceil(block_size);
         let hashes_size = round_to_multiple(num_blocks * digest_size, block_size);
         level_sizes.push(hashes_size);
     }
diff --git a/libs/bssl/src/cbb.rs b/libs/bssl/src/cbb.rs
index a48c714..282a77d 100644
--- a/libs/bssl/src/cbb.rs
+++ b/libs/bssl/src/cbb.rs
@@ -40,13 +40,13 @@
     }
 }
 
-impl<'a> AsRef<CBB> for CbbFixed<'a> {
+impl AsRef<CBB> for CbbFixed<'_> {
     fn as_ref(&self) -> &CBB {
         &self.cbb
     }
 }
 
-impl<'a> AsMut<CBB> for CbbFixed<'a> {
+impl AsMut<CBB> for CbbFixed<'_> {
     fn as_mut(&mut self) -> &mut CBB {
         &mut self.cbb
     }
diff --git a/libs/bssl/src/cbs.rs b/libs/bssl/src/cbs.rs
index 12671cf..166484c 100644
--- a/libs/bssl/src/cbs.rs
+++ b/libs/bssl/src/cbs.rs
@@ -42,13 +42,13 @@
     }
 }
 
-impl<'a> AsRef<CBS> for Cbs<'a> {
+impl AsRef<CBS> for Cbs<'_> {
     fn as_ref(&self) -> &CBS {
         &self.cbs
     }
 }
 
-impl<'a> AsMut<CBS> for Cbs<'a> {
+impl AsMut<CBS> for Cbs<'_> {
     fn as_mut(&mut self) -> &mut CBS {
         &mut self.cbs
     }
diff --git a/libs/bssl/src/ec_key.rs b/libs/bssl/src/ec_key.rs
index 3e2e382..da9eb77 100644
--- a/libs/bssl/src/ec_key.rs
+++ b/libs/bssl/src/ec_key.rs
@@ -471,7 +471,7 @@
 /// Wrapper of an `EC_GROUP` reference.
 struct EcGroup<'a>(&'a EC_GROUP);
 
-impl<'a> EcGroup<'a> {
+impl EcGroup<'_> {
     /// Returns the NID that identifies the EC group of the key.
     fn curve_nid(&self) -> i32 {
         // SAFETY: It is safe since the inner pointer is valid and points to an initialized
@@ -518,7 +518,7 @@
     }
 }
 
-impl<'a> AsRef<EC_GROUP> for EcGroup<'a> {
+impl AsRef<EC_GROUP> for EcGroup<'_> {
     fn as_ref(&self) -> &EC_GROUP {
         self.0
     }
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/Android.bp b/libs/devicemapper/Android.bp
index 5332469..6b7f680 100644
--- a/libs/devicemapper/Android.bp
+++ b/libs/devicemapper/Android.bp
@@ -8,7 +8,6 @@
     defaults: ["avf_build_flags_rust"],
     srcs: ["src/lib.rs"],
     edition: "2021",
-    prefer_rlib: true,
     rustlibs: [
         "libanyhow",
         "libbitflags",
@@ -18,16 +17,12 @@
         "libuuid",
         "libzerocopy",
     ],
-    multilib: {
-        lib32: {
-            enabled: false,
-        },
-    },
 }
 
 rust_library {
     name: "libdm_rust",
     defaults: ["libdm_rust.defaults"],
+    host_supported: true,
 }
 
 rust_test {
diff --git a/libs/devicemapper/src/crypt.rs b/libs/devicemapper/src/crypt.rs
index 75417ed..1326caf 100644
--- a/libs/devicemapper/src/crypt.rs
+++ b/libs/devicemapper/src/crypt.rs
@@ -87,7 +87,7 @@
     opt_params: Vec<&'a str>,
 }
 
-impl<'a> Default for DmCryptTargetBuilder<'a> {
+impl Default for DmCryptTargetBuilder<'_> {
     fn default() -> Self {
         DmCryptTargetBuilder {
             cipher: CipherType::AES256HCTR2,
diff --git a/libs/devicemapper/src/lib.rs b/libs/devicemapper/src/lib.rs
index a8f3049..a8c2833 100644
--- a/libs/devicemapper/src/lib.rs
+++ b/libs/devicemapper/src/lib.rs
@@ -235,6 +235,7 @@
 #[cfg(test)]
 mod tests {
     use super::*;
+    use crate::loopdevice::LoopConfigOptions;
     use crypt::{CipherType, DmCryptTargetBuilder};
     use rdroidtest::{ignore_if, rdroidtest};
     use rustutils::system_properties;
@@ -328,10 +329,10 @@
             backing_file,
             0,
             sz,
-            /* direct_io */ true,
-            /* writable */ true,
+            &LoopConfigOptions { direct_io: true, writable: true, ..Default::default() },
         )
-        .unwrap();
+        .unwrap()
+        .path;
         let device_diff = device.to_owned() + "_diff";
 
         scopeguard::defer! {
@@ -372,10 +373,10 @@
             backing_file,
             0,
             sz,
-            /* direct_io */ true,
-            /* writable */ true,
+            &LoopConfigOptions { direct_io: true, writable: true, ..Default::default() },
         )
-        .unwrap();
+        .unwrap()
+        .path;
         let device_diff = device.to_owned() + "_diff";
         scopeguard::defer! {
             loopdevice::detach(&data_device).unwrap();
diff --git a/libs/devicemapper/src/loopdevice.rs b/libs/devicemapper/src/loopdevice.rs
index 130c1c4..b830eda 100644
--- a/libs/devicemapper/src/loopdevice.rs
+++ b/libs/devicemapper/src/loopdevice.rs
@@ -59,14 +59,31 @@
     Ok(unsafe { _loop_clr_fd(device_file.as_raw_fd()) }?)
 }
 
+/// LOOP_CONFIGURE ioctl operation flags.
+#[derive(Default)]
+pub struct LoopConfigOptions {
+    /// Whether to use direct I/O
+    pub direct_io: bool,
+    /// Whether the device is writable
+    pub writable: bool,
+    /// Whether to autodestruct the device on last close
+    pub autoclear: bool,
+}
+
+pub struct LoopDevice {
+    /// The loop device file
+    pub file: File,
+    /// Path to the loop device
+    pub path: PathBuf,
+}
+
 /// Creates a loop device and attach the given file at `path` as the backing store.
 pub fn attach<P: AsRef<Path>>(
     path: P,
     offset: u64,
     size_limit: u64,
-    direct_io: bool,
-    writable: bool,
-) -> Result<PathBuf> {
+    options: &LoopConfigOptions,
+) -> Result<LoopDevice> {
     // Attaching a file to a loop device can make a race condition; a loop device number obtained
     // from LOOP_CTL_GET_FREE might have been used by another thread or process. In that case the
     // subsequent LOOP_CONFIGURE ioctl returns with EBUSY. Try until it succeeds.
@@ -80,8 +97,8 @@
 
     let begin = Instant::now();
     loop {
-        match try_attach(&path, offset, size_limit, direct_io, writable) {
-            Ok(loop_dev) => return Ok(loop_dev),
+        match try_attach(&path, offset, size_limit, options) {
+            Ok(loop_device) => return Ok(loop_device),
             Err(e) => {
                 if begin.elapsed() > TIMEOUT {
                     return Err(e);
@@ -102,9 +119,8 @@
     path: P,
     offset: u64,
     size_limit: u64,
-    direct_io: bool,
-    writable: bool,
-) -> Result<PathBuf> {
+    options: &LoopConfigOptions,
+) -> Result<LoopDevice> {
     // Get a free loop device
     wait_for_path(LOOP_CONTROL)?;
     let ctrl_file = OpenOptions::new()
@@ -117,8 +133,8 @@
     // Construct the loop_info64 struct
     let backing_file = OpenOptions::new()
         .read(true)
-        .write(writable)
-        .custom_flags(if direct_io { O_DIRECT } else { 0 })
+        .write(options.writable)
+        .custom_flags(if options.direct_io { O_DIRECT } else { 0 })
         .open(&path)
         .context(format!("failed to open {:?}", path.as_ref()))?;
     let mut config = loop_config::new_zeroed();
@@ -127,14 +143,18 @@
     config.info.lo_offset = offset;
     config.info.lo_sizelimit = size_limit;
 
-    if !writable {
+    if !options.writable {
         config.info.lo_flags = Flag::LO_FLAGS_READ_ONLY;
     }
 
-    if direct_io {
+    if options.direct_io {
         config.info.lo_flags.insert(Flag::LO_FLAGS_DIRECT_IO);
     }
 
+    if options.autoclear {
+        config.info.lo_flags.insert(Flag::LO_FLAGS_AUTOCLEAR);
+    }
+
     // Configure the loop device to attach the backing file
     let device_path = format!("{}{}", LOOP_DEV_PREFIX, num);
     wait_for_path(&device_path)?;
@@ -146,7 +166,7 @@
     loop_configure(&device_file, &config)
         .context(format!("Failed to configure {:?}", &device_path))?;
 
-    Ok(PathBuf::from(device_path))
+    Ok(LoopDevice { file: device_file, path: PathBuf::from(device_path) })
 }
 
 /// Detaches backing file from the loop device `path`.
@@ -185,7 +205,10 @@
         let a_file = a_dir.path().join("test");
         let a_size = 4096u64;
         create_empty_file(&a_file, a_size);
-        let dev = attach(a_file, 0, a_size, /* direct_io */ true, /* writable */ false).unwrap();
+        let dev =
+            attach(a_file, 0, a_size, &LoopConfigOptions { direct_io: true, ..Default::default() })
+                .unwrap()
+                .path;
         scopeguard::defer! {
             detach(&dev).unwrap();
         }
@@ -198,7 +221,7 @@
         let a_file = a_dir.path().join("test");
         let a_size = 4096u64;
         create_empty_file(&a_file, a_size);
-        let dev = attach(a_file, 0, a_size, /* direct_io */ false, /* writable */ false).unwrap();
+        let dev = attach(a_file, 0, a_size, &LoopConfigOptions::default()).unwrap().path;
         scopeguard::defer! {
             detach(&dev).unwrap();
         }
@@ -211,11 +234,34 @@
         let a_file = a_dir.path().join("test");
         let a_size = 4096u64;
         create_empty_file(&a_file, a_size);
-        let dev = attach(a_file, 0, a_size, /* direct_io */ true, /* writable */ true).unwrap();
+        let dev = attach(
+            a_file,
+            0,
+            a_size,
+            &LoopConfigOptions { direct_io: true, writable: true, ..Default::default() },
+        )
+        .unwrap()
+        .path;
         scopeguard::defer! {
             detach(&dev).unwrap();
         }
         assert!(is_direct_io(&dev));
         assert!(is_direct_io_writable(&dev));
     }
+
+    #[rdroidtest]
+    fn attach_loop_device_autoclear() {
+        let a_dir = tempfile::TempDir::new().unwrap();
+        let a_file = a_dir.path().join("test");
+        let a_size = 4096u64;
+        create_empty_file(&a_file, a_size);
+        let dev =
+            attach(a_file, 0, a_size, &LoopConfigOptions { autoclear: true, ..Default::default() })
+                .unwrap();
+        drop(dev.file);
+
+        let dev_size_path =
+            Path::new("/sys/block").join(dev.path.file_name().unwrap()).join("size");
+        assert_eq!("0", fs::read_to_string(dev_size_path).unwrap().trim());
+    }
 }
diff --git a/libs/devicemapper/src/verity.rs b/libs/devicemapper/src/verity.rs
index 09087da..100320b 100644
--- a/libs/devicemapper/src/verity.rs
+++ b/libs/devicemapper/src/verity.rs
@@ -66,7 +66,7 @@
     }
 }
 
-impl<'a> Default for DmVerityTargetBuilder<'a> {
+impl Default for DmVerityTargetBuilder<'_> {
     fn default() -> Self {
         DmVerityTargetBuilder {
             version: DmVerityVersion::V1,
diff --git a/libs/dice/driver/src/lib.rs b/libs/dice/driver/src/lib.rs
index b5c1f12..245bf11 100644
--- a/libs/dice/driver/src/lib.rs
+++ b/libs/dice/driver/src/lib.rs
@@ -185,7 +185,6 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use core::ffi::CStr;
     use diced_open_dice::{
         hash, retry_bcc_format_config_descriptor, DiceConfigValues, HIDDEN_SIZE,
     };
@@ -233,10 +232,7 @@
 
         let dice = DiceDriver::from_file(&file_path)?;
 
-        let values = DiceConfigValues {
-            component_name: Some(CStr::from_bytes_with_nul(b"test\0")?),
-            ..Default::default()
-        };
+        let values = DiceConfigValues { component_name: Some(c"test"), ..Default::default() };
         let desc = retry_bcc_format_config_descriptor(&values)?;
         let code_hash = hash(&String::from("test code hash").into_bytes())?;
         let authority_hash = hash(&String::from("test authority hash").into_bytes())?;
diff --git a/libs/dice/open_dice/Android.bp b/libs/dice/open_dice/Android.bp
index f799fb1..75f70c3 100644
--- a/libs/dice/open_dice/Android.bp
+++ b/libs/dice/open_dice/Android.bp
@@ -75,6 +75,7 @@
     defaults: ["libdiced_open_dice_test_defaults"],
     rustlibs: [
         "libdiced_open_dice",
+        "libcoset",
     ],
 }
 
@@ -83,6 +84,7 @@
     defaults: ["libdiced_open_dice_test_defaults"],
     rustlibs: [
         "libdiced_open_dice_nostd",
+        "libcoset_nostd",
     ],
 }
 
@@ -128,7 +130,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: [
@@ -146,6 +148,7 @@
         "--allowlist-function=DiceKdf",
         "--allowlist-function=DiceKeypairFromSeed",
         "--allowlist-function=DiceSign",
+        "--allowlist-function=DiceCoseSignAndEncodeSign1",
         "--allowlist-function=DiceVerify",
         "--allowlist-function=DiceGenerateCertificate",
 
@@ -184,7 +187,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 +267,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 94%
rename from libs/dice/open_dice/bindgen/dice.h
rename to libs/dice/open_dice/bindgen/dice/dice.h
index 47fe911..e6d5131 100644
--- a/libs/dice/open_dice/bindgen/dice.h
+++ b/libs/dice/open_dice/bindgen/dice/dice.h
@@ -16,3 +16,4 @@
 
 #include <dice/dice.h>
 #include <dice/ops.h>
+#include <dice/ops/trait/cose.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..e9c4b81
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/dice/rules.mk
@@ -0,0 +1,57 @@
+# 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 \
+	DiceCoseSignAndEncodeSign1 \
+	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..1d9039d 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;
 
@@ -172,7 +172,7 @@
     bcc: Option<&'a [u8]>,
 }
 
-impl<'a> DiceArtifacts for BccHandover<'a> {
+impl DiceArtifacts for BccHandover<'_> {
     fn cdi_attest(&self) -> &[u8; CDI_SIZE] {
         self.cdi_attest
     }
diff --git a/libs/dice/open_dice/src/error.rs b/libs/dice/open_dice/src/error.rs
index 9089432..c9eb5cc 100644
--- a/libs/dice/open_dice/src/error.rs
+++ b/libs/dice/open_dice/src/error.rs
@@ -31,6 +31,8 @@
     PlatformError,
     /// Unsupported key algorithm.
     UnsupportedKeyAlgorithm(coset::iana::Algorithm),
+    /// A failed fallible allocation. Used in no_std environments.
+    MemoryAllocationError,
 }
 
 /// This makes `DiceError` accepted by anyhow.
@@ -48,6 +50,7 @@
             Self::UnsupportedKeyAlgorithm(algorithm) => {
                 write!(f, "Unsupported key algorithm: {algorithm:?}")
             }
+            Self::MemoryAllocationError => write!(f, "Memory allocation failed"),
         }
     }
 }
diff --git a/libs/dice/open_dice/src/lib.rs b/libs/dice/open_dice/src/lib.rs
index 4d05255..33fb65c 100644
--- a/libs/dice/open_dice/src/lib.rs
+++ b/libs/dice/open_dice/src/lib.rs
@@ -43,9 +43,11 @@
 };
 pub use error::{DiceError, Result};
 pub use ops::{
-    derive_cdi_leaf_priv, generate_certificate, hash, kdf, keypair_from_seed, sign, verify,
+    derive_cdi_leaf_priv, generate_certificate, hash, kdf, keypair_from_seed, sign,
+    sign_cose_sign1, sign_cose_sign1_with_cdi_leaf_priv, verify,
 };
 pub use retry::{
     retry_bcc_format_config_descriptor, retry_bcc_main_flow, retry_dice_main_flow,
-    retry_generate_certificate, OwnedDiceArtifacts,
+    retry_generate_certificate, retry_sign_cose_sign1, retry_sign_cose_sign1_with_cdi_leaf_priv,
+    OwnedDiceArtifacts,
 };
diff --git a/libs/dice/open_dice/src/ops.rs b/libs/dice/open_dice/src/ops.rs
index 41951bf..2014118 100644
--- a/libs/dice/open_dice/src/ops.rs
+++ b/libs/dice/open_dice/src/ops.rs
@@ -23,8 +23,8 @@
 use crate::error::{check_result, DiceError, Result};
 use alloc::{vec, vec::Vec};
 use open_dice_cbor_bindgen::{
-    DiceGenerateCertificate, DiceHash, DiceKdf, DiceKeypairFromSeed, DicePrincipal, DiceSign,
-    DiceVerify,
+    DiceCoseSignAndEncodeSign1, DiceGenerateCertificate, DiceHash, DiceKdf, DiceKeypairFromSeed,
+    DicePrincipal, DiceSign, DiceVerify,
 };
 use std::ptr;
 
@@ -114,7 +114,7 @@
     Ok(private_key)
 }
 
-/// Signs the `message` with the give `private_key` using `DiceSign`.
+/// Signs the `message` with the given `private_key` using `DiceSign`.
 pub fn sign(message: &[u8], private_key: &[u8; PRIVATE_KEY_SIZE]) -> Result<Vec<u8>> {
     let mut signature = vec![0u8; VM_KEY_ALGORITHM.signature_size()];
     check_result(
@@ -136,6 +136,58 @@
     Ok(signature)
 }
 
+/// Signs the `message` with the given `private_key` and places a `CoseSign1` encoded
+/// object in `encoded_signature`. Uses `DiceCoseSignAndEncodeSign1`.
+///
+/// Returns the actual size of encoded_signature on success.
+pub fn sign_cose_sign1(
+    message: &[u8],
+    aad: &[u8],
+    private_key: &[u8; PRIVATE_KEY_SIZE],
+    encoded_signature: &mut [u8],
+) -> Result<usize> {
+    let mut encoded_signature_actual_size = 0;
+
+    check_result(
+        // SAFETY: The function writes to `encoded_signature` and `encoded_signature_actual_size`
+        // within the given bounds. It only reads `message`, `aad`, and `private_key` within their
+        // given bounds.
+        //
+        // The first argument is a pointer to a valid |DiceContext_| object for multi-alg open-dice
+        // and a null pointer otherwise.
+        unsafe {
+            DiceCoseSignAndEncodeSign1(
+                context(),
+                message.as_ptr(),
+                message.len(),
+                aad.as_ptr(),
+                aad.len(),
+                private_key.as_ptr(),
+                encoded_signature.len(),
+                encoded_signature.as_mut_ptr(),
+                &mut encoded_signature_actual_size,
+            )
+        },
+        encoded_signature_actual_size,
+    )?;
+    Ok(encoded_signature_actual_size)
+}
+
+/// Signs the `message` with a private key derived from the given `dice_artifacts`
+/// CDI Attest. On success, places a `CoseSign1` encoded object in `encoded_signature`.
+/// Uses `DiceCoseSignAndEncodeSign1`.
+///
+/// Returns the actual size of encoded_signature on success.
+pub fn sign_cose_sign1_with_cdi_leaf_priv(
+    message: &[u8],
+    aad: &[u8],
+    dice_artifacts: &dyn DiceArtifacts,
+    encoded_signature: &mut [u8],
+) -> Result<usize> {
+    let private_key = derive_cdi_leaf_priv(dice_artifacts)?;
+    sign_cose_sign1(message, aad, private_key.as_array(), encoded_signature)
+}
+
 /// Verifies the `signature` of the `message` with the given `public_key` using `DiceVerify`.
 pub fn verify(message: &[u8], signature: &[u8], public_key: &[u8]) -> Result<()> {
     if signature.len() != VM_KEY_ALGORITHM.signature_size()
diff --git a/libs/dice/open_dice/src/retry.rs b/libs/dice/open_dice/src/retry.rs
index 6e75e91..cf36bc0 100644
--- a/libs/dice/open_dice/src/retry.rs
+++ b/libs/dice/open_dice/src/retry.rs
@@ -13,16 +13,17 @@
 // limitations under the License.
 
 //! This module implements a retry version for multiple DICE functions that
-//! require preallocated output buffer. As the retry functions require
-//! memory allocation on heap, currently we only expose these functions in
-//! std environment.
+//! require preallocated output buffer. When running without std the allocation
+//! of this buffer may fail and callers will see Error::MemoryAllocationError.
+//! When running with std, allocation may fail.
 
 use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow, DiceConfigValues};
 use crate::dice::{
     dice_main_flow, Cdi, CdiValues, DiceArtifacts, InputValues, CDI_SIZE, PRIVATE_KEY_SEED_SIZE,
+    PRIVATE_KEY_SIZE,
 };
 use crate::error::{DiceError, Result};
-use crate::ops::generate_certificate;
+use crate::ops::{generate_certificate, sign_cose_sign1, sign_cose_sign1_with_cdi_leaf_priv};
 use alloc::vec::Vec;
 #[cfg(feature = "serde_derive")]
 use serde_derive::{Deserialize, Serialize};
@@ -62,6 +63,9 @@
     let mut buffer = Vec::new();
     match f(&mut buffer) {
         Err(DiceError::BufferTooSmall(actual_size)) => {
+            #[cfg(not(feature = "std"))]
+            buffer.try_reserve_exact(actual_size).map_err(|_| DiceError::MemoryAllocationError)?;
+
             buffer.resize(actual_size, 0);
             f(&mut buffer)?;
         }
@@ -141,3 +145,28 @@
         )
     })
 }
+
+/// Signs a message with the given private key and returns the signature
+/// as an encoded CoseSign1 object.
+pub fn retry_sign_cose_sign1(
+    message: &[u8],
+    aad: &[u8],
+    private_key: &[u8; PRIVATE_KEY_SIZE],
+) -> Result<Vec<u8>> {
+    retry_with_measured_buffer(|encoded_signature| {
+        sign_cose_sign1(message, aad, private_key, encoded_signature)
+    })
+}
+
+/// Signs a message with the given the private key derived from the
+/// CDI Attest of the given `dice_artifacts` and returns the signature
+/// as an encoded CoseSign1 object.
+pub fn retry_sign_cose_sign1_with_cdi_leaf_priv(
+    message: &[u8],
+    aad: &[u8],
+    dice_artifacts: &dyn DiceArtifacts,
+) -> Result<Vec<u8>> {
+    retry_with_measured_buffer(|encoded_signature| {
+        sign_cose_sign1_with_cdi_leaf_priv(message, aad, dice_artifacts, encoded_signature)
+    })
+}
diff --git a/libs/dice/open_dice/tests/api_test.rs b/libs/dice/open_dice/tests/api_test.rs
index a47265b..b0c2ca7 100644
--- a/libs/dice/open_dice/tests/api_test.rs
+++ b/libs/dice/open_dice/tests/api_test.rs
@@ -14,94 +14,186 @@
  * 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,
+        retry_sign_cose_sign1, retry_sign_cose_sign1_with_cdi_leaf_priv, sign, verify,
+        DiceArtifacts, PrivateKey, 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,
+    use coset::{CborSerializable, CoseSign1};
+
+    // 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; CDI_SIZE] = &[
+        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,
-];
+    #[test]
+    fn hash_derive_sign_verify() {
+        let (pub_key, priv_key) = get_test_key_pair();
 
-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,
-];
+        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());
+    }
 
-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 sign_cose_sign1_verify() {
+        let (pub_key, priv_key) = get_test_key_pair();
 
-#[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());
+        let signature_res = retry_sign_cose_sign1(b"MyMessage", b"MyAad", priv_key.as_array());
+        assert!(signature_res.is_ok());
+        let signature = signature_res.unwrap();
+        let cose_sign1_res = CoseSign1::from_slice(&signature);
+        assert!(cose_sign1_res.is_ok());
+        let mut cose_sign1 = cose_sign1_res.unwrap();
+
+        let mut verify_result =
+            cose_sign1.verify_signature(b"MyAad", |sign, data| verify(data, sign, &pub_key));
+        assert!(verify_result.is_ok());
+
+        verify_result =
+            cose_sign1.verify_signature(b"BadAad", |sign, data| verify(data, sign, &pub_key));
+        assert!(verify_result.is_err());
+
+        // if we modify the signature, the payload should no longer verify
+        cose_sign1.signature.push(0xAA);
+        verify_result =
+            cose_sign1.verify_signature(b"MyAad", |sign, data| verify(data, sign, &pub_key));
+        assert!(verify_result.is_err());
+    }
+
+    struct TestArtifactsForSigning {}
+
+    impl DiceArtifacts for TestArtifactsForSigning {
+        fn cdi_attest(&self) -> &[u8; CDI_SIZE] {
+            EXPECTED_CDI_ATTEST
+        }
+
+        fn cdi_seal(&self) -> &[u8; CDI_SIZE] {
+            unimplemented!("no test functionality depends on this")
+        }
+
+        fn bcc(&self) -> Option<&[u8]> {
+            unimplemented!("no test functionality depends on this")
+        }
+    }
+
+    #[test]
+    fn sign_cose_sign1_with_cdi_leaf_priv_verify() {
+        let dice = TestArtifactsForSigning {};
+
+        let signature_res = retry_sign_cose_sign1_with_cdi_leaf_priv(b"MyMessage", b"MyAad", &dice);
+        assert!(signature_res.is_ok());
+        let signature = signature_res.unwrap();
+        let cose_sign1_res = CoseSign1::from_slice(&signature);
+        assert!(cose_sign1_res.is_ok());
+        let mut cose_sign1 = cose_sign1_res.unwrap();
+
+        let mut verify_result = cose_sign1
+            .verify_signature(b"MyAad", |sign, data| verify(data, sign, EXPECTED_PUB_KEY));
+        assert!(verify_result.is_ok());
+
+        verify_result = cose_sign1
+            .verify_signature(b"BadAad", |sign, data| verify(data, sign, EXPECTED_PUB_KEY));
+        assert!(verify_result.is_err());
+
+        // if we modify the signature, the payload should no longer verify
+        cose_sign1.signature.push(0xAA);
+        verify_result = cose_sign1
+            .verify_signature(b"MyAad", |sign, data| verify(data, sign, EXPECTED_PUB_KEY));
+        assert!(verify_result.is_err());
+    }
+
+    fn get_test_key_pair() -> (Vec<u8>, PrivateKey) {
+        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);
+
+        (pub_key, priv_key)
+    }
 }
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 66%
copy from libs/cstr/rules.mk
copy to libs/dice/open_dice/tests/rules.mk
index 2309c30..83a6bff 100644
--- a/libs/cstr/rules.mk
+++ b/libs/dice/open_dice/tests/rules.mk
@@ -17,12 +17,20 @@
 
 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 \
+	$(call FIND_CRATE,coset) \
 
-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 c323bc4..adca46b 100644
--- a/libs/dice/sample_inputs/src/sample_inputs.rs
+++ b/libs/dice/sample_inputs/src/sample_inputs.rs
@@ -18,7 +18,6 @@
 use alloc::vec;
 use alloc::vec::Vec;
 use ciborium::{de, ser, value::Value};
-use core::ffi::CStr;
 use coset::{iana, Algorithm, AsCborValue, CoseKey, KeyOperation, KeyType, Label};
 use diced_open_dice::{
     derive_cdi_private_key_seed, keypair_from_seed, retry_bcc_format_config_descriptor,
@@ -115,7 +114,7 @@
 
     // Gets the ABL certificate to as the root certificate of DICE chain.
     let config_values = DiceConfigValues {
-        component_name: Some(CStr::from_bytes_with_nul(b"ABL\0").unwrap()),
+        component_name: Some(c"ABL"),
         component_version: Some(1),
         resettable: true,
         security_version: Some(10),
@@ -148,7 +147,7 @@
 
     // Appends AVB certificate to DICE chain.
     let config_values = DiceConfigValues {
-        component_name: Some(CStr::from_bytes_with_nul(b"AVB\0").unwrap()),
+        component_name: Some(c"AVB"),
         component_version: Some(1),
         resettable: true,
         security_version: Some(11),
@@ -173,7 +172,7 @@
 
     // Appends Android certificate to DICE chain.
     let config_values = DiceConfigValues {
-        component_name: Some(CStr::from_bytes_with_nul(b"Android\0").unwrap()),
+        component_name: Some(c"Android"),
         component_version: Some(12),
         resettable: true,
         security_version: Some(12),
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/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/iterators.rs b/libs/libfdt/src/iterators.rs
index 743c52b..1c66e4d 100644
--- a/libs/libfdt/src/iterators.rs
+++ b/libs/libfdt/src/iterators.rs
@@ -66,7 +66,7 @@
     }
 }
 
-impl<'a> Iterator for CellIterator<'a> {
+impl Iterator for CellIterator<'_> {
     type Item = u32;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -118,7 +118,7 @@
     }
 }
 
-impl<'a> Iterator for RegIterator<'a> {
+impl Iterator for RegIterator<'_> {
     type Item = Reg<u64>;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -161,7 +161,7 @@
     }
 }
 
-impl<'a> Iterator for MemRegIterator<'a> {
+impl Iterator for MemRegIterator<'_> {
     type Item = Range<usize>;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -215,8 +215,8 @@
     }
 }
 
-impl<'a, A: FromAddrCells, P: FromAddrCells, S: FromSizeCells> Iterator
-    for RangesIterator<'a, A, P, S>
+impl<A: FromAddrCells, P: FromAddrCells, S: FromSizeCells> Iterator
+    for RangesIterator<'_, A, P, S>
 {
     type Item = AddressRange<A, P, S>;
 
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index 0dcd31a..47f4817 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -344,7 +344,7 @@
     }
 }
 
-impl<'a> PartialEq for FdtNode<'a> {
+impl PartialEq for FdtNode<'_> {
     fn eq(&self, other: &Self) -> bool {
         self.fdt.as_ptr() == other.fdt.as_ptr() && self.offset == other.offset
     }
diff --git a/libs/libhypervisor_backends/Android.bp b/libs/libhypervisor_backends/Android.bp
index b001b8f..e9e8915 100644
--- a/libs/libhypervisor_backends/Android.bp
+++ b/libs/libhypervisor_backends/Android.bp
@@ -11,19 +11,27 @@
     host_supported: false,
     no_stdlibs: true,
     srcs: ["src/lib.rs"],
-    rustlibs: [
-        "libonce_cell_nostd",
-        "libsmccc",
-        "libuuid_nostd",
-    ],
     enabled: false,
+    stdlibs: [
+        "libcompiler_builtins.rust_sysroot",
+        "libcore.rust_sysroot",
+    ],
     target: {
         android_arm64: {
-            enabled: true,
-            stdlibs: [
-                "libcompiler_builtins.rust_sysroot",
-                "libcore.rust_sysroot",
+            rustlibs: [
+                "libonce_cell_nostd",
+                "libsmccc",
+                "libthiserror_nostd",
+                "libuuid_nostd",
             ],
+            enabled: true,
+        },
+        android_x86_64: {
+            rustlibs: [
+                "libonce_cell_nostd",
+                "libthiserror_nostd",
+            ],
+            enabled: true,
         },
     },
 }
diff --git a/libs/libhypervisor_backends/rules.mk b/libs/libhypervisor_backends/rules.mk
index 6fc9dea..1a48773 100644
--- a/libs/libhypervisor_backends/rules.mk
+++ b/libs/libhypervisor_backends/rules.mk
@@ -8,6 +8,7 @@
 	trusty/user/base/lib/liballoc-rust \
 	$(call FIND_CRATE,once_cell) \
 	$(call FIND_CRATE,smccc) \
+	$(call FIND_CRATE,thiserror) \
 	$(call FIND_CRATE,uuid) \
 
 include make/library.mk
\ No newline at end of file
diff --git a/libs/libhypervisor_backends/src/error.rs b/libs/libhypervisor_backends/src/error.rs
index e9c37e1..3046b0c 100644
--- a/libs/libhypervisor_backends/src/error.rs
+++ b/libs/libhypervisor_backends/src/error.rs
@@ -16,7 +16,10 @@
 
 use core::{fmt, result};
 
-use super::hypervisor::{GeniezoneError, KvmError};
+#[cfg(target_arch = "aarch64")]
+use super::hypervisor::GeniezoneError;
+use super::hypervisor::KvmError;
+#[cfg(target_arch = "aarch64")]
 use uuid::Uuid;
 
 /// Result type with hypervisor error.
@@ -29,10 +32,15 @@
     MmioGuardNotSupported,
     /// Failed to invoke a certain KVM HVC function.
     KvmError(KvmError, u32),
+    #[cfg(target_arch = "aarch64")]
     /// Failed to invoke GenieZone HVC function.
     GeniezoneError(GeniezoneError, u32),
+    #[cfg(target_arch = "aarch64")]
     /// Unsupported Hypervisor
     UnsupportedHypervisorUuid(Uuid),
+    #[cfg(target_arch = "x86_64")]
+    /// Unsupported x86_64 Hypervisor
+    UnsupportedHypervisor(u128),
 }
 
 impl fmt::Display for Error {
@@ -42,15 +50,21 @@
             Self::KvmError(e, function_id) => {
                 write!(f, "Failed to invoke the HVC function with function ID {function_id}: {e}")
             }
+            #[cfg(target_arch = "aarch64")]
             Self::GeniezoneError(e, function_id) => {
                 write!(
                     f,
                     "Failed to invoke GenieZone HVC function with function ID {function_id}: {e}"
                 )
             }
+            #[cfg(target_arch = "aarch64")]
             Self::UnsupportedHypervisorUuid(u) => {
                 write!(f, "Unsupported Hypervisor UUID {u}")
             }
+            #[cfg(target_arch = "x86_64")]
+            Self::UnsupportedHypervisor(c) => {
+                write!(f, "Unsupported x86_64 Hypervisor {c}")
+            }
         }
     }
 }
diff --git a/libs/libhypervisor_backends/src/hypervisor.rs b/libs/libhypervisor_backends/src/hypervisor.rs
index 1b45f38..aa65133 100644
--- a/libs/libhypervisor_backends/src/hypervisor.rs
+++ b/libs/libhypervisor_backends/src/hypervisor.rs
@@ -15,26 +15,42 @@
 //! Wrappers around hypervisor back-ends.
 
 mod common;
+#[cfg(target_arch = "aarch64")]
 mod geniezone;
+#[cfg(target_arch = "aarch64")]
 mod gunyah;
+#[cfg(target_arch = "aarch64")]
+#[path = "hypervisor/kvm_aarch64.rs"]
 mod kvm;
 
-use super::{Error, Result};
+#[cfg(target_arch = "x86_64")]
+#[path = "hypervisor/kvm_x86.rs"]
+mod kvm;
+
+#[cfg(target_arch = "aarch64")]
+use {
+    super::{Error, Result},
+    geniezone::GeniezoneHypervisor,
+    gunyah::GunyahHypervisor,
+    smccc::hvc64,
+    uuid::Uuid,
+};
+
+#[cfg(target_arch = "aarch64")]
+pub use geniezone::GeniezoneError;
+
 use alloc::boxed::Box;
 use common::Hypervisor;
 pub use common::{DeviceAssigningHypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
-pub use geniezone::GeniezoneError;
-use geniezone::GeniezoneHypervisor;
-use gunyah::GunyahHypervisor;
 pub use kvm::KvmError;
 use kvm::{ProtectedKvmHypervisor, RegularKvmHypervisor};
 use once_cell::race::OnceBox;
-use smccc::hvc64;
-use uuid::Uuid;
 
 enum HypervisorBackend {
     RegularKvm,
+    #[cfg(target_arch = "aarch64")]
     Gunyah,
+    #[cfg(target_arch = "aarch64")]
     Geniezone,
     ProtectedKvm,
 }
@@ -43,13 +59,16 @@
     fn get_hypervisor(&self) -> &'static dyn Hypervisor {
         match self {
             Self::RegularKvm => &RegularKvmHypervisor,
+            #[cfg(target_arch = "aarch64")]
             Self::Gunyah => &GunyahHypervisor,
+            #[cfg(target_arch = "aarch64")]
             Self::Geniezone => &GeniezoneHypervisor,
             Self::ProtectedKvm => &ProtectedKvmHypervisor,
         }
     }
 }
 
+#[cfg(target_arch = "aarch64")]
 impl TryFrom<Uuid> for HypervisorBackend {
     type Error = Error;
 
@@ -74,8 +93,10 @@
     }
 }
 
+#[cfg(target_arch = "aarch64")]
 const ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: u32 = 0x8600ff01;
 
+#[cfg(target_arch = "aarch64")]
 fn query_vendor_hyp_call_uid() -> Uuid {
     let args = [0u64; 17];
     let res = hvc64(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, args);
@@ -101,7 +122,13 @@
 }
 
 fn detect_hypervisor() -> HypervisorBackend {
-    query_vendor_hyp_call_uid().try_into().expect("Failed to detect hypervisor")
+    #[cfg(target_arch = "aarch64")]
+    {
+        query_vendor_hyp_call_uid().try_into().expect("Failed to detect hypervisor")
+    }
+
+    #[cfg(target_arch = "x86_64")]
+    kvm::determine_hyp_type().expect("Failed to detect hypervisor")
 }
 
 /// Gets the hypervisor singleton.
diff --git a/libs/libhypervisor_backends/src/hypervisor/geniezone.rs b/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
index fe56528..76e010b 100644
--- a/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/geniezone.rs
@@ -14,8 +14,6 @@
 
 //! Wrappers around calls to the GenieZone hypervisor.
 
-use core::fmt::{self, Display, Formatter};
-
 use super::{Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
 use crate::{mem::page_4kb_of, Error, Result};
 
@@ -23,6 +21,7 @@
     error::{positive_or_error_64, success_or_error_64},
     hvc64,
 };
+use thiserror::Error;
 use uuid::{uuid, Uuid};
 
 pub(super) struct GeniezoneHypervisor;
@@ -44,15 +43,19 @@
 }
 
 /// Error from a GenieZone HVC call.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Eq, Error, PartialEq)]
 pub enum GeniezoneError {
     /// The call is not supported by the implementation.
+    #[error("GenieZone call not supported")]
     NotSupported,
     /// The call is not required to implement.
+    #[error("GenieZone call not required")]
     NotRequired,
     /// One of the call parameters has a invalid value.
+    #[error("GenieZone call received invalid value")]
     InvalidParameter,
     /// There was an unexpected return value.
+    #[error("Unknown return value from GenieZone {0} ({0:#x})")]
     Unknown(i64),
 }
 
@@ -73,17 +76,6 @@
     }
 }
 
-impl Display for GeniezoneError {
-    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
-        match self {
-            Self::NotSupported => write!(f, "GenieZone call not supported"),
-            Self::NotRequired => write!(f, "GenieZone call not required"),
-            Self::InvalidParameter => write!(f, "GenieZone call received invalid value"),
-            Self::Unknown(e) => write!(f, "Unknown return value from GenieZone {} ({0:#x})", e),
-        }
-    }
-}
-
 impl Hypervisor for GeniezoneHypervisor {
     fn as_mmio_guard(&self) -> Option<&dyn MmioGuardedHypervisor> {
         Some(self)
diff --git a/libs/libhypervisor_backends/src/hypervisor/kvm.rs b/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
similarity index 93%
rename from libs/libhypervisor_backends/src/hypervisor/kvm.rs
rename to libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
index e18c1f4..233097b 100644
--- a/libs/libhypervisor_backends/src/hypervisor/kvm.rs
+++ b/libs/libhypervisor_backends/src/hypervisor/kvm_aarch64.rs
@@ -14,8 +14,6 @@
 
 //! Wrappers around calls to the KVM hypervisor.
 
-use core::fmt::{self, Display, Formatter};
-
 use super::{DeviceAssigningHypervisor, Hypervisor, MemSharingHypervisor, MmioGuardedHypervisor};
 use crate::{mem::page_4kb_of, Error, Result};
 
@@ -23,16 +21,20 @@
     error::{positive_or_error_64, success_or_error_32, success_or_error_64},
     hvc64,
 };
+use thiserror::Error;
 use uuid::{uuid, Uuid};
 
 /// Error from a KVM HVC call.
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Eq, Error, PartialEq)]
 pub enum KvmError {
     /// The call is not supported by the implementation.
+    #[error("KVM call not supported")]
     NotSupported,
     /// One of the call parameters has a non-supported value.
+    #[error("KVM call received non-supported value")]
     InvalidParameter,
     /// There was an unexpected return value.
+    #[error("Unknown return value from KVM {0} ({0:#x})")]
     Unknown(i64),
 }
 
@@ -52,16 +54,6 @@
     }
 }
 
-impl Display for KvmError {
-    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
-        match self {
-            Self::NotSupported => write!(f, "KVM call not supported"),
-            Self::InvalidParameter => write!(f, "KVM call received non-supported value"),
-            Self::Unknown(e) => write!(f, "Unknown return value from KVM {} ({0:#x})", e),
-        }
-    }
-}
-
 const ARM_SMCCC_KVM_FUNC_HYP_MEMINFO: u32 = 0xc6000002;
 const ARM_SMCCC_KVM_FUNC_MEM_SHARE: u32 = 0xc6000003;
 const ARM_SMCCC_KVM_FUNC_MEM_UNSHARE: u32 = 0xc6000004;
diff --git a/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs b/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs
new file mode 100644
index 0000000..7f9ea4d
--- /dev/null
+++ b/libs/libhypervisor_backends/src/hypervisor/kvm_x86.rs
@@ -0,0 +1,172 @@
+// 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.
+
+//! Wrappers around calls to the KVM hypervisor.
+
+use super::{Hypervisor, MemSharingHypervisor};
+use crate::{mem::SIZE_4KB, Error, Result};
+use core::fmt::{self, Display, Formatter};
+
+const KVM_HC_PKVM_OP: u32 = 20;
+const PKVM_GHC_SHARE_MEM: u32 = KVM_HC_PKVM_OP + 1;
+const PKVM_GHC_UNSHARE_MEM: u32 = KVM_HC_PKVM_OP + 2;
+
+const KVM_ENOSYS: i64 = -1000;
+const KVM_EINVAL: i64 = -22;
+
+/// This CPUID returns the signature and can be used to determine if VM is running under pKVM, KVM
+/// or not.
+pub const KVM_CPUID_SIGNATURE: u32 = 0x40000000;
+
+/// Error from a KVM HVC call.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum KvmError {
+    /// The call is not supported by the implementation.
+    NotSupported,
+    /// One of the call parameters has a non-supported value.
+    InvalidParameter,
+    /// There was an unexpected return value.
+    Unknown(i64),
+}
+
+impl From<i64> for KvmError {
+    fn from(value: i64) -> Self {
+        match value {
+            KVM_ENOSYS => KvmError::NotSupported,
+            KVM_EINVAL => KvmError::InvalidParameter,
+            _ => KvmError::Unknown(value),
+        }
+    }
+}
+
+impl From<i32> for KvmError {
+    fn from(value: i32) -> Self {
+        i64::from(value).into()
+    }
+}
+
+impl Display for KvmError {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        match self {
+            Self::NotSupported => write!(f, "KVM call not supported"),
+            Self::InvalidParameter => write!(f, "KVM call received non-supported value"),
+            Self::Unknown(e) => write!(f, "Unknown return value from KVM {} ({0:#x})", e),
+        }
+    }
+}
+
+pub(super) struct RegularKvmHypervisor;
+
+impl RegularKvmHypervisor {
+    pub(super) const CPUID: u128 = u128::from_le_bytes(*b"KVMKVMKVM\0\0\0\0\0\0\0");
+}
+
+impl Hypervisor for RegularKvmHypervisor {}
+
+pub(super) struct ProtectedKvmHypervisor;
+
+impl ProtectedKvmHypervisor {
+    pub(super) const CPUID: u128 = u128::from_le_bytes(*b"PKVMPKVMPKVM\0\0\0\0");
+}
+
+impl Hypervisor for ProtectedKvmHypervisor {
+    fn as_mem_sharer(&self) -> Option<&dyn MemSharingHypervisor> {
+        Some(self)
+    }
+}
+
+macro_rules! vmcall {
+    ($hypcall:expr, $base:expr, $size:expr) => {{
+        let ret;
+        // SAFETY:
+        // Any undeclared register aren't clobbered except rbx but rbx value is restored at the end
+        // of the asm block.
+        unsafe {
+            core::arch::asm!(
+                "xchg %rbx, {0:r}",
+                "vmcall",
+                "xchg %rbx, {0:r}",
+                in(reg) $base,
+                inout("rax") $hypcall => ret,
+                in("rcx") $size,
+                options(att_syntax, nomem));
+        };
+        ret
+    }};
+}
+
+macro_rules! cpuid {
+    ($hypcall:expr) => {{
+        let ret_1: u32;
+        let ret_2: u32;
+        let ret_3: u32;
+        // SAFETY:
+        // Any undeclared register aren't clobbered except rbx but rbx value is restored at the end
+        // of the asm block.
+        unsafe {
+            // The argument for cpuid is passed via rax and in case of KVM_CPUID_SIGNATURE returned
+            // via rbx, rcx and rdx. Ideally using named arguments in inline asm for rbx would be
+            // much more straightforward but when rbx is directly used LLVM complains that: error:
+            // cannot use register `bx`: rbx is used internally by LLVM and cannot be used as an
+            // operand for inline asm
+            //
+            // Therefore use temp register to store rbx content and restore it back after cpuid
+            // call.
+            core::arch::asm!(
+                "xchg %rbx, {0:r}",
+                "cpuid",
+                "xchg %rbx, {0:r}",
+                out(reg) ret_1, in("eax") $hypcall, out("rcx") ret_2, out ("rdx") ret_3,
+                options(att_syntax, nomem));
+        };
+        ((ret_3 as u128) << 64) | ((ret_2 as u128) << 32) | (ret_1 as u128)
+    }};
+}
+
+impl MemSharingHypervisor for ProtectedKvmHypervisor {
+    fn share(&self, base_ipa: u64) -> Result<()> {
+        let ret: u32 = vmcall!(PKVM_GHC_SHARE_MEM, base_ipa, SIZE_4KB);
+
+        if ret != 0 {
+            return Err(Error::KvmError(KvmError::from(ret as i32), PKVM_GHC_SHARE_MEM));
+        }
+
+        Ok(())
+    }
+
+    fn unshare(&self, base_ipa: u64) -> Result<()> {
+        let ret: u32 = vmcall!(PKVM_GHC_UNSHARE_MEM, base_ipa, SIZE_4KB);
+        if ret != 0 {
+            return Err(Error::KvmError(KvmError::from(ret as i32), PKVM_GHC_UNSHARE_MEM));
+        }
+
+        Ok(())
+    }
+
+    fn granule(&self) -> Result<usize> {
+        Ok(SIZE_4KB)
+    }
+}
+
+use crate::hypervisor::HypervisorBackend;
+
+pub(crate) fn determine_hyp_type() -> Result<HypervisorBackend> {
+    let cpuid: u128 = cpuid!(KVM_CPUID_SIGNATURE);
+
+    match cpuid {
+        RegularKvmHypervisor::CPUID => Ok(HypervisorBackend::RegularKvm),
+        ProtectedKvmHypervisor::CPUID => Ok(HypervisorBackend::ProtectedKvm),
+        c => Err(Error::UnsupportedHypervisor(c)),
+    }
+}
diff --git a/libs/libhypervisor_backends/src/mem.rs b/libs/libhypervisor_backends/src/mem.rs
index ff65c49..9f7eafc 100644
--- a/libs/libhypervisor_backends/src/mem.rs
+++ b/libs/libhypervisor_backends/src/mem.rs
@@ -15,6 +15,7 @@
 /// The size of a 4KB memory in bytes.
 pub const SIZE_4KB: usize = 4 << 10;
 
+#[cfg(target_arch = "aarch64")]
 /// Computes the largest multiple of the provided alignment smaller or equal to the address.
 ///
 /// Note: the result is undefined if alignment isn't a power of two.
@@ -22,6 +23,7 @@
     addr & !(alignment - 1)
 }
 
+#[cfg(target_arch = "aarch64")]
 /// Computes the address of the 4KiB page containing a given address.
 pub const fn page_4kb_of(addr: usize) -> usize {
     unchecked_align_down(addr, SIZE_4KB)
diff --git a/libs/libservice_vm_requests/src/cert.rs b/libs/libservice_vm_requests/src/cert.rs
index e31d870..de5ae1a 100644
--- a/libs/libservice_vm_requests/src/cert.rs
+++ b/libs/libservice_vm_requests/src/cert.rs
@@ -58,7 +58,7 @@
     vm_components: Vec<VmComponent<'a>>,
 }
 
-impl<'a> AssociatedOid for AttestationExtension<'a> {
+impl AssociatedOid for AttestationExtension<'_> {
     const OID: ObjectIdentifier = AVF_ATTESTATION_EXTENSION_V1;
 }
 
diff --git a/libs/libvm_payload/include/vm_payload.h b/libs/libvm_payload/include/vm_payload.h
index 43fba82..e4609fa 100644
--- a/libs/libvm_payload/include/vm_payload.h
+++ b/libs/libvm_payload/include/vm_payload.h
@@ -118,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.
@@ -304,4 +309,13 @@
 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 0c6b56d..ca949d9 100644
--- a/libs/libvm_payload/libvm_payload.map.txt
+++ b/libs/libvm_payload/libvm_payload.map.txt
@@ -17,6 +17,7 @@
     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 29b0cbd..14aff99 100644
--- a/libs/libvm_payload/src/lib.rs
+++ b/libs/libvm_payload/src/lib.rs
@@ -27,7 +27,7 @@
 use rpcbinder::{RpcServer, RpcSession};
 use openssl::{ec::EcKey, sha::sha256, ecdsa::EcdsaSig};
 use std::convert::Infallible;
-use std::ffi::{CString, CStr};
+use std::ffi::CString;
 use std::fmt::Debug;
 use std::os::raw::{c_char, c_void};
 use std::path::Path;
@@ -376,20 +376,16 @@
 #[no_mangle]
 pub extern "C" fn AVmAttestationStatus_toString(status: AVmAttestationStatus) -> *const c_char {
     let message = match status {
-        AVmAttestationStatus::ATTESTATION_OK => {
-            CStr::from_bytes_with_nul(b"The remote attestation completes successfully.\0").unwrap()
-        }
+        AVmAttestationStatus::ATTESTATION_OK => c"The remote attestation completes successfully.",
         AVmAttestationStatus::ATTESTATION_ERROR_INVALID_CHALLENGE => {
-            CStr::from_bytes_with_nul(b"The challenge size is not between 0 and 64.\0").unwrap()
+            c"The challenge size is not between 0 and 64."
         }
         AVmAttestationStatus::ATTESTATION_ERROR_ATTESTATION_FAILED => {
-            CStr::from_bytes_with_nul(b"Failed to attest the VM. Please retry at a later time.\0")
-                .unwrap()
+            c"Failed to attest the VM. Please retry at a later time."
         }
-        AVmAttestationStatus::ATTESTATION_ERROR_UNSUPPORTED => CStr::from_bytes_with_nul(
-            b"Remote attestation is not supported in the current environment.\0",
-        )
-        .unwrap(),
+        AVmAttestationStatus::ATTESTATION_ERROR_UNSUPPORTED => {
+            c"Remote attestation is not supported in the current environment."
+        }
     };
     message.as_ptr()
 }
@@ -652,3 +648,15 @@
         .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/attestation.rs b/libs/libvm_payload/wrapper/attestation.rs
index e0055d5..69fef4f 100644
--- a/libs/libvm_payload/wrapper/attestation.rs
+++ b/libs/libvm_payload/wrapper/attestation.rs
@@ -265,7 +265,7 @@
     current: usize, // Invariant: current <= count
 }
 
-impl<'a> Iterator for CertIterator<'a> {
+impl Iterator for CertIterator<'_> {
     type Item = Vec<u8>;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -284,5 +284,5 @@
     }
 }
 
-impl<'a> ExactSizeIterator for CertIterator<'a> {}
-impl<'a> FusedIterator for CertIterator<'a> {}
+impl ExactSizeIterator for CertIterator<'_> {}
+impl FusedIterator for CertIterator<'_> {}
diff --git a/libs/libvm_payload/wrapper/lib.rs b/libs/libvm_payload/wrapper/lib.rs
index 133b14e..bf274b0 100644
--- a/libs/libvm_payload/wrapper/lib.rs
+++ b/libs/libvm_payload/wrapper/lib.rs
@@ -31,7 +31,7 @@
 use std::ptr;
 use vm_payload_bindgen::{
     AIBinder, AVmPayload_getApkContentsPath, AVmPayload_getEncryptedStoragePath,
-    AVmPayload_getVmInstanceSecret, AVmPayload_notifyPayloadReady,
+    AVmPayload_getVmInstanceSecret, AVmPayload_isNewInstance, AVmPayload_notifyPayloadReady,
     AVmPayload_readRollbackProtectedSecret, AVmPayload_runVsockRpcServer,
     AVmPayload_writeRollbackProtectedSecret,
 };
@@ -208,3 +208,11 @@
     // 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 de347c7..7465508 100644
--- a/libs/libvmbase/Android.bp
+++ b/libs/libvmbase/Android.bp
@@ -87,6 +87,7 @@
         "libsmccc",
         "libspin_nostd",
         "libstatic_assertions",
+        "libthiserror_nostd",
         "libtinyvec_nostd",
         "libuuid_nostd",
         "libvirtio_drivers",
diff --git a/libs/libvmbase/src/bionic.rs b/libs/libvmbase/src/bionic.rs
index 37b6e45..2b59493 100644
--- a/libs/libvmbase/src/bionic.rs
+++ b/libs/libvmbase/src/bionic.rs
@@ -20,7 +20,6 @@
 use core::ffi::c_int;
 use core::ffi::c_void;
 use core::ffi::CStr;
-use core::ptr::addr_of_mut;
 use core::slice;
 use core::str;
 
@@ -71,11 +70,10 @@
 pub static mut ERRNO: c_int = 0;
 
 #[no_mangle]
-#[allow(unused_unsafe)]
+// SAFETY: C functions which call this are only called from the main thread, not from exception
+// handlers.
 unsafe extern "C" fn __errno() -> *mut c_int {
-    // SAFETY: C functions which call this are only called from the main thread, not from exception
-    // handlers.
-    unsafe { addr_of_mut!(ERRNO) as *mut _ }
+    (&raw mut ERRNO).cast()
 }
 
 fn set_errno(value: c_int) {
@@ -88,15 +86,20 @@
     unsafe { ERRNO }
 }
 
+/// # Safety
+///
+/// `buffer` must point to an allocation of at least `length` bytes which is valid to write to and
+/// has no concurrent access while this function is running.
 #[no_mangle]
-extern "C" fn getentropy(buffer: *mut c_void, length: usize) -> c_int {
+unsafe extern "C" fn getentropy(buffer: *mut c_void, length: usize) -> c_int {
     if length > 256 {
         // The maximum permitted value for the length argument is 256.
         set_errno(EIO);
         return -1;
     }
 
-    // SAFETY: Just like libc, we need to assume that `ptr` is valid.
+    // SAFETY: The caller promised that `buffer` is a valid pointer to at least `length` bytes with
+    // no concurrent access.
     let buffer = unsafe { slice::from_raw_parts_mut(buffer.cast::<u8>(), length) };
     fill_with_entropy(buffer).unwrap();
 
@@ -169,9 +172,13 @@
 #[no_mangle]
 static stderr: CFilePtr = CFilePtr::Stderr;
 
+/// # Safety
+///
+/// `c_str` must be a valid pointer to a NUL-terminated string which is not modified before this
+/// function returns.
 #[no_mangle]
-extern "C" fn fputs(c_str: *const c_char, stream: usize) -> c_int {
-    // SAFETY: Just like libc, we need to assume that `s` is a valid NULL-terminated string.
+unsafe extern "C" fn fputs(c_str: *const c_char, stream: usize) -> c_int {
+    // SAFETY: The caller promised that `c_str` is a valid NUL-terminated string.
     let c_str = unsafe { CStr::from_ptr(c_str) };
 
     if let (Ok(s), Ok(f)) = (c_str.to_str(), CFilePtr::try_from(stream)) {
@@ -183,11 +190,16 @@
     }
 }
 
+/// # Safety
+///
+/// `ptr` must be a valid pointer to an array of at least `size * nmemb` initialised bytes, which
+/// are not modified before this function returns.
 #[no_mangle]
-extern "C" fn fwrite(ptr: *const c_void, size: usize, nmemb: usize, stream: usize) -> usize {
+unsafe extern "C" fn fwrite(ptr: *const c_void, size: usize, nmemb: usize, stream: usize) -> usize {
     let length = size.saturating_mul(nmemb);
 
-    // SAFETY: Just like libc, we need to assume that `ptr` is valid.
+    // SAFETY: The caller promised that `ptr` is a valid pointer to at least `size * nmemb`
+    // initialised bytes, and `length` is no more than that.
     let bytes = unsafe { slice::from_raw_parts(ptr as *const u8, length) };
 
     if let (Ok(s), Ok(f)) = (str::from_utf8(bytes), CFilePtr::try_from(stream)) {
@@ -203,12 +215,16 @@
     cstr_error(n).as_ptr().cast_mut().cast()
 }
 
+/// # Safety
+///
+/// `s` must be a valid pointer to a NUL-terminated string which is not modified before this
+/// function returns.
 #[no_mangle]
-extern "C" fn perror(s: *const c_char) {
+unsafe extern "C" fn perror(s: *const c_char) {
     let prefix = if s.is_null() {
         None
     } else {
-        // SAFETY: Just like libc, we need to assume that `s` is a valid NULL-terminated string.
+        // SAFETY: The caller promised that `s` is a valid NUL-terminated string.
         let c_str = unsafe { CStr::from_ptr(s) };
         if c_str.is_empty() {
             None
diff --git a/libs/libvmbase/src/fdt/pci.rs b/libs/libvmbase/src/fdt/pci.rs
index ebaa671..fcaa806 100644
--- a/libs/libvmbase/src/fdt/pci.rs
+++ b/libs/libvmbase/src/fdt/pci.rs
@@ -14,40 +14,47 @@
 
 //! Library for working with (VirtIO) PCI devices discovered from a device tree.
 
-use core::{
-    ffi::CStr,
-    fmt::{self, Display, Formatter},
-    ops::Range,
-};
+use core::ops::Range;
 use libfdt::{AddressRange, Fdt, FdtError, FdtNode};
 use log::debug;
-use virtio_drivers::transport::pci::bus::{Cam, PciRoot};
+use thiserror::Error;
+use virtio_drivers::transport::pci::bus::{Cam, ConfigurationAccess, MmioCam, PciRoot};
 
 /// PCI MMIO configuration region size.
 const PCI_CFG_SIZE: usize = 0x100_0000;
 
 /// An error parsing a PCI node from an FDT.
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, Error, PartialEq)]
 pub enum PciError {
     /// Error getting PCI node from FDT.
+    #[error("Error getting PCI node from FDT: {0}")]
     FdtErrorPci(FdtError),
     /// Failed to find PCI bus in FDT.
+    #[error("Failed to find PCI bus in FDT.")]
     FdtNoPci,
     /// Error getting `reg` property from PCI node.
+    #[error("Error getting reg property from PCI node: {0}")]
     FdtErrorReg(FdtError),
     /// PCI node missing `reg` property.
+    #[error("PCI node missing reg property.")]
     FdtMissingReg,
     /// Empty `reg property on PCI node.
+    #[error("Empty reg property on PCI node.")]
     FdtRegEmpty,
     /// PCI `reg` property missing size.
+    #[error("PCI reg property missing size.")]
     FdtRegMissingSize,
     /// PCI CAM size reported by FDT is not what we expected.
+    #[error("FDT says PCI CAM is {0} bytes but we expected {PCI_CFG_SIZE}.")]
     CamWrongSize(usize),
     /// Error getting `ranges` property from PCI node.
+    #[error("Error getting ranges property from PCI node: {0}")]
     FdtErrorRanges(FdtError),
     /// PCI node missing `ranges` property.
+    #[error("PCI node missing ranges property.")]
     FdtMissingRanges,
     /// Bus address is not equal to CPU physical address in `ranges` property.
+    #[error("bus address {bus_address:#018x} != CPU physical address {cpu_physical:#018x}")]
     RangeAddressMismatch {
         /// A bus address from the `ranges` property.
         bus_address: u64,
@@ -55,39 +62,10 @@
         cpu_physical: u64,
     },
     /// No suitable PCI memory range found.
+    #[error("No suitable PCI memory range found.")]
     NoSuitableRange,
 }
 
-impl Display for PciError {
-    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
-        match self {
-            Self::FdtErrorPci(e) => write!(f, "Error getting PCI node from FDT: {}", e),
-            Self::FdtNoPci => write!(f, "Failed to find PCI bus in FDT."),
-            Self::FdtErrorReg(e) => write!(f, "Error getting reg property from PCI node: {}", e),
-            Self::FdtMissingReg => write!(f, "PCI node missing reg property."),
-            Self::FdtRegEmpty => write!(f, "Empty reg property on PCI node."),
-            Self::FdtRegMissingSize => write!(f, "PCI reg property missing size."),
-            Self::CamWrongSize(cam_size) => write!(
-                f,
-                "FDT says PCI CAM is {} bytes but we expected {}.",
-                cam_size, PCI_CFG_SIZE
-            ),
-            Self::FdtErrorRanges(e) => {
-                write!(f, "Error getting ranges property from PCI node: {}", e)
-            }
-            Self::FdtMissingRanges => write!(f, "PCI node missing ranges property."),
-            Self::RangeAddressMismatch { bus_address, cpu_physical } => {
-                write!(
-                    f,
-                    "bus address {:#018x} != CPU physical address {:#018x}",
-                    bus_address, cpu_physical
-                )
-            }
-            Self::NoSuitableRange => write!(f, "No suitable PCI memory range found."),
-        }
-    }
-}
-
 /// Information about the PCI bus parsed from the device tree.
 #[derive(Clone, Debug)]
 pub struct PciInfo {
@@ -116,16 +94,16 @@
     /// To prevent concurrent access, only one `PciRoot` should exist in the program. Thus this
     /// method must only be called once, and there must be no other `PciRoot` constructed using the
     /// same CAM.
-    pub unsafe fn make_pci_root(&self) -> PciRoot {
+    pub unsafe fn make_pci_root(&self) -> PciRoot<impl ConfigurationAccess> {
         // SAFETY: We trust that the FDT gave us a valid MMIO base address for the CAM. The caller
         // guarantees to only call us once, so there are no other references to it.
-        unsafe { PciRoot::new(self.cam_range.start as *mut u8, Cam::MmioCam) }
+        PciRoot::new(unsafe { MmioCam::new(self.cam_range.start as *mut u8, Cam::MmioCam) })
     }
 }
 
 /// Finds an FDT node with compatible=pci-host-cam-generic.
 fn pci_node(fdt: &Fdt) -> Result<FdtNode, PciError> {
-    fdt.compatible_nodes(CStr::from_bytes_with_nul(b"pci-host-cam-generic\0").unwrap())
+    fdt.compatible_nodes(c"pci-host-cam-generic")
         .map_err(PciError::FdtErrorPci)?
         .next()
         .ok_or(PciError::FdtNoPci)
diff --git a/libs/libvmbase/src/layout.rs b/libs/libvmbase/src/layout.rs
index cf3a8fc..4c45eb2 100644
--- a/libs/libvmbase/src/layout.rs
+++ b/libs/libvmbase/src/layout.rs
@@ -22,7 +22,6 @@
 use crate::memory::{max_stack_size, page_4kb_of, PAGE_SIZE};
 use aarch64_paging::paging::VirtualAddress;
 use core::ops::Range;
-use core::ptr::addr_of;
 use static_assertions::const_assert_eq;
 
 /// First address that can't be translated by a level 1 TTBR0_EL1.
@@ -44,9 +43,7 @@
 #[macro_export]
 macro_rules! linker_addr {
     ($symbol:ident) => {{
-        // SAFETY: We're just getting the address of an extern static symbol provided by the linker,
-        // not dereferencing it.
-        let addr = unsafe { addr_of!($crate::linker::$symbol) as usize };
+        let addr = (&raw const $crate::linker::$symbol) as usize;
         VirtualAddress(addr)
     }};
 }
@@ -132,5 +129,5 @@
     // SAFETY: __stack_chk_guard shouldn't have any mutable aliases unless the stack overflows. If
     // it does, then there could be undefined behaviour all over the program, but we want to at
     // least have a chance at catching it.
-    unsafe { addr_of!(__stack_chk_guard).read_volatile() }
+    unsafe { (&raw const __stack_chk_guard).read_volatile() }
 }
diff --git a/libs/libvmbase/src/virtio/pci.rs b/libs/libvmbase/src/virtio/pci.rs
index ec89b6b..c2e3301 100644
--- a/libs/libvmbase/src/virtio/pci.rs
+++ b/libs/libvmbase/src/virtio/pci.rs
@@ -26,7 +26,7 @@
 use virtio_drivers::{
     device::{blk, socket},
     transport::pci::{
-        bus::{BusDeviceIterator, PciRoot},
+        bus::{BusDeviceIterator, ConfigurationAccess, PciRoot},
         virtio_device_type, PciTransport,
     },
     Hal,
@@ -66,7 +66,7 @@
 /// 3. Creates and returns a `PciRoot`.
 ///
 /// This must only be called once and after having switched to the dynamic page tables.
-pub fn initialize(pci_info: PciInfo) -> Result<PciRoot, PciError> {
+pub fn initialize(pci_info: PciInfo) -> Result<PciRoot<impl ConfigurationAccess>, PciError> {
     PCI_INFO.set(Box::new(pci_info.clone())).map_err(|_| PciError::DuplicateInitialization)?;
 
     let cam_start = pci_info.cam_range.start;
@@ -90,21 +90,21 @@
 pub type VirtIOSocket<T> = socket::VirtIOSocket<T, PciTransport>;
 
 /// An iterator that iterates over the PCI transport for each device.
-pub struct PciTransportIterator<'a, T: Hal> {
-    pci_root: &'a mut PciRoot,
-    bus: BusDeviceIterator,
+pub struct PciTransportIterator<'a, T: Hal, C: ConfigurationAccess> {
+    pci_root: &'a mut PciRoot<C>,
+    bus: BusDeviceIterator<C>,
     _hal: PhantomData<T>,
 }
 
-impl<'a, T: Hal> PciTransportIterator<'a, T> {
+impl<'a, T: Hal, C: ConfigurationAccess> PciTransportIterator<'a, T, C> {
     /// Creates a new iterator.
-    pub fn new(pci_root: &'a mut PciRoot) -> Self {
+    pub fn new(pci_root: &'a mut PciRoot<C>) -> Self {
         let bus = pci_root.enumerate_bus(0);
         Self { pci_root, bus, _hal: PhantomData }
     }
 }
 
-impl<'a, T: Hal> Iterator for PciTransportIterator<'a, T> {
+impl<T: Hal, C: ConfigurationAccess> Iterator for PciTransportIterator<'_, T, C> {
     type Item = PciTransport;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -121,7 +121,7 @@
             };
             debug!("  VirtIO {:?}", virtio_type);
 
-            return PciTransport::new::<T>(self.pci_root, device_function).ok();
+            return PciTransport::new::<T, C>(self.pci_root, device_function).ok();
         }
     }
 }
diff --git a/libs/statslog_virtualization/Android.bp b/libs/statslog_virtualization/Android.bp
index 2860e6c..f33a147 100644
--- a/libs/statslog_virtualization/Android.bp
+++ b/libs/statslog_virtualization/Android.bp
@@ -72,4 +72,7 @@
     rustlibs: [
         "libstatslog_virtualization_rust_header",
     ],
+    flags: [
+        "-A clippy::needless-lifetimes",
+    ],
 }
diff --git a/tests/aidl/Android.bp b/tests/aidl/Android.bp
index ed4e8ff..63db488 100644
--- a/tests/aidl/Android.bp
+++ b/tests/aidl/Android.bp
@@ -17,5 +17,8 @@
         cpp: {
             enabled: true,
         },
+        ndk: {
+            min_sdk_version: "UpsideDownCake",
+        },
     },
 }
diff --git a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
index 73e5c5c..6a413d6 100644
--- a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
+++ b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
@@ -97,4 +97,11 @@
      * 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/backcompat_test/src/main.rs b/tests/backcompat_test/src/main.rs
index 4113881..aa69eec 100644
--- a/tests/backcompat_test/src/main.rs
+++ b/tests/backcompat_test/src/main.rs
@@ -152,12 +152,17 @@
         .arg("/chosen/kaslr-seed")
         .arg("--ignore-path-value")
         .arg("/chosen/rng-seed")
+        // TODO: b/391420337 Investigate if bootargs may mutate VM
+        .arg("--ignore-path-value")
+        .arg("/chosen/bootargs")
+        .arg("--ignore-path-value")
+        .arg("/config/kernel-size")
         .arg("--ignore-path-value")
         .arg("/avf/untrusted/instance-id")
         .arg("--ignore-path-value")
-        .arg("/chosen/linuxinitrd-start")
+        .arg("/chosen/linux,initrd-start")
         .arg("--ignore-path-value")
-        .arg("/chosen/linuxinitrd-end")
+        .arg("/chosen/linux,initrd-end")
         .arg("--ignore-path-value")
         .arg("/avf/secretkeeper_public_key")
         .arg("--ignore-path")
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 538d14f..94f7ced 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
@@ -625,6 +625,7 @@
         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 6d7c25e..fa2ff8e 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -39,7 +39,6 @@
     ":microdroid_general_sepolicy.conf",
     ":test.com.android.virt.pem",
     ":test2.com.android.virt.pem",
-    "java/**/goldens/dt_dump_*",
 ]
 
 BINS = [
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index 4f9806a..7864f3f 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -101,6 +101,9 @@
     private static final String INSTANCE_IMG = TEST_ROOT + "instance.img";
     private static final String INSTANCE_ID_FILE = TEST_ROOT + "instance_id";
 
+    private static final String DEBUG_LEVEL_FULL = "full --enable-earlycon";
+    private static final String DEBUG_LEVEL_NONE = "none";
+
     private static final int MIN_MEM_ARM64 = 170;
     private static final int MIN_MEM_X86_64 = 196;
 
@@ -465,7 +468,7 @@
         try {
             microdroid =
                     MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                            .debugLevel("full")
+                            .debugLevel(DEBUG_LEVEL_FULL)
                             .memoryMib(minMemorySize())
                             .cpuTopology("match_host")
                             .protectedVm(true)
@@ -495,7 +498,7 @@
         // Act
         mMicrodroidDevice =
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
+                        .debugLevel(DEBUG_LEVEL_FULL)
                         .memoryMib(minMemorySize())
                         .cpuTopology("match_host")
                         .protectedVm(true)
@@ -644,7 +647,7 @@
 
         mMicrodroidDevice =
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
+                        .debugLevel(DEBUG_LEVEL_FULL)
                         .memoryMib(minMemorySize())
                         .cpuTopology("match_host")
                         .protectedVm(protectedVm)
@@ -751,7 +754,7 @@
                                 VIRT_APEX + "bin/vm",
                                 "run-app",
                                 "--debug",
-                                debuggable ? "full" : "none",
+                                debuggable ? DEBUG_LEVEL_FULL : DEBUG_LEVEL_NONE,
                                 apkPath,
                                 idsigPath,
                                 instanceImgPath));
@@ -871,7 +874,7 @@
         final String configPath = "assets/vm_config_apex.json"; // path inside the APK
         ITestDevice microdroid =
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
+                        .debugLevel(DEBUG_LEVEL_FULL)
                         .memoryMib(minMemorySize())
                         .cpuTopology("match_host")
                         .protectedVm(protectedVm)
@@ -1023,7 +1026,7 @@
         final String configPath = "assets/vm_config.json"; // path inside the APK
         testMicrodroidBootsWithBuilder(
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
+                        .debugLevel(DEBUG_LEVEL_FULL)
                         .memoryMib(minMemorySize())
                         .cpuTopology("match_host")
                         .protectedVm(protectedVm)
@@ -1061,7 +1064,7 @@
         final String configPath = "assets/vm_config.json";
         mMicrodroidDevice =
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
+                        .debugLevel(DEBUG_LEVEL_FULL)
                         .memoryMib(minMemorySize())
                         .cpuTopology("match_host")
                         .protectedVm(protectedVm)
@@ -1175,7 +1178,7 @@
                                 "shell",
                                 VIRT_APEX + "bin/vm",
                                 "run-app",
-                                "--debug full",
+                                "--debug " + DEBUG_LEVEL_FULL,
                                 "--console " + CONSOLE_PATH,
                                 "--payload-binary-name",
                                 "MicrodroidEmptyPayloadJniLib.so",
@@ -1357,7 +1360,7 @@
 
         mMicrodroidDevice =
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
+                        .debugLevel(DEBUG_LEVEL_FULL)
                         .memoryMib(minMemorySize())
                         .cpuTopology("match_host")
                         .protectedVm(protectedVm)
@@ -1403,7 +1406,7 @@
         final String configPath = "assets/vm_config.json";
         mMicrodroidDevice =
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
+                        .debugLevel(DEBUG_LEVEL_FULL)
                         .memoryMib(minMemorySize())
                         .cpuTopology("match_host")
                         .protectedVm(protectedVm)
@@ -1419,138 +1422,6 @@
         }
     }
 
-    @Test
-    @Parameters(method = "osVersions")
-    @TestCaseName("{method}_os_{0}")
-    @CddTest
-    public void microdroidDeviceTreeCompat(String os) throws Exception {
-        assumeArm64Supported();
-        final String configPath = "assets/vm_config.json";
-        // Preconditions
-        assumeKernelSupported(os);
-        int mem_size = 256;
-        assertTrue("Memory size too small", mem_size >= minMemorySize());
-
-        // Start the VM with the dump DT option.
-        mMicrodroidDevice =
-                MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
-                        .memoryMib(mem_size)
-                        .cpuTopology("one_cpu")
-                        .protectedVm(false)
-                        .os(SUPPORTED_OSES.get(os))
-                        .name("test_device_tree")
-                        .dumpDt("/data/local/tmp/dump_dt.dtb")
-                        .build(getAndroidDevice());
-        assertThat(mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT)).isTrue();
-
-        File goldenDt = findTestFile("dt_dump_golden.dts");
-        testGoldenDeviceTree(goldenDt.getAbsolutePath());
-    }
-
-    @Test
-    @Parameters(method = "osVersions")
-    @TestCaseName("{method}_os_{0}")
-    @CddTest
-    public void microdroidProtectedDeviceTreeCompat(String os) throws Exception {
-        assumeArm64Supported();
-        final String configPath = "assets/vm_config.json";
-        // Preconditions
-        assumeKernelSupported(os);
-        assumeVmTypeSupported(os, true);
-        int mem_size = 256;
-        assertTrue("Memory size too small", mem_size >= minMemorySize());
-
-        // Start the VM with the dump DT option.
-        mMicrodroidDevice =
-                MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
-                        .debugLevel("full")
-                        .memoryMib(mem_size)
-                        .cpuTopology("one_cpu")
-                        .protectedVm(true)
-                        .os(SUPPORTED_OSES.get(os))
-                        .name("test_device_tree")
-                        .dumpDt("/data/local/tmp/dump_dt.dtb")
-                        .build(getAndroidDevice());
-        assertThat(mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT)).isTrue();
-
-        File goldenDt = findTestFile("dt_dump_protected_golden.dts");
-        testGoldenDeviceTree(goldenDt.getAbsolutePath());
-    }
-
-    private void testGoldenDeviceTree(String goldenDt) throws Exception {
-        // Pull the device tree to host.
-        TestDevice device = getAndroidDevice();
-        boolean disableRoot = !device.isAdbRoot();
-        device.enableAdbRoot();
-        assumeTrue("adb root is not enabled", device.isAdbRoot());
-
-        // Pull DT from device
-        File dtb_from_device = device.pullFile("/data/local/tmp/dump_dt.dtb");
-        if (disableRoot) {
-            device.disableAdbRoot();
-        }
-
-        File dtc = findTestFile("dtc");
-
-        // Create temp file for Device tree conversion
-        File dt_dump_dts = File.createTempFile("dt_dump", "dts");
-        dt_dump_dts.delete();
-        String dt_dump_dts_path = dt_dump_dts.getAbsolutePath();
-        // Convert DT to text format.
-        CommandResult dtb_to_dts =
-                RunUtil.getDefault()
-                        .runTimedCmd(
-                                3000,
-                                dtc.getAbsolutePath(),
-                                "-I",
-                                "dtb",
-                                "-O",
-                                "dts",
-                                "-qqq",
-                                "-f",
-                                "-s",
-                                "-o",
-                                dt_dump_dts_path,
-                                dtb_from_device.getAbsolutePath());
-        assertTrue(
-                "result convert stderr: " + dtb_to_dts.getStderr(),
-                dtb_to_dts.getStderr().trim().isEmpty());
-        assertTrue(
-                "result convert stdout: " + dtb_to_dts.getStdout(),
-                dtb_to_dts.getStdout().trim().isEmpty());
-
-        // Diff device's DT with the golden DT.
-        CommandResult result_compare =
-                RunUtil.getDefault()
-                        .runTimedCmd(
-                                3000,
-                                "diff",
-                                "-u",
-                                "-w",
-                                "-I",
-                                "kaslr-seed",
-                                "-I",
-                                "instance-id",
-                                "-I",
-                                "rng-seed",
-                                "-I",
-                                "linux,initrd-end",
-                                "-I",
-                                "secretkeeper_public_key",
-                                "-I",
-                                "interrupt-map",
-                                dt_dump_dts_path,
-                                goldenDt);
-
-        assertTrue(
-                "result compare stderr: " + result_compare.getStderr(),
-                result_compare.getStderr().trim().isEmpty());
-        assertTrue(
-                "result compare stdout: " + result_compare.getStdout(),
-                result_compare.getStdout().trim().isEmpty());
-    }
-
     @Before
     public void setUp() throws Exception {
         assumeDeviceIsCapable(getDevice());
diff --git a/tests/hostside/java/com/android/microdroid/test/goldens/dt_dump_golden.dts b/tests/hostside/java/com/android/microdroid/test/goldens/dt_dump_golden.dts
deleted file mode 100644
index 095eb54..0000000
--- a/tests/hostside/java/com/android/microdroid/test/goldens/dt_dump_golden.dts
+++ /dev/null
@@ -1,145 +0,0 @@
-/dts-v1/;
-
-/ {
-        #address-cells = <0x02>;
-        #size-cells = <0x02>;
-        compatible = "linux,dummy-virt";
-        interrupt-parent = <0x01>;
-        name = "reference";
-
-        U6_16550A@2e8 {
-                clock-frequency = <0x1c2000>;
-                compatible = "ns16550a";
-                interrupts = <0x00 0x02 0x01>;
-                reg = <0x00 0x2e8 0x00 0x08>;
-        };
-
-        U6_16550A@2f8 {
-                clock-frequency = <0x1c2000>;
-                compatible = "ns16550a";
-                interrupts = <0x00 0x02 0x01>;
-                reg = <0x00 0x2f8 0x00 0x08>;
-        };
-
-        U6_16550A@3e8 {
-                clock-frequency = <0x1c2000>;
-                compatible = "ns16550a";
-                interrupts = <0x00 0x00 0x01>;
-                reg = <0x00 0x3e8 0x00 0x08>;
-        };
-
-        U6_16550A@3f8 {
-                clock-frequency = <0x1c2000>;
-                compatible = "ns16550a";
-                interrupts = <0x00 0x00 0x01>;
-                reg = <0x00 0x3f8 0x00 0x08>;
-        };
-
-        __symbols__ {
-                intc = "/intc";
-        };
-
-        avf {
-                secretkeeper_public_key = [];
-
-                untrusted {
-                        defer-rollback-protection;
-                        instance-id = <0xf145d4f8 0x15f03952 0x5af249aa 0xfead94d8 0xb9f05746 0xd9163f48 0x7251b67b 0xe117409e 0x2b14dfa5 0xcaa8caf7 0x14176d2d 0xf88cc94b 0xeed4a59d 0x9a2d8fe5 0x5ac590f1 0xbb6c96f5>;
-                };
-        };
-
-        chosen {
-                bootargs = "panic=-1 crashkernel=17M";
-                kaslr-seed = <>;
-                linux,initrd-end = <0x81200360>;
-                linux,initrd-start = <0x81000000>;
-                linux,pci-probe-only = <0x01>;
-                rng-seed = <>;
-                stdout-path = "/U6_16550A@3f8";
-        };
-
-        config {
-                kernel-address = <0x80000000>;
-                kernel-size = <0xc91000>;
-        };
-
-        cpufreq {
-                compatible = "virtual,kvm-cpufreq";
-        };
-
-        cpus {
-                #address-cells = <0x01>;
-                #size-cells = <0x00>;
-
-                cpu@0 {
-                        compatible = "arm,armv8";
-                        device_type = "cpu";
-                        phandle = <0x100>;
-                        reg = <0x00>;
-                };
-        };
-
-        intc {
-                #address-cells = <0x02>;
-                #interrupt-cells = <0x03>;
-                #size-cells = <0x02>;
-                compatible = "arm,gic-v3";
-                interrupt-controller;
-                phandle = <0x01>;
-                reg = <0x00 0x3fff0000 0x00 0x10000 0x00 0x3ffd0000 0x00 0x20000>;
-        };
-
-        memory {
-                device_type = "memory";
-                reg = <0x00 0x80000000 0x00 0x10000000>;
-        };
-
-        pci {
-                #address-cells = <0x03>;
-                #interrupt-cells = <0x01>;
-                #size-cells = <0x02>;
-                bus-range = <0x00 0x00>;
-                compatible = "pci-host-cam-generic";
-                device_type = "pci";
-                dma-coherent;
-                interrupt-map = <0x800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x04 0x04 0x1000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x05 0x04 0x1800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x06 0x04 0x2000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x07 0x04 0x2800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x08 0x04 0x3000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x09 0x04 0x3800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x0a 0x04 0x4000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x0b 0x04 0x4800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x0c 0x04>;
-                interrupt-map-mask = <0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07>;
-                ranges = <0x3000000 0x00 0x70000000 0x00 0x70000000 0x00 0x2000000 0x43000000 0x00 0x90800000 0x00 0x90800000 0xff 0x6f800000>;
-                reg = <0x00 0x72000000 0x00 0x1000000>;
-        };
-
-        pclk@3M {
-                #clock-cells = <0x00>;
-                clock-frequency = <0x2fefd8>;
-                compatible = "fixed-clock";
-                phandle = <0x18>;
-        };
-
-        psci {
-                compatible = "arm,psci-1.0\0arm,psci-0.2";
-                method = "hvc";
-        };
-
-        rtc@2000 {
-                arm,primecell-periphid = <0x41030>;
-                clock-names = "apb_pclk";
-                clocks = <0x18>;
-                compatible = "arm,primecell";
-                interrupts = <0x00 0x01 0x04>;
-                reg = <0x00 0x2000 0x00 0x1000>;
-        };
-
-        timer {
-                always-on;
-                compatible = "arm,armv8-timer";
-                interrupts = <0x01 0x0d 0x108 0x01 0x0e 0x108 0x01 0x0b 0x108 0x01 0x0a 0x108>;
-        };
-
-        vmwdt@3000 {
-                clock-frequency = <0x02>;
-                compatible = "qemu,vcpu-stall-detector";
-                interrupts = <0x01 0x0f 0x101>;
-                reg = <0x00 0x3000 0x00 0x1000>;
-                timeout-sec = <0x0a>;
-        };
-};
diff --git a/tests/hostside/java/com/android/microdroid/test/goldens/dt_dump_protected_golden.dts b/tests/hostside/java/com/android/microdroid/test/goldens/dt_dump_protected_golden.dts
deleted file mode 100644
index f2ebdf9..0000000
--- a/tests/hostside/java/com/android/microdroid/test/goldens/dt_dump_protected_golden.dts
+++ /dev/null
@@ -1,159 +0,0 @@
-/dts-v1/;
-
-/ {
-        #address-cells = <0x02>;
-        #size-cells = <0x02>;
-        compatible = "linux,dummy-virt";
-        interrupt-parent = <0x01>;
-        name = "reference";
-
-        U6_16550A@2e8 {
-                clock-frequency = <0x1c2000>;
-                compatible = "ns16550a";
-                interrupts = <0x00 0x02 0x01>;
-                reg = <0x00 0x2e8 0x00 0x08>;
-        };
-
-        U6_16550A@2f8 {
-                clock-frequency = <0x1c2000>;
-                compatible = "ns16550a";
-                interrupts = <0x00 0x02 0x01>;
-                reg = <0x00 0x2f8 0x00 0x08>;
-        };
-
-        U6_16550A@3e8 {
-                clock-frequency = <0x1c2000>;
-                compatible = "ns16550a";
-                interrupts = <0x00 0x00 0x01>;
-                reg = <0x00 0x3e8 0x00 0x08>;
-        };
-
-        U6_16550A@3f8 {
-                clock-frequency = <0x1c2000>;
-                compatible = "ns16550a";
-                interrupts = <0x00 0x00 0x01>;
-                reg = <0x00 0x3f8 0x00 0x08>;
-        };
-
-        __symbols__ {
-                intc = "/intc";
-        };
-
-        avf {
-                secretkeeper_public_key = [];
-
-                untrusted {
-                        defer-rollback-protection;
-                        instance-id = <0x4d482941 0x27228238 0x11d7b28 0xaeed3076 0x88eb3fcb 0x2b9de301 0x57ff8977 0xaf8c24b6 0x55466af4 0x23beed37 0x2f976083 0xe630eb28 0x1edbc491 0xa8300897 0xeb3e9f76 0x21ea9284>;
-                };
-        };
-
-        chosen {
-                bootargs = "panic=-1 crashkernel=31M";
-                kaslr-seed = <>;
-                linux,initrd-end = <0x81202104>;
-                linux,initrd-start = <0x81000000>;
-                linux,pci-probe-only = <0x01>;
-                rng-seed = <>;
-                stdout-path = "/U6_16550A@3f8";
-        };
-
-        config {
-                kernel-address = <0x80000000>;
-                kernel-size = <0xc91000>;
-        };
-
-        cpufreq {
-                compatible = "virtual,kvm-cpufreq";
-        };
-
-        cpus {
-                #address-cells = <0x01>;
-                #size-cells = <0x00>;
-
-                cpu@0 {
-                        compatible = "arm,armv8";
-                        device_type = "cpu";
-                        phandle = <0x100>;
-                        reg = <0x00>;
-                };
-        };
-
-        intc {
-                #address-cells = <0x02>;
-                #interrupt-cells = <0x03>;
-                #size-cells = <0x02>;
-                compatible = "arm,gic-v3";
-                interrupt-controller;
-                phandle = <0x01>;
-                reg = <0x00 0x3fff0000 0x00 0x10000 0x00 0x3ffd0000 0x00 0x20000>;
-        };
-
-        memory {
-                device_type = "memory";
-                reg = <0x00 0x80000000 0x00 0x10e00000>;
-        };
-
-        pci {
-                #address-cells = <0x03>;
-                #interrupt-cells = <0x01>;
-                #size-cells = <0x02>;
-                bus-range = <0x00 0x00>;
-                compatible = "pci-host-cam-generic";
-                device_type = "pci";
-                dma-coherent;
-                interrupt-map = <0x800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x04 0x04 0x1000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x05 0x04 0x1800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x06 0x04 0x2000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x07 0x04 0x2800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x08 0x04 0x3000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x09 0x04 0x3800 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x0a 0x04 0x4000 0x00 0x00 0x01 0x01 0x00 0x00 0x00 0x0b 0x04>;
-                interrupt-map-mask = <0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07 0xf800 0x00 0x00 0x07>;
-                memory-region = <0x02>;
-                ranges = <0x3000000 0x00 0x70000000 0x00 0x70000000 0x00 0x2000000 0x43000000 0x00 0x91600000 0x00 0x91600000 0xff 0x6ea00000>;
-                reg = <0x00 0x72000000 0x00 0x1000000>;
-        };
-
-        pclk@3M {
-                #clock-cells = <0x00>;
-                clock-frequency = <0x2fefd8>;
-                compatible = "fixed-clock";
-                phandle = <0x18>;
-        };
-
-        psci {
-                compatible = "arm,psci-1.0\0arm,psci-0.2";
-                method = "hvc";
-        };
-
-        reserved-memory {
-                #address-cells = <0x02>;
-                #size-cells = <0x02>;
-                ranges;
-
-                restricted_dma_reserved {
-                        alignment = <0x00 0x1000>;
-                        compatible = "restricted-dma-pool";
-                        phandle = <0x02>;
-                        size = <0x00 0xe00000>;
-                };
-        };
-
-        rtc@2000 {
-                arm,primecell-periphid = <0x41030>;
-                clock-names = "apb_pclk";
-                clocks = <0x18>;
-                compatible = "arm,primecell";
-                interrupts = <0x00 0x01 0x04>;
-                reg = <0x00 0x2000 0x00 0x1000>;
-        };
-
-        timer {
-                always-on;
-                compatible = "arm,armv8-timer";
-                interrupts = <0x01 0x0d 0x108 0x01 0x0e 0x108 0x01 0x0b 0x108 0x01 0x0a 0x108>;
-        };
-
-        vmwdt@3000 {
-                clock-frequency = <0x02>;
-                compatible = "qemu,vcpu-stall-detector";
-                interrupts = <0x01 0x0f 0x101>;
-                reg = <0x00 0x3000 0x00 0x1000>;
-                timeout-sec = <0x0a>;
-        };
-};
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 d0e045b..99300e2 100644
--- a/tests/testapk/Android.bp
+++ b/tests/testapk/Android.bp
@@ -173,6 +173,8 @@
         "liblog",
         "libprotobuf-cpp-lite-ndk",
     ],
+    // We've added support for updatable payloads in Android U.
+    min_sdk_version: "UpsideDownCake",
 }
 
 cc_library_shared {
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 193e9d3..3ece140 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -32,7 +32,6 @@
 import static com.google.common.truth.TruthJUnit.assume;
 
 import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
@@ -1868,22 +1867,14 @@
         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
+    @CddTest
     public void rollbackProtectedDataOfPayload() throws Exception {
         assumeSupportedDevice();
         // Rollback protected data is only possible if Updatable VMs is supported -
         // which implies Secretkeeper support.
-        ensureUpdatableVmSupported();
+        assumeTrue("Missing Updatable VM support", isUpdatableVmSupported());
+
         byte[] value1 = new byte[32];
         Arrays.fill(value1, (byte) 0xcc);
         byte[] value2 = new byte[32];
@@ -1996,6 +1987,49 @@
 
     @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 {
         assumeSupportedDevice();
 
@@ -2485,25 +2519,7 @@
     }
 
     @Test
-    public void kernelVersionRequirement() throws Exception {
-        assumeVsrCompliant();
-        int firstApiLevel = SystemProperties.getInt("ro.product.first_api_level", 0);
-        assume().withMessage("Skip on devices launched before Android 14 (API level 34)")
-                .that(firstApiLevel)
-                .isAtLeast(34);
-
-        String[] tokens = KERNEL_VERSION.split("\\.");
-        int major = Integer.parseInt(tokens[0]);
-        int minor = Integer.parseInt(tokens[1]);
-
-        // Check kernel version >= 5.15
-        assertTrue(major >= 5);
-        if (major == 5) {
-            assertTrue(minor >= 15);
-        }
-    }
-
-    @Test
+    @CddTest
     public void createAndRunRustVm() throws Exception {
         // This test is here mostly to exercise the Rust wrapper around the VM Payload API.
         // We're testing the same functionality as in other tests, the only difference is
@@ -2707,6 +2723,7 @@
     }
 
     @Test
+    @GmsTest(requirements = {"GMS-3-7.1-001.002"})
     public void pageSize() throws Exception {
         assumeSupportedDevice();
 
diff --git a/tests/testapk/src/native/testbinary.cpp b/tests/testapk/src/native/testbinary.cpp
index 83b6d23..2ab73a4 100644
--- a/tests/testapk/src/native/testbinary.cpp
+++ b/tests/testapk/src/native/testbinary.cpp
@@ -348,20 +348,40 @@
         }
 
         ScopedAStatus insecurelyReadPayloadRpData(std::array<uint8_t, 32>* out) override {
-            int32_t ret = AVmPayload_readRollbackProtectedSecret(out->data(), 32);
-            if (ret != 32) {
-                return ScopedAStatus::fromServiceSpecificError(ret);
+            if (__builtin_available(android 36, *)) {
+                int32_t ret = AVmPayload_readRollbackProtectedSecret(out->data(), 32);
+                if (ret != 32) {
+                    return ScopedAStatus::fromServiceSpecificError(ret);
+                }
+                return ScopedAStatus::ok();
+            } else {
+                return ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC,
+                                                                   "not available before SDK 36");
             }
-            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);
+            if (__builtin_available(android 36, *)) {
+                int32_t ret = AVmPayload_writeRollbackProtectedSecret(inputData.data(), 32);
+                if (ret != 32) {
+                    return ScopedAStatus::fromServiceSpecificError(ret);
+                }
+                return ScopedAStatus::ok();
+            } else {
+                return ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC,
+                                                                   "not available before SDK 36");
             }
-            return ScopedAStatus::ok();
+        }
+
+        ScopedAStatus isNewInstance(bool* is_new_instance_out) override {
+            if (__builtin_available(android 36, *)) {
+                *is_new_instance_out = AVmPayload_isNewInstance();
+                return ScopedAStatus::ok();
+            } else {
+                return ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC,
+                                                                   "not available before SDK 36");
+            }
         }
 
         ScopedAStatus quit() override { exit(0); }
diff --git a/tests/testapk/src/native/testbinary.rs b/tests/testapk/src/native/testbinary.rs
index dee3b8e..c9d46b8 100644
--- a/tests/testapk/src/native/testbinary.rs
+++ b/tests/testapk/src/native/testbinary.rs
@@ -132,6 +132,9 @@
     fn insecurelyWritePayloadRpData(&self, _: &[u8; 32]) -> BinderResult<()> {
         unimplemented()
     }
+    fn isNewInstance(&self) -> BinderResult<bool> {
+        unimplemented()
+    }
 }
 
 fn unimplemented<T>() -> BinderResult<T> {
diff --git a/tests/vmshareapp/Android.bp b/tests/vmshareapp/Android.bp
index 5f6dc57..86c48f6 100644
--- a/tests/vmshareapp/Android.bp
+++ b/tests/vmshareapp/Android.bp
@@ -13,4 +13,8 @@
         "MicrodroidPayloadInOtherAppNativeLib",
     ],
     min_sdk_version: "34",
+    sdk_version: "system_current",
+    // Ideally we should set something "latest finalized sdk version" here.
+    // However, soong doesn't seem to provide such functionality.
+    target_sdk_version: "VanillaIceCream",
 }
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 4465c5e..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
@@ -286,5 +286,10 @@
         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" />
diff --git a/tests/vts/src/vts_libavf_test.rs b/tests/vts/src/vts_libavf_test.rs
index e30c175..dc37aad 100644
--- a/tests/vts/src/vts_libavf_test.rs
+++ b/tests/vts/src/vts_libavf_test.rs
@@ -16,7 +16,6 @@
 
 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;
@@ -87,10 +86,7 @@
 
     // SAFETY: config is the only reference to a valid object
     unsafe {
-        AVirtualMachineRawConfig_setName(
-            config,
-            CStr::from_bytes_with_nul(b"vts_libavf_test_rialto\0").unwrap().as_ptr(),
-        );
+        AVirtualMachineRawConfig_setName(config, c"vts_libavf_test_rialto".as_ptr());
         AVirtualMachineRawConfig_setKernel(config, kernel_fd);
         AVirtualMachineRawConfig_setProtectedVm(config, protected_vm);
         AVirtualMachineRawConfig_setMemoryMiB(config, VM_MEMORY_MB);