Merge "Remove client.p12" into main
diff --git a/android/TerminalApp/AndroidManifest.xml b/android/TerminalApp/AndroidManifest.xml
index dad07ee..a9d6e9d 100644
--- a/android/TerminalApp/AndroidManifest.xml
+++ b/android/TerminalApp/AndroidManifest.xml
@@ -83,10 +83,6 @@
             <property
                 android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
                 android:value="Run VM instances" />
-            <intent-filter>
-                <action android:name="android.virtualization.START_VM_LAUNCHER_SERVICE" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
         </service>
     </application>
 
diff --git a/android/TerminalApp/aidl/com/android/virtualization/terminal/IInstallerService.aidl b/android/TerminalApp/aidl/com/android/virtualization/terminal/IInstallerService.aidl
index daf1fa4..1ae1951 100644
--- a/android/TerminalApp/aidl/com/android/virtualization/terminal/IInstallerService.aidl
+++ b/android/TerminalApp/aidl/com/android/virtualization/terminal/IInstallerService.aidl
@@ -19,7 +19,7 @@
 import com.android.virtualization.terminal.IInstallProgressListener;
 
 interface IInstallerService {
-    void requestInstall();
+    void requestInstall(boolean isWifiOnly);
     void setProgressListener(in IInstallProgressListener listener);
 
     boolean isInstalling();
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java b/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java
index 01d2afa..fa5c382 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/CertificateUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.virtualization.terminal;
 
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
 import android.content.Context;
 import android.security.keystore.KeyGenParameterSpec;
 import android.security.keystore.KeyProperties;
@@ -37,8 +39,6 @@
 import java.security.cert.X509Certificate;
 
 public class CertificateUtils {
-    private static final String TAG = "CertificateUtils";
-
     private static final String ALIAS = "ttyd";
 
     public static KeyStore.PrivateKeyEntry createOrGetKey() {
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java b/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
index e1342e9..cec1b7a 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ConfigJson.java
@@ -35,8 +35,16 @@
 import com.google.gson.Gson;
 import com.google.gson.annotations.SerializedName;
 
+import java.io.BufferedReader;
 import java.io.FileReader;
+import java.io.IOException;
+import java.io.PipedReader;
+import java.io.PipedWriter;
+import java.io.Reader;
+import java.nio.file.Path;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Objects;
 
 /** This class and its inner classes model vm_config.json. */
@@ -69,14 +77,54 @@
     private GpuJson gpu;
 
     /** Parses JSON file at jsonPath */
-    static ConfigJson from(String jsonPath) {
-        try (FileReader r = new FileReader(jsonPath)) {
+    static ConfigJson from(Context context, Path jsonPath) {
+        try (FileReader fileReader = new FileReader(jsonPath.toFile());
+                Reader r = replaceKeywords(fileReader, context)) {
             return new Gson().fromJson(r, ConfigJson.class);
         } catch (Exception e) {
             throw new RuntimeException("Failed to parse " + jsonPath, e);
         }
     }
 
+    private static Reader replaceKeywords(Reader r, Context context) throws IOException {
+        PipedWriter pipeIn = new PipedWriter();
+        PipedReader pipeOut = new PipedReader();
+        pipeOut.connect(pipeIn);
+
+        Map<String, String> rules = new HashMap<>();
+        rules.put("\\$PAYLOAD_DIR", InstallUtils.getInternalStorageDir(context).toString());
+        rules.put("\\$USER_ID", String.valueOf(context.getUserId()));
+        rules.put("\\$PACKAGE_NAME", context.getPackageName());
+        String appDataDir = context.getDataDir().toString();
+        // TODO: remove this hack
+        if (context.getUserId() == 0) {
+            appDataDir = "/data/data/" + context.getPackageName();
+        }
+        rules.put("\\$APP_DATA_DIR", appDataDir);
+
+        try (BufferedReader br = new BufferedReader(r)) {
+            br.lines()
+                    .map(
+                            line -> {
+                                for (Map.Entry<String, String> rule : rules.entrySet()) {
+                                    line = line.replaceAll(rule.getKey(), rule.getValue());
+                                }
+                                return line;
+                            })
+                    .forEach(
+                            line -> {
+                                try {
+                                    pipeIn.write(line);
+                                    pipeIn.write('\n');
+                                } catch (IOException e) {
+                                    // this cannot happen as it is connected to a pipe.
+                                    throw new RuntimeException(e);
+                                }
+                            });
+        }
+        return pipeOut;
+    }
+
     private int getCpuTopology() {
         switch (cpu_topology) {
             case "one_cpu":
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/DebianServiceImpl.java b/android/TerminalApp/java/com/android/virtualization/terminal/DebianServiceImpl.java
index 0b65cf6..93b0b0c 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/DebianServiceImpl.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/DebianServiceImpl.java
@@ -16,6 +16,8 @@
 
 package com.android.virtualization.terminal;
 
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.util.Log;
@@ -37,7 +39,6 @@
 import java.util.Set;
 
 final class DebianServiceImpl extends DebianServiceGrpc.DebianServiceImplBase {
-    public static final String TAG = "DebianService";
     private static final String PREFERENCE_FILE_KEY =
             "com.android.virtualization.terminal.PREFERENCE_FILE_KEY";
     private static final String PREFERENCE_FORWARDING_PORTS = "PREFERENCE_FORWARDING_PORTS";
@@ -46,6 +47,8 @@
 
     private final Context mContext;
     private final SharedPreferences mSharedPref;
+    private final String mPreferenceForwardingPorts;
+    private final String mPreferenceForwardingPortIsEnabled;
     private SharedPreferences.OnSharedPreferenceChangeListener mPortForwardingListener;
     private final DebianServiceCallback mCallback;
 
@@ -57,28 +60,35 @@
         super();
         mCallback = callback;
         mContext = context;
-        mSharedPref = mContext.getSharedPreferences(PREFERENCE_FILE_KEY, Context.MODE_PRIVATE);
+        mSharedPref =
+                mContext.getSharedPreferences(
+                        mContext.getString(R.string.preference_file_key), Context.MODE_PRIVATE);
+        mPreferenceForwardingPorts = mContext.getString(R.string.preference_forwarding_ports);
+        mPreferenceForwardingPortIsEnabled =
+                mContext.getString(R.string.preference_forwarding_port_is_enabled);
     }
 
     @Override
     public void reportVmActivePorts(
             ReportVmActivePortsRequest request,
             StreamObserver<ReportVmActivePortsResponse> responseObserver) {
-        Log.d(DebianServiceImpl.TAG, "reportVmActivePorts: " + request.toString());
+        Log.d(TAG, "reportVmActivePorts: " + request.toString());
 
+        Set<String> prevPorts =
+                mSharedPref.getStringSet(mPreferenceForwardingPorts, Collections.emptySet());
         SharedPreferences.Editor editor = mSharedPref.edit();
         Set<String> ports = new HashSet<>();
         for (int port : request.getPortsList()) {
             ports.add(Integer.toString(port));
             if (!mSharedPref.contains(
-                    PREFERENCE_FORWARDING_PORT_IS_ENABLED_PREFIX + Integer.toString(port))) {
+                    mPreferenceForwardingPortIsEnabled + Integer.toString(port))) {
                 editor.putBoolean(
-                        PREFERENCE_FORWARDING_PORT_IS_ENABLED_PREFIX + Integer.toString(port),
-                        false);
+                        mPreferenceForwardingPortIsEnabled + Integer.toString(port), false);
             }
         }
-        editor.putStringSet(PREFERENCE_FORWARDING_PORTS, ports);
+        editor.putStringSet(mPreferenceForwardingPorts, ports);
         editor.apply();
+        mCallback.onActivePortsChanged(prevPorts, ports);
 
         ReportVmActivePortsResponse reply =
                 ReportVmActivePortsResponse.newBuilder().setSuccess(true).build();
@@ -89,7 +99,7 @@
     @Override
     public void reportVmIpAddr(
             IpAddr request, StreamObserver<ReportVmIpAddrResponse> responseObserver) {
-        Log.d(DebianServiceImpl.TAG, "reportVmIpAddr: " + request.toString());
+        Log.d(TAG, "reportVmIpAddr: " + request.toString());
         mCallback.onIpAddressAvailable(request.getAddr());
         ReportVmIpAddrResponse reply = ReportVmIpAddrResponse.newBuilder().setSuccess(true).build();
         responseObserver.onNext(reply);
@@ -99,14 +109,14 @@
     @Override
     public void openForwardingRequestQueue(
             QueueOpeningRequest request, StreamObserver<ForwardingRequestItem> responseObserver) {
-        Log.d(DebianServiceImpl.TAG, "OpenForwardingRequestQueue");
+        Log.d(TAG, "OpenForwardingRequestQueue");
         mPortForwardingListener =
                 new SharedPreferences.OnSharedPreferenceChangeListener() {
                     @Override
                     public void onSharedPreferenceChanged(
                             SharedPreferences sharedPreferences, String key) {
-                        if (key.startsWith(PREFERENCE_FORWARDING_PORT_IS_ENABLED_PREFIX)
-                                || key.equals(PREFERENCE_FORWARDING_PORTS)) {
+                        if (key.startsWith(mPreferenceForwardingPortIsEnabled)
+                                || key.equals(mPreferenceForwardingPorts)) {
                             updateListeningPorts();
                         }
                     }
@@ -140,7 +150,7 @@
     private static native void terminateForwarderHost();
 
     void killForwarderHost() {
-        Log.d(DebianServiceImpl.TAG, "Stopping port forwarding");
+        Log.d(TAG, "Stopping port forwarding");
         if (mPortForwardingListener != null) {
             mSharedPref.unregisterOnSharedPreferenceChangeListener(mPortForwardingListener);
             terminateForwarderHost();
@@ -152,13 +162,12 @@
     private void updateListeningPorts() {
         updateListeningPorts(
                 mSharedPref
-                        .getStringSet(PREFERENCE_FORWARDING_PORTS, Collections.emptySet())
+                        .getStringSet(mPreferenceForwardingPorts, Collections.emptySet())
                         .stream()
                         .filter(
                                 port ->
                                         mSharedPref.getBoolean(
-                                                PREFERENCE_FORWARDING_PORT_IS_ENABLED_PREFIX + port,
-                                                false))
+                                                mPreferenceForwardingPortIsEnabled + port, false))
                         .map(Integer::valueOf)
                         .mapToInt(Integer::intValue)
                         .toArray());
@@ -166,5 +175,7 @@
 
     protected interface DebianServiceCallback {
         void onIpAddressAvailable(String ipAddr);
+
+        void onActivePortsChanged(Set<String> oldPorts, Set<String> newPorts);
     }
 }
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallUtils.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallUtils.java
index b17e636..1b6da6c 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallUtils.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallUtils.java
@@ -15,6 +15,8 @@
  */
 package com.android.virtualization.terminal;
 
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
 import android.content.Context;
 import android.os.Environment;
 import android.os.FileUtils;
@@ -33,13 +35,8 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
 
 public class InstallUtils {
-    private static final String TAG = InstallUtils.class.getSimpleName();
-
     private static final String VM_CONFIG_FILENAME = "vm_config.json";
     private static final String COMPRESSED_PAYLOAD_FILENAME = "images.tar.gz";
     private static final String ROOTFS_FILENAME = "root_part";
@@ -47,8 +44,8 @@
     private static final String INSTALLATION_COMPLETED_FILENAME = "completed";
     private static final String PAYLOAD_DIR = "linux";
 
-    public static String getVmConfigPath(Context context) {
-        return getInternalStorageDir(context).toPath().resolve(VM_CONFIG_FILENAME).toString();
+    public static Path getVmConfigPath(Context context) {
+        return getInternalStorageDir(context).resolve(VM_CONFIG_FILENAME);
     }
 
     public static boolean isImageInstalled(Context context) {
@@ -57,15 +54,16 @@
 
     public static void backupRootFs(Context context) throws IOException {
         Files.move(
-                getRootfsFile(context).toPath(),
-                getBackupFile(context).toPath(),
+                getRootfsFile(context),
+                getBackupFile(context),
                 StandardCopyOption.REPLACE_EXISTING);
     }
 
     public static boolean createInstalledMarker(Context context) {
         try {
-            File file = new File(getInstallationCompletedPath(context).toString());
-            return file.createNewFile();
+            Path path = getInstallationCompletedPath(context);
+            Files.createFile(path);
+            return true;
         } catch (IOException e) {
             Log.e(TAG, "Failed to mark install completed", e);
             return false;
@@ -74,7 +72,7 @@
 
     @VisibleForTesting
     public static void deleteInstallation(Context context) {
-        FileUtils.deleteContentsAndDir(getInternalStorageDir(context));
+        FileUtils.deleteContentsAndDir(getInternalStorageDir(context).toFile());
     }
 
     private static Path getPayloadPath() {
@@ -91,16 +89,16 @@
         return Files.exists(getPayloadPath());
     }
 
-    public static File getInternalStorageDir(Context context) {
-        return new File(context.getFilesDir(), PAYLOAD_DIR);
+    public static Path getInternalStorageDir(Context context) {
+        return context.getFilesDir().toPath().resolve(PAYLOAD_DIR);
     }
 
-    public static File getBackupFile(Context context) {
-        return new File(context.getFilesDir(), BACKUP_FILENAME);
+    public static Path getBackupFile(Context context) {
+        return context.getFilesDir().toPath().resolve(BACKUP_FILENAME);
     }
 
     private static Path getInstallationCompletedPath(Context context) {
-        return getInternalStorageDir(context).toPath().resolve(INSTALLATION_COMPLETED_FILENAME);
+        return getInternalStorageDir(context).resolve(INSTALLATION_COMPLETED_FILENAME);
     }
 
     public static boolean installImageFromExternalStorage(Context context) {
@@ -128,15 +126,6 @@
             Log.e(TAG, "installation failed", e);
             return false;
         }
-        if (!resolvePathInVmConfig(context)) {
-            Log.d(TAG, "resolving path failed");
-            try {
-                Files.deleteIfExists(Path.of(getVmConfigPath(context)));
-            } catch (IOException e) {
-                return false;
-            }
-            return false;
-        }
 
         // remove payload if installation is done.
         try {
@@ -149,46 +138,12 @@
         return createInstalledMarker(context);
     }
 
-    private static Function<String, String> getReplacer(Context context) {
-        Map<String, String> rules = new HashMap<>();
-        rules.put("\\$PAYLOAD_DIR", new File(context.getFilesDir(), PAYLOAD_DIR).toString());
-        rules.put("\\$USER_ID", String.valueOf(context.getUserId()));
-        rules.put("\\$PACKAGE_NAME", context.getPackageName());
-        String appDataDir = context.getDataDir().toString();
-        // TODO: remove this hack
-        if (context.getUserId() == 0) {
-            appDataDir = "/data/data/" + context.getPackageName();
-        }
-        rules.put("\\$APP_DATA_DIR", appDataDir);
-        return (s) -> {
-            for (Map.Entry<String, String> rule : rules.entrySet()) {
-                s = s.replaceAll(rule.getKey(), rule.getValue());
-            }
-            return s;
-        };
-    }
-
-    public static boolean resolvePathInVmConfig(Context context) {
-        try {
-            String replacedVmConfig =
-                    String.join(
-                            "\n",
-                            Files.readAllLines(Path.of(getVmConfigPath(context))).stream()
-                                    .map(getReplacer(context))
-                                    .toList());
-            Files.write(Path.of(getVmConfigPath(context)), replacedVmConfig.getBytes());
-            return true;
-        } catch (IOException e) {
-            return false;
-        }
-    }
-
-    public static File getRootfsFile(Context context) throws FileNotFoundException {
-        File file = new File(getInternalStorageDir(context), ROOTFS_FILENAME);
-        if (!file.exists()) {
-            Log.d(TAG, file.getAbsolutePath() + " - file not found");
+    public static Path getRootfsFile(Context context) throws FileNotFoundException {
+        Path path = getInternalStorageDir(context).resolve(ROOTFS_FILENAME);
+        if (!Files.exists(path)) {
+            Log.d(TAG, path.toString() + " - file not found");
             throw new FileNotFoundException("File not found: " + ROOTFS_FILENAME);
         }
-        return file;
+        return path;
     }
 }
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
index 4d8c00a..52ef3d4 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.virtualization.terminal;
 
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
 import android.annotation.MainThread;
 import android.content.ComponentName;
 import android.content.Context;
@@ -40,14 +42,10 @@
 import com.google.android.material.snackbar.Snackbar;
 
 import java.lang.ref.WeakReference;
-import java.util.concurrent.ExecutorService;
 
 public class InstallerActivity extends BaseActivity {
-    private static final String TAG = "LinuxInstaller";
-
     private static final long ESTIMATED_IMG_SIZE_BYTES = FileUtils.parseSize("550MB");
 
-    private ExecutorService mExecutorService;
     private CheckBox mWaitForWifiCheckbox;
     private TextView mInstallButton;
 
@@ -83,7 +81,7 @@
         Intent intent = new Intent(this, InstallerService.class);
         mInstallerServiceConnection = new InstallerServiceConnection(this);
         if (!bindService(intent, mInstallerServiceConnection, Context.BIND_AUTO_CREATE)) {
-            handleCriticalError(new Exception("Failed to connect to installer service"));
+            handleInternalError(new Exception("Failed to connect to installer service"));
         }
     }
 
@@ -92,11 +90,7 @@
         super.onResume();
 
         if (Build.isDebuggable() && InstallUtils.payloadFromExternalStorageExists()) {
-            Snackbar.make(
-                            findViewById(android.R.id.content),
-                            "Auto installing",
-                            Snackbar.LENGTH_LONG)
-                    .show();
+            showSnackbar("Auto installing", Snackbar.LENGTH_LONG);
             requestInstall();
         }
     }
@@ -125,13 +119,17 @@
         return mInstallCompleted.block(timeoutMillis);
     }
 
-    public void handleCriticalError(Exception e) {
+    private void showSnackbar(String message, int length) {
+        Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), message, length);
+        snackbar.setAnchorView(mWaitForWifiCheckbox);
+        snackbar.show();
+    }
+
+    public void handleInternalError(Exception e) {
         if (Build.isDebuggable()) {
-            Snackbar.make(
-                            findViewById(android.R.id.content),
-                            e.getMessage() + ". File a bugreport to go/ferrochrome-bug",
-                            Snackbar.LENGTH_INDEFINITE)
-                    .show();
+            showSnackbar(
+                    e.getMessage() + ". File a bugreport to go/ferrochrome-bug",
+                    Snackbar.LENGTH_INDEFINITE);
         }
         Log.e(TAG, "Internal error", e);
         finishWithResult(RESULT_CANCELED);
@@ -168,9 +166,9 @@
 
         if (mService != null) {
             try {
-                mService.requestInstall();
+                mService.requestInstall(mWaitForWifiCheckbox.isChecked());
             } catch (RemoteException e) {
-                handleCriticalError(e);
+                handleInternalError(e);
             }
         } else {
             Log.d(TAG, "requestInstall() is called, but not yet connected");
@@ -195,21 +193,18 @@
                 setInstallEnabled(false);
             }
         } catch (RemoteException e) {
-            handleCriticalError(e);
+            handleInternalError(e);
         }
     }
 
     @MainThread
     public void handleInstallerServiceDisconnected() {
-        handleCriticalError(new Exception("InstallerService is destroyed while in use"));
+        handleInternalError(new Exception("InstallerService is destroyed while in use"));
     }
 
     @MainThread
-    private void handleError(String displayText) {
-        if (Build.isDebuggable()) {
-            Snackbar.make(findViewById(android.R.id.content), displayText, Snackbar.LENGTH_LONG)
-                    .show();
-        }
+    private void handleInstallError(String displayText) {
+        showSnackbar(displayText, Snackbar.LENGTH_LONG);
         setInstallEnabled(true);
     }
 
@@ -249,7 +244,7 @@
                             return;
                         }
 
-                        activity.handleError(displayText);
+                        activity.handleInstallError(displayText);
                     });
         }
     }
@@ -270,7 +265,7 @@
                 return;
             }
             if (service == null) {
-                activity.handleCriticalError(new Exception("service shouldn't be null"));
+                activity.handleInternalError(new Exception("service shouldn't be null"));
             }
 
             activity.mService = IInstallerService.Stub.asInterface(service);
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
index f839c64..4b2e640 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/InstallerService.java
@@ -16,16 +16,22 @@
 
 package com.android.virtualization.terminal;
 
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Intent;
 import android.content.pm.ServiceInfo;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.os.Build;
 import android.os.IBinder;
 import android.os.SELinux;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.GuardedBy;
@@ -37,7 +43,9 @@
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.ref.WeakReference;
+import java.net.SocketException;
 import java.net.URL;
 import java.net.UnknownHostException;
 import java.nio.file.Files;
@@ -49,8 +57,6 @@
 import java.util.concurrent.Executors;
 
 public class InstallerService extends Service {
-    private static final String TAG = "InstallerService";
-
     private static final int NOTIFICATION_ID = 1313; // any unique number among notifications
 
     private static final String IMAGE_URL =
@@ -69,9 +75,14 @@
     private boolean mIsInstalling;
 
     @GuardedBy("mLock")
+    private boolean mHasWifi;
+
+    @GuardedBy("mLock")
     private IInstallProgressListener mListener;
 
     private ExecutorService mExecutorService;
+    private ConnectivityManager mConnectivityManager;
+    private MyNetworkCallback mNetworkCallback;
 
     @Override
     public void onCreate() {
@@ -91,6 +102,18 @@
                         .build();
 
         mExecutorService = Executors.newSingleThreadExecutor();
+
+        mConnectivityManager = getSystemService(ConnectivityManager.class);
+        Network defaultNetwork = mConnectivityManager.getBoundNetworkForProcess();
+        if (defaultNetwork != null) {
+            NetworkCapabilities capability =
+                    mConnectivityManager.getNetworkCapabilities(defaultNetwork);
+            if (capability != null) {
+                mHasWifi = capability.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+            }
+        }
+        mNetworkCallback = new MyNetworkCallback();
+        mConnectivityManager.registerDefaultNetworkCallback(mNetworkCallback);
     }
 
     @Nullable
@@ -116,9 +139,10 @@
         if (mExecutorService != null) {
             mExecutorService.shutdown();
         }
+        mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
     }
 
-    private void requestInstall() {
+    private void requestInstall(boolean isWifiOnly) {
         synchronized (mLock) {
             if (mIsInstalling) {
                 Log.i(TAG, "already installing..");
@@ -137,8 +161,7 @@
 
         mExecutorService.execute(
                 () -> {
-                    // TODO(b/374015561): Provide progress update
-                    boolean success = downloadFromSdcard() || downloadFromUrl();
+                    boolean success = downloadFromSdcard() || downloadFromUrl(isWifiOnly);
                     if (success) {
                         reLabelImagesSELinuxContext();
                     }
@@ -154,7 +177,7 @@
     }
 
     private void reLabelImagesSELinuxContext() {
-        File payloadFolder = InstallUtils.getInternalStorageDir(this);
+        File payloadFolder = InstallUtils.getInternalStorageDir(this).toFile();
 
         // The context should be u:object_r:privapp_data_file:s0:c35,c257,c512,c768
         // and we want to get s0:c35,c257,c512,c768 part
@@ -187,17 +210,33 @@
         return false;
     }
 
+    private boolean checkForWifiOnly(boolean isWifiOnly) {
+        if (!isWifiOnly) {
+            return true;
+        }
+        synchronized (mLock) {
+            return mHasWifi;
+        }
+    }
+
     // TODO(b/374015561): Support pause/resume download
-    // TODO(b/374015561): Wait for Wi-Fi on metered network if requested.
-    private boolean downloadFromUrl() {
+    private boolean downloadFromUrl(boolean isWifiOnly) {
         Log.i(TAG, "trying to download from " + IMAGE_URL);
 
+        if (!checkForWifiOnly(isWifiOnly)) {
+            Log.e(TAG, "Install isn't started because Wifi isn't available");
+            notifyError(getString(R.string.installer_error_no_wifi));
+            return false;
+        }
+
         try (BufferedInputStream inputStream =
                         new BufferedInputStream(new URL(IMAGE_URL).openStream());
+                WifiCheckInputStream wifiInputStream =
+                        new WifiCheckInputStream(inputStream, isWifiOnly);
                 TarArchiveInputStream tar =
-                        new TarArchiveInputStream(new GzipCompressorInputStream(inputStream))) {
+                        new TarArchiveInputStream(new GzipCompressorInputStream(wifiInputStream))) {
             ArchiveEntry entry;
-            Path baseDir = InstallUtils.getInternalStorageDir(this).toPath();
+            Path baseDir = InstallUtils.getInternalStorageDir(this);
             Files.createDirectories(baseDir);
             while ((entry = tar.getNextEntry()) != null) {
                 Path extractTo = baseDir.resolve(entry.getName());
@@ -207,23 +246,21 @@
                     Files.copy(tar, extractTo, StandardCopyOption.REPLACE_EXISTING);
                 }
             }
-        } catch (UnknownHostException e) {
+        } catch (WifiCheckInputStream.NoWifiException e) {
+            Log.e(TAG, "Install failed because of Wi-Fi is gone");
+            notifyError(getString(R.string.installer_error_no_wifi));
+            return false;
+        } catch (UnknownHostException | SocketException e) {
             // Log.e() doesn't print stack trace for UnknownHostException
-            Log.e(TAG, "Install failed UnknownHostException: " + e.getMessage());
-            notifyError(getString(R.string.installer_install_network_error_message));
+            Log.e(TAG, "Install failed: " + e.getMessage(), e);
+            notifyError(getString(R.string.installer_error_network));
             return false;
         } catch (IOException e) {
-            // TODO(b/374015561): Provide more finer grained error message
             Log.e(TAG, "Installation failed", e);
             notifyError(getString(R.string.installer_error_unknown));
             return false;
         }
 
-        if (!InstallUtils.resolvePathInVmConfig(this)) {
-            // TODO(b/374015561): Provide more finer grained error message
-            notifyError(getString(R.string.installer_error_unknown));
-            return false;
-        }
         return InstallUtils.createInstalledMarker(this);
     }
 
@@ -271,10 +308,10 @@
         }
 
         @Override
-        public void requestInstall() {
+        public void requestInstall(boolean isWifiOnly) {
             InstallerService service = ensureServiceConnected();
             synchronized (service.mLock) {
-                service.requestInstall();
+                service.requestInstall(isWifiOnly);
             }
         }
 
@@ -302,4 +339,57 @@
             }
         }
     }
+
+    private final class WifiCheckInputStream extends InputStream {
+        private static final int READ_BYTES = 1024;
+
+        private final InputStream mInputStream;
+        private final boolean mIsWifiOnly;
+
+        public WifiCheckInputStream(InputStream is, boolean isWifiOnly) {
+            super();
+            mInputStream = is;
+            mIsWifiOnly = isWifiOnly;
+        }
+
+        @Override
+        public int read(byte[] buf, int offset, int numToRead) throws IOException {
+            int totalRead = 0;
+            while (numToRead > 0) {
+                if (!checkForWifiOnly(mIsWifiOnly)) {
+                    throw new NoWifiException();
+                }
+                int read =
+                        mInputStream.read(buf, offset + totalRead, Math.min(READ_BYTES, numToRead));
+                if (read <= 0) {
+                    break;
+                }
+                totalRead += read;
+                numToRead -= read;
+            }
+            return totalRead;
+        }
+
+        @Override
+        public int read() throws IOException {
+            if (!checkForWifiOnly(mIsWifiOnly)) {
+                throw new NoWifiException();
+            }
+            return mInputStream.read();
+        }
+
+        private static final class NoWifiException extends SocketException {
+            // empty
+        }
+    }
+
+    private final class MyNetworkCallback extends ConnectivityManager.NetworkCallback {
+        @Override
+        public void onCapabilitiesChanged(
+                @NonNull Network network, @NonNull NetworkCapabilities capability) {
+            synchronized (mLock) {
+                mHasWifi = capability.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+            }
+        }
+    }
 }
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
index eb0e7e2..a3b0577 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/MainActivity.java
@@ -15,6 +15,8 @@
  */
 package com.android.virtualization.terminal;
 
+import static android.webkit.WebSettings.LOAD_NO_CACHE;
+
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -40,7 +42,9 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.WindowInsets;
 import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
 import android.webkit.ClientCertRequest;
 import android.webkit.SslErrorHandler;
 import android.webkit.WebChromeClient;
@@ -57,7 +61,6 @@
 
 import com.google.android.material.appbar.MaterialToolbar;
 
-import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -66,15 +69,16 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.security.KeyStore;
 import java.security.PrivateKey;
 import java.security.cert.X509Certificate;
+import java.util.Map;
 
 public class MainActivity extends BaseActivity
-        implements VmLauncherServices.VmLauncherServiceCallback,
-                AccessibilityManager.TouchExplorationStateChangeListener {
-
-    private static final String TAG = "VmTerminalApp";
+        implements VmLauncherService.VmLauncherServiceCallback, AccessibilityStateChangeListener {
+    static final String TAG = "VmTerminalApp";
     private static final String VM_ADDR = "192.168.0.2";
     private static final int TTYD_PORT = 7681;
     private static final int REQUEST_CODE_INSTALLER = 0x33;
@@ -88,6 +92,20 @@
     private static final int POST_NOTIFICATIONS_PERMISSION_REQUEST_CODE = 101;
     private ActivityResultLauncher<Intent> mManageExternalStorageActivityResultLauncher;
     private static int diskSizeStep;
+    private static final Map<Integer, Integer> BTN_KEY_CODE_MAP =
+            Map.ofEntries(
+                    Map.entry(R.id.btn_tab, KeyEvent.KEYCODE_TAB),
+                    // Alt key sends ESC keycode
+                    Map.entry(R.id.btn_alt, KeyEvent.KEYCODE_ESCAPE),
+                    Map.entry(R.id.btn_esc, KeyEvent.KEYCODE_ESCAPE),
+                    Map.entry(R.id.btn_left, KeyEvent.KEYCODE_DPAD_LEFT),
+                    Map.entry(R.id.btn_right, KeyEvent.KEYCODE_DPAD_RIGHT),
+                    Map.entry(R.id.btn_up, KeyEvent.KEYCODE_DPAD_UP),
+                    Map.entry(R.id.btn_down, KeyEvent.KEYCODE_DPAD_DOWN),
+                    Map.entry(R.id.btn_home, KeyEvent.KEYCODE_MOVE_HOME),
+                    Map.entry(R.id.btn_end, KeyEvent.KEYCODE_MOVE_END),
+                    Map.entry(R.id.btn_pgup, KeyEvent.KEYCODE_PAGE_UP),
+                    Map.entry(R.id.btn_pgdn, KeyEvent.KEYCODE_PAGE_DOWN));
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -115,13 +133,15 @@
         mWebView.getSettings().setDatabaseEnabled(true);
         mWebView.getSettings().setDomStorageEnabled(true);
         mWebView.getSettings().setJavaScriptEnabled(true);
+        mWebView.getSettings().setCacheMode(LOAD_NO_CACHE);
         mWebView.setWebChromeClient(new WebChromeClient());
 
+        setupModifierKeys();
+
         mAccessibilityManager = getSystemService(AccessibilityManager.class);
-        mAccessibilityManager.addTouchExplorationStateChangeListener(this);
+        mAccessibilityManager.addAccessibilityStateChangeListener(this);
 
         readClientCertificate();
-        connectToTerminalService();
 
         mManageExternalStorageActivityResultLauncher =
                 registerForActivityResult(
@@ -129,7 +149,14 @@
                         (ActivityResult result) -> {
                             startVm();
                         });
-
+        getWindow()
+                .getDecorView()
+                .getRootView()
+                .setOnApplyWindowInsetsListener(
+                        (v, insets) -> {
+                            updateKeyboardContainerVisibility();
+                            return insets;
+                        });
         // if installer is launched, it will be handled in onActivityResult
         if (!launchInstaller) {
             if (!Environment.isExternalStorageManager()) {
@@ -140,6 +167,32 @@
         }
     }
 
+    private void setupModifierKeys() {
+        // Only ctrl key is special, it communicates with xtermjs to modify key event with ctrl key
+        findViewById(R.id.btn_ctrl)
+                .setOnClickListener(
+                        (v) -> {
+                            mWebView.loadUrl(TerminalView.CTRL_KEY_HANDLER);
+                            mWebView.loadUrl(TerminalView.ENABLE_CTRL_KEY);
+                        });
+
+        View.OnClickListener modifierButtonClickListener =
+                v -> {
+                    if (BTN_KEY_CODE_MAP.containsKey(v.getId())) {
+                        int keyCode = BTN_KEY_CODE_MAP.get(v.getId());
+                        mWebView.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
+                        mWebView.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
+                    }
+                };
+
+        for (int btn : BTN_KEY_CODE_MAP.keySet()) {
+            View v = findViewById(btn);
+            if (v != null) {
+                v.setOnClickListener(modifierButtonClickListener);
+            }
+        }
+    }
+
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (Build.isDebuggable() && event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN) {
@@ -170,7 +223,7 @@
                         + "&fontWeightBold="
                         + (FontStyle.FONT_WEIGHT_BOLD + config.fontWeightAdjustment)
                         + "&screenReaderMode="
-                        + mAccessibilityManager.isTouchExplorationEnabled()
+                        + mAccessibilityManager.isEnabled()
                         + "&titleFixed="
                         + getString(R.string.app_name);
 
@@ -216,6 +269,7 @@
                             case WebViewClient.ERROR_CONNECT:
                             case WebViewClient.ERROR_HOST_LOOKUP:
                             case WebViewClient.ERROR_FAILED_SSL_HANDSHAKE:
+                            case WebViewClient.ERROR_TIMEOUT:
                                 view.reload();
                                 return;
                             default:
@@ -241,8 +295,15 @@
                                             android.os.Trace.endAsyncSection("executeTerminal", 0);
                                             findViewById(R.id.boot_progress)
                                                     .setVisibility(View.GONE);
-                                            view.setVisibility(View.VISIBLE);
+                                            findViewById(R.id.webview_container)
+                                                    .setVisibility(View.VISIBLE);
                                             mBootCompleted.open();
+                                            // TODO(b/376813452): support talkback as well
+                                            int keyVisibility =
+                                                    mAccessibilityManager.isEnabled()
+                                                            ? View.GONE
+                                                            : View.VISIBLE;
+                                            updateKeyboardContainerVisibility();
                                         }
                                     }
                                 });
@@ -274,33 +335,29 @@
                 .start();
     }
 
-    private void diskResize(File file, long sizeInBytes) throws IOException {
+    private void diskResize(Path path, long sizeInBytes) throws IOException {
         try {
             if (sizeInBytes == 0) {
                 return;
             }
-            String filePath = file.getAbsolutePath();
-            Log.d(TAG, "Disk-resize in progress for partition: " + filePath);
+            Log.d(TAG, "Disk-resize in progress for partition: " + path);
 
-            long currentSize = Os.stat(filePath).st_size;
-            runE2fsck(filePath);
+            long currentSize = Files.size(path);
+            runE2fsck(path);
             if (sizeInBytes > currentSize) {
-                allocateSpace(file, sizeInBytes);
+                allocateSpace(path, sizeInBytes);
             }
 
-            resizeFilesystem(filePath, sizeInBytes);
-        } catch (ErrnoException e) {
-            Log.e(TAG, "ErrnoException during disk resize", e);
-            throw new IOException("ErrnoException during disk resize", e);
+            resizeFilesystem(path, sizeInBytes);
         } catch (IOException e) {
             Log.e(TAG, "Failed to resize disk", e);
             throw e;
         }
     }
 
-    private static void allocateSpace(File file, long sizeInBytes) throws IOException {
+    private static void allocateSpace(Path path, long sizeInBytes) throws IOException {
         try {
-            RandomAccessFile raf = new RandomAccessFile(file, "rw");
+            RandomAccessFile raf = new RandomAccessFile(path.toFile(), "rw");
             FileDescriptor fd = raf.getFD();
             Os.posix_fallocate(fd, 0, sizeInBytes);
             raf.close();
@@ -311,17 +368,18 @@
         }
     }
 
-    private static void runE2fsck(String filePath) throws IOException {
+    private static void runE2fsck(Path path) throws IOException {
         try {
-            runCommand("/system/bin/e2fsck", "-y", "-f", filePath);
-            Log.d(TAG, "e2fsck completed: " + filePath);
+            String p = path.toAbsolutePath().toString();
+            runCommand("/system/bin/e2fsck", "-y", "-f", p);
+            Log.d(TAG, "e2fsck completed: " + path);
         } catch (IOException e) {
             Log.e(TAG, "Failed to run e2fsck", e);
             throw e;
         }
     }
 
-    private static void resizeFilesystem(String filePath, long sizeInBytes) throws IOException {
+    private static void resizeFilesystem(Path path, long sizeInBytes) throws IOException {
         long sizeInMB = sizeInBytes / (1024 * 1024);
         if (sizeInMB == 0) {
             Log.e(TAG, "Invalid size: " + sizeInBytes + " bytes");
@@ -329,8 +387,9 @@
         }
         String sizeArg = sizeInMB + "M";
         try {
-            runCommand("/system/bin/resize2fs", filePath, sizeArg);
-            Log.d(TAG, "resize2fs completed: " + filePath + ", size: " + sizeArg);
+            String p = path.toAbsolutePath().toString();
+            runCommand("/system/bin/resize2fs", p, sizeArg);
+            Log.d(TAG, "resize2fs completed: " + path + ", size: " + sizeArg);
         } catch (IOException e) {
             Log.e(TAG, "Failed to run resize2fs", e);
             throw e;
@@ -366,8 +425,8 @@
 
     @Override
     protected void onDestroy() {
-        getSystemService(AccessibilityManager.class).removeTouchExplorationStateChangeListener(this);
-        VmLauncherServices.stopVmLauncherService(this);
+        getSystemService(AccessibilityManager.class).removeAccessibilityStateChangeListener(this);
+        VmLauncherService.stop(this);
         super.onDestroy();
     }
 
@@ -379,6 +438,7 @@
     @Override
     public void onVmStop() {
         Log.i(TAG, "onVmStop()");
+        finish();
     }
 
     @Override
@@ -410,10 +470,20 @@
     }
 
     @Override
-    public void onTouchExplorationStateChanged(boolean enabled) {
+    public void onAccessibilityStateChanged(boolean enabled) {
         connectToTerminalService();
     }
 
+    private void updateKeyboardContainerVisibility() {
+        boolean imeVisible =
+                this.getWindow()
+                        .getDecorView()
+                        .getRootWindowInsets()
+                        .isVisible(WindowInsets.Type.ime());
+        View keyboardContainer = findViewById(R.id.keyboard_container);
+        keyboardContainer.setVisibility(!imeVisible ? View.GONE : View.VISIBLE);
+    }
+
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
@@ -468,7 +538,7 @@
 
         Intent stopIntent = new Intent();
         stopIntent.setClass(this, VmLauncherService.class);
-        stopIntent.setAction(VmLauncherServices.ACTION_STOP_VM_LAUNCHER_SERVICE);
+        stopIntent.setAction(VmLauncherService.ACTION_STOP_VM_LAUNCHER_SERVICE);
         PendingIntent stopPendingIntent =
                 PendingIntent.getService(
                         this,
@@ -492,7 +562,7 @@
                                                         .getString(
                                                                 R.string
                                                                         .service_notification_settings),
-                                        settingsPendingIntent)
+                                                settingsPendingIntent)
                                         .build())
                         .addAction(
                                 new Notification.Action.Builder(
@@ -506,7 +576,8 @@
                         .build();
 
         android.os.Trace.beginAsyncSection("executeTerminal", 0);
-        VmLauncherServices.startVmLauncherService(this, this, notification);
+        VmLauncherService.run(this, this, notification);
+        connectToTerminalService();
     }
 
     @VisibleForTesting
@@ -519,10 +590,11 @@
         return (long) Math.ceil(((double) diskSize) / diskSizeStep) * diskSizeStep;
     }
 
-    public static long getMinFilesystemSize(File file) throws IOException, NumberFormatException {
+    public static long getMinFilesystemSize(Path path) throws IOException, NumberFormatException {
         try {
-            runE2fsck(file.getAbsolutePath());
-            String result = runCommand("/system/bin/resize2fs", "-P", file.getAbsolutePath());
+            runE2fsck(path);
+            String p = path.toAbsolutePath().toString();
+            String result = runCommand("/system/bin/resize2fs", "-P", p);
             // The return value is the number of 4k block
             long minSize = Long.parseLong(
                     result.lines().toArray(String[]::new)[1].substring(42)) * 4 * 1024;
@@ -533,13 +605,13 @@
         }
     }
 
-    private static long getFilesystemSize(File file) throws ErrnoException {
-        return Os.stat(file.getAbsolutePath()).st_size;
+    private static long getFilesystemSize(Path fsPath) throws ErrnoException {
+        return Os.stat(fsPath.toAbsolutePath().toString()).st_size;
     }
 
     private void resizeDiskIfNecessary() {
         try {
-            File file = InstallUtils.getRootfsFile(this);
+            Path file = InstallUtils.getRootfsFile(this);
             SharedPreferences sharedPref = this.getSharedPreferences(
                     getString(R.string.preference_file_key), Context.MODE_PRIVATE);
             SharedPreferences.Editor editor = sharedPref.edit();
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java
new file mode 100644
index 0000000..2f728ba
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/PortNotifier.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.virtualization.terminal;
+
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
+import android.app.Notification;
+import android.app.Notification.Action;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.drawable.Icon;
+import android.util.Log;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * PortNotifier is responsible for posting a notification when a new open port is detected. User can
+ * enable or disable forwarding of the port in notification panel.
+ */
+class PortNotifier {
+    private static final String ACTION_PORT_FORWARDING = "android.virtualization.PORT_FORWARDING";
+    private static final String KEY_PORT = "port";
+    private static final String KEY_ENABLED = "enabled";
+
+    private final Context mContext;
+    private final NotificationManager mNotificationManager;
+    private final BroadcastReceiver mReceiver;
+
+    public PortNotifier(Context context) {
+        mContext = context;
+        mNotificationManager = mContext.getSystemService(NotificationManager.class);
+        mReceiver = new PortForwardingRequestReceiver();
+
+        IntentFilter intentFilter = new IntentFilter(ACTION_PORT_FORWARDING);
+        mContext.registerReceiver(mReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED);
+    }
+
+    public void onActivePortsChanged(Set<String> oldPorts, Set<String> newPorts) {
+        Set<String> union = new HashSet<>(oldPorts);
+        union.addAll(newPorts);
+        for (String portStr : union) {
+            try {
+                int port = Integer.parseInt(portStr);
+                if (!oldPorts.contains(portStr)) {
+                    showNotificationFor(port);
+                } else if (!newPorts.contains(portStr)) {
+                    discardNotificationFor(port);
+                }
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "Failed to parse port: " + portStr);
+                throw e;
+            }
+        }
+    }
+
+    public void stop() {
+        mContext.unregisterReceiver(mReceiver);
+    }
+
+    private String getString(int resId) {
+        return mContext.getString(resId);
+    }
+
+    private PendingIntent getPendingIntentFor(int port, boolean enabled) {
+        Intent intent = new Intent(ACTION_PORT_FORWARDING);
+        intent.setPackage(mContext.getPackageName());
+        intent.setIdentifier(String.format(Locale.ROOT, "%d_%b", port, enabled));
+        intent.putExtra(KEY_PORT, port);
+        intent.putExtra(KEY_ENABLED, enabled);
+        return PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_IMMUTABLE);
+    }
+
+    private void showNotificationFor(int port) {
+        Intent tapIntent = new Intent(mContext, SettingsPortForwardingActivity.class);
+        tapIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        PendingIntent tapPendingIntent =
+                PendingIntent.getActivity(mContext, 0, tapIntent, PendingIntent.FLAG_IMMUTABLE);
+
+        String title = getString(R.string.settings_port_forwarding_notification_title);
+        String content =
+                mContext.getString(R.string.settings_port_forwarding_notification_content, port);
+        String acceptText = getString(R.string.settings_port_forwarding_notification_accept);
+        String denyText = getString(R.string.settings_port_forwarding_notification_deny);
+        Icon icon = Icon.createWithResource(mContext, R.drawable.ic_launcher_foreground);
+
+        Action acceptAction =
+                new Action.Builder(icon, acceptText, getPendingIntentFor(port, true /* enabled */))
+                        .build();
+        Action denyAction =
+                new Action.Builder(icon, denyText, getPendingIntentFor(port, false /* enabled */))
+                        .build();
+        Notification notification =
+                new Notification.Builder(mContext, mContext.getPackageName())
+                        .setSmallIcon(R.drawable.ic_launcher_foreground)
+                        .setContentTitle(title)
+                        .setContentText(content)
+                        .setContentIntent(tapPendingIntent)
+                        .addAction(acceptAction)
+                        .addAction(denyAction)
+                        .build();
+        mNotificationManager.notify(TAG, port, notification);
+    }
+
+    private void discardNotificationFor(int port) {
+        mNotificationManager.cancel(TAG, port);
+    }
+
+    private final class PortForwardingRequestReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (ACTION_PORT_FORWARDING.equals(intent.getAction())) {
+                performActionPortForwarding(context, intent);
+            }
+        }
+
+        private void performActionPortForwarding(Context context, Intent intent) {
+            String prefKey = context.getString(R.string.preference_file_key);
+            int port = intent.getIntExtra(KEY_PORT, 0);
+            String key = context.getString(R.string.preference_forwarding_port_is_enabled) + port;
+            boolean enabled = intent.getBooleanExtra(KEY_ENABLED, false);
+
+            context.getSharedPreferences(prefKey, Context.MODE_PRIVATE)
+                    .edit()
+                    .putBoolean(key, enabled)
+                    .apply();
+
+            discardNotificationFor(port);
+        }
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java
index a2247b1..4094025 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/Runner.java
@@ -16,6 +16,8 @@
 
 package com.android.virtualization.terminal;
 
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
 import android.content.Context;
 import android.system.virtualmachine.VirtualMachine;
 import android.system.virtualmachine.VirtualMachineCallback;
@@ -30,7 +32,6 @@
 
 /** Utility class for creating a VM and waiting for it to finish. */
 class Runner {
-    private static final String TAG = Runner.class.getSimpleName();
     private final VirtualMachine mVirtualMachine;
     private final Callback mCallback;
 
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
index a1509ad..1b39ff0 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsPortForwardingActivity.kt
@@ -28,9 +28,9 @@
 import androidx.core.app.ActivityCompat
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
+import com.android.virtualization.terminal.MainActivity.TAG
 
 class SettingsPortForwardingActivity : AppCompatActivity() {
-    val TAG: String = "VmTerminalApp"
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.settings_port_forwarding)
@@ -62,48 +62,5 @@
         val recyclerView: RecyclerView = findViewById(R.id.settings_port_forwarding_recycler_view)
         recyclerView.layoutManager = LinearLayoutManager(this)
         recyclerView.adapter = settingsPortForwardingAdapter
-
-        // TODO: implement intent for accept, deny and tap to the notification
-        // Currently show a mock notification of a port opening
-        val terminalIntent = Intent()
-        val pendingIntent = PendingIntent.getActivity(
-            this, 0, terminalIntent,
-            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
-        )
-        val notification =
-            Notification.Builder(this, TAG)
-                .setChannelId(TAG)
-                .setSmallIcon(R.drawable.ic_launcher_foreground)
-                .setContentTitle(resources.getString(R.string.settings_port_forwarding_notification_title))
-                .setContentText(
-                    resources.getString(
-                        R.string.settings_port_forwarding_notification_content,
-                        8080
-                    )
-                )
-                .addAction(
-                    Notification.Action.Builder(
-                        Icon.createWithResource(resources, R.drawable.ic_launcher_foreground),
-                        resources.getString(R.string.settings_port_forwarding_notification_accept),
-                        pendingIntent
-                    ).build()
-                )
-                .addAction(
-                    Notification.Action.Builder(
-                        Icon.createWithResource(resources, R.drawable.ic_launcher_foreground),
-                        resources.getString(R.string.settings_port_forwarding_notification_deny),
-                        pendingIntent
-                    ).build()
-                )
-                .build()
-
-        with(NotificationManager.from(this)) {
-            if (ActivityCompat.checkSelfPermission(
-                    this@SettingsPortForwardingActivity, Manifest.permission.POST_NOTIFICATIONS
-                ) == PackageManager.PERMISSION_GRANTED
-            ) {
-                notify(0, notification)
-            }
-        }
     }
-}
\ No newline at end of file
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsRecoveryActivity.kt b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsRecoveryActivity.kt
index ef76e03..4b6bf96 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/SettingsRecoveryActivity.kt
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/SettingsRecoveryActivity.kt
@@ -22,16 +22,16 @@
 import androidx.appcompat.app.AppCompatActivity
 import androidx.core.view.isVisible
 import androidx.lifecycle.lifecycleScope
+import com.android.virtualization.terminal.MainActivity.TAG
 import com.google.android.material.card.MaterialCardView
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import com.google.android.material.snackbar.Snackbar
 import java.io.IOException
+import java.nio.file.Files
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 
-const val TAG: String = "VmTerminalApp"
-
 class SettingsRecoveryActivity : AppCompatActivity() {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -56,7 +56,7 @@
             dialog.show()
         }
         val resetBackupCard = findViewById<View>(R.id.settings_recovery_reset_backup_card)
-        resetBackupCard.isVisible = InstallUtils.getBackupFile(this).exists()
+        resetBackupCard.isVisible = Files.exists(InstallUtils.getBackupFile(this))
 
         resetBackupCard.setOnClickListener {
             val dialog = MaterialAlertDialogBuilder(this)
@@ -74,7 +74,10 @@
     }
 
     private fun removeBackup(): Unit {
-        if (!InstallUtils.getBackupFile(this@SettingsRecoveryActivity).delete()) {
+        val file = InstallUtils.getBackupFile(this@SettingsRecoveryActivity)
+        try {
+            Files.deleteIfExists(file)
+        } catch (e: IOException) {
             Snackbar.make(
                 findViewById(android.R.id.content),
                 R.string.settings_recovery_error_during_removing_backup,
@@ -123,4 +126,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java
new file mode 100644
index 0000000..274f423
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/TerminalView.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.virtualization.terminal;
+
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.View.AccessibilityDelegate;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
+import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.webkit.WebView;
+
+import java.util.List;
+
+public class TerminalView extends WebView
+        implements AccessibilityStateChangeListener, TouchExplorationStateChangeListener {
+    // Maximum length of texts the talk back announcements can be. This value is somewhat
+    // arbitrarily set. We may want to adjust this in the future.
+    private static final int TEXT_TOO_LONG_TO_ANNOUNCE = 200;
+
+    // keyCode 229 means composing text, so get the last character in e.target.value.
+    // keycode 64(@)-95(_) is mapped to a ctrl code
+    // keycode 97(A)-122(Z) is converted to a small letter, and mapped to ctrl code
+    public static final String CTRL_KEY_HANDLER =
+            """
+javascript: (function() {
+  window.term.attachCustomKeyEventHandler((e) => {
+      if (window.ctrl) {
+          keyCode = e.keyCode;
+          if (keyCode === 229) {
+              keyCode = e.target.value.charAt(e.target.selectionStart - 1).charCodeAt();
+          }
+          if (64 <= keyCode && keyCode <= 95) {
+              input = String.fromCharCode(keyCode - 64);
+          } else if (97 <= keyCode && keyCode <= 122) {
+              input = String.fromCharCode(keyCode - 96);
+          } else {
+              return true;
+          }
+          if (e.type === 'keyup') {
+              window.term.input(input);
+              e.target.value = e.target.value.slice(0, -1);
+              window.ctrl = false;
+          }
+          return false;
+      } else {
+          return true;
+      }
+  });
+})();
+""";
+    public static final String ENABLE_CTRL_KEY = "javascript:(function(){window.ctrl=true;})();";
+
+    private final AccessibilityManager mA11yManager;
+
+    public TerminalView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mA11yManager = context.getSystemService(AccessibilityManager.class);
+        mA11yManager.addTouchExplorationStateChangeListener(this);
+        mA11yManager.addAccessibilityStateChangeListener(this);
+        adjustToA11yStateChange();
+    }
+
+    @Override
+    public void onAccessibilityStateChanged(boolean enabled) {
+        Log.d(TAG, "accessibility " + enabled);
+        adjustToA11yStateChange();
+    }
+
+    @Override
+    public void onTouchExplorationStateChanged(boolean enabled) {
+        Log.d(TAG, "touch exploration " + enabled);
+        adjustToA11yStateChange();
+    }
+
+    private void adjustToA11yStateChange() {
+        if (!mA11yManager.isEnabled()) {
+            setFocusable(true);
+            return;
+        }
+
+        // When accessibility is on, the webview itself doesn't have to be focusable. The (virtual)
+        // edittext will be focusable to accept inputs. However, the webview has to be focusable for
+        // an accessibility purpose so that users can read the contents in it or scroll the view.
+        setFocusable(false);
+        setFocusableInTouchMode(true);
+    }
+
+    // AccessibilityEvents for WebView are sent directly from WebContentsAccessibilityImpl to the
+    // parent of WebView, without going through WebView. So, there's no WebView methods we can
+    // override to intercept the event handling process. To work around this, we attach an
+    // AccessibilityDelegate to the parent view where the events are sent to. And to guarantee that
+    // the parent view exists, wait until the WebView is attached to the window by when the parent
+    // must exist.
+    private final AccessibilityDelegate mA11yEventFilter =
+            new AccessibilityDelegate() {
+                @Override
+                public boolean onRequestSendAccessibilityEvent(
+                        ViewGroup host, View child, AccessibilityEvent e) {
+                    // We filter only the a11y events from the WebView
+                    if (child != TerminalView.this) {
+                        return super.onRequestSendAccessibilityEvent(host, child, e);
+                    }
+                    final int eventType = e.getEventType();
+                    switch (e.getEventType()) {
+                            // Skip reading texts that are too long. Right now, ttyd emits entire
+                            // text on the terminal to the live region, which is very annoying to
+                            // screen reader users.
+                        case AccessibilityEvent.TYPE_ANNOUNCEMENT:
+                            CharSequence text = e.getText().get(0); // there always is a text
+                            if (text.length() >= TEXT_TOO_LONG_TO_ANNOUNCE) {
+                                Log.i(TAG, "Announcement skipped because it's too long: " + text);
+                                return false;
+                            }
+                            break;
+                    }
+                    return super.onRequestSendAccessibilityEvent(host, child, e);
+                }
+            };
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        if (mA11yManager.isEnabled()) {
+            View parent = (View) getParent();
+            parent.setAccessibilityDelegate(mA11yEventFilter);
+        }
+    }
+
+    private final AccessibilityNodeProvider mA11yNodeProvider =
+            new AccessibilityNodeProvider() {
+
+                /** Returns the original NodeProvider that WebView implements. */
+                private AccessibilityNodeProvider getParent() {
+                    return TerminalView.super.getAccessibilityNodeProvider();
+                }
+
+                /** Convenience method for reading a string resource. */
+                private String getString(int resId) {
+                    return TerminalView.this.getContext().getResources().getString(resId);
+                }
+
+                /** Checks if NodeInfo renders an empty line in the terminal. */
+                private boolean isEmptyLine(AccessibilityNodeInfo info) {
+                    final CharSequence text = info.getText();
+                    // Node with no text is not consiered a line. ttyd emits at least one character,
+                    // which usually is NBSP.
+                    if (text == null) {
+                        return false;
+                    }
+                    for (int i = 0; i < text.length(); i++) {
+                        char c = text.charAt(i);
+                        // Note: don't use Characters.isWhitespace as it doesn't recognize NBSP as a
+                        // whitespace.
+                        if (!TextUtils.isWhitespace(c)) {
+                            return false;
+                        }
+                    }
+                    return true;
+                }
+
+                @Override
+                public AccessibilityNodeInfo createAccessibilityNodeInfo(int id) {
+                    AccessibilityNodeInfo info = getParent().createAccessibilityNodeInfo(id);
+                    if (info == null) {
+                        return null;
+                    }
+
+                    final String className = info.getClassName().toString();
+
+                    // By default all views except the cursor is not click-able. Other views are
+                    // read-only. This ensures that user is not navigated to non-clickable elements
+                    // when using switches.
+                    if (!"android.widget.EditText".equals(className)) {
+                        info.removeAction(AccessibilityAction.ACTION_CLICK);
+                    }
+
+                    switch (className) {
+                        case "android.webkit.WebView":
+                            // There are two NodeInfo objects of class name WebView. The one is the
+                            // real WebView whose ID is View.NO_ID as it's at the root of the
+                            // virtual view hierarchy. The second one is a virtual view for the
+                            // iframe. The latter one's text is set to the command that we give to
+                            // ttyd, which is "login -f droid ...". This is an impl detail which
+                            // doesn't have to be announced.  Replace the text with "Terminal
+                            // display".
+                            if (id != View.NO_ID) {
+                                info.setText(null);
+                                info.setContentDescription(getString(R.string.terminal_display));
+                            }
+
+                            // These two lines below are to prevent this WebView element from being
+                            // fousable by the screen reader, while allowing any other element in
+                            // the WebView to be focusable by the reader. In our case, the EditText
+                            // is a117_focusable.
+                            info.setScreenReaderFocusable(false);
+                            info.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
+                            break;
+                        case "android.view.View":
+                            // Empty line was announced as "space" (via the NBSP character).
+                            // Localize the spoken text.
+                            if (isEmptyLine(info)) {
+                                info.setContentDescription(getString(R.string.empty_line));
+                            }
+                            break;
+                        case "android.widget.TextView":
+                            // There are several TextViews in the terminal, and one of them is an
+                            // invisible TextView which seems to be from the <div
+                            // class="live-region"> tag. Interestingly, its text is often populated
+                            // with the entire text on the screen. Silence this by forcibly setting
+                            // the text to null. Note that this TextView is identified by having a
+                            // zero width. This certainly is not elegant, but I couldn't find other
+                            // options.
+                            Rect rect = new Rect();
+                            info.getBoundsInScreen(rect);
+                            if (rect.width() == 0) {
+                                info.setText(null);
+                            }
+                            info.setScreenReaderFocusable(false);
+                            break;
+                        case "android.widget.EditText":
+                            // This EditText is for the <textarea> accepting user input; the cursor.
+                            // ttyd name it as "Terminal input" but it's not i18n'ed. Override it
+                            // here for better i18n.
+                            info.setText(null);
+                            info.setHintText(null);
+                            info.setContentDescription(getString(R.string.terminal_input));
+                            info.setScreenReaderFocusable(true);
+                            info.addAction(AccessibilityAction.ACTION_FOCUS);
+                            break;
+                    }
+                    return info;
+                }
+
+                @Override
+                public boolean performAction(int id, int action, Bundle arguments) {
+                    return getParent().performAction(id, action, arguments);
+                }
+
+                @Override
+                public void addExtraDataToAccessibilityNodeInfo(
+                        int virtualViewId,
+                        AccessibilityNodeInfo info,
+                        String extraDataKey,
+                        Bundle arguments) {
+                    getParent()
+                            .addExtraDataToAccessibilityNodeInfo(
+                                    virtualViewId, info, extraDataKey, arguments);
+                }
+
+                @Override
+                public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(
+                        String text, int virtualViewId) {
+                    return getParent().findAccessibilityNodeInfosByText(text, virtualViewId);
+                }
+
+                @Override
+                public AccessibilityNodeInfo findFocus(int focus) {
+                    return getParent().findFocus(focus);
+                }
+            };
+
+    @Override
+    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
+        AccessibilityNodeProvider p = super.getAccessibilityNodeProvider();
+        if (p != null && mA11yManager.isEnabled()) {
+            return mA11yNodeProvider;
+        }
+        return p;
+    }
+
+    @Override
+    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+        InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
+        if (outAttrs != null) {
+            // TODO(b/378642568): consider using InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
+            // here..
+            outAttrs.inputType =
+                    InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
+        }
+        return inputConnection;
+    }
+}
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
index 25afcb7..879b5e5 100644
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherService.java
@@ -16,11 +16,18 @@
 
 package com.android.virtualization.terminal;
 
+import static com.android.virtualization.terminal.MainActivity.TAG;
+
 import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.Parcel;
 import android.os.ResultReceiver;
 import android.system.virtualmachine.VirtualMachine;
 import android.system.virtualmachine.VirtualMachineConfig;
@@ -43,14 +50,20 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
 public class VmLauncherService extends Service implements DebianServiceImpl.DebianServiceCallback {
-    public static final String EXTRA_NOTIFICATION = "EXTRA_NOTIFICATION";
-    private static final String TAG = "VmLauncherService";
+    private static final String EXTRA_NOTIFICATION = "EXTRA_NOTIFICATION";
+    private static final String ACTION_START_VM_LAUNCHER_SERVICE =
+            "android.virtualization.START_VM_LAUNCHER_SERVICE";
+
+    public static final String ACTION_STOP_VM_LAUNCHER_SERVICE =
+            "android.virtualization.STOP_VM_LAUNCHER_SERVICE";
 
     private static final int RESULT_START = 0;
     private static final int RESULT_STOP = 1;
@@ -63,20 +76,73 @@
     private ResultReceiver mResultReceiver;
     private Server mServer;
     private DebianServiceImpl mDebianService;
+    private PortNotifier mPortNotifier;
+
+    private static Intent getMyIntent(Context context) {
+        return new Intent(context.getApplicationContext(), VmLauncherService.class);
+    }
+
+    public interface VmLauncherServiceCallback {
+        void onVmStart();
+
+        void onVmStop();
+
+        void onVmError();
+
+        void onIpAddrAvailable(String ipAddr);
+    }
+
+    public static void run(
+            Context context, VmLauncherServiceCallback callback, Notification notification) {
+        Intent i = getMyIntent(context);
+        if (i == null) {
+            return;
+        }
+        ResultReceiver resultReceiver =
+                new ResultReceiver(new Handler(Looper.myLooper())) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (callback == null) {
+                            return;
+                        }
+                        switch (resultCode) {
+                            case RESULT_START:
+                                callback.onVmStart();
+                                return;
+                            case RESULT_STOP:
+                                callback.onVmStop();
+                                return;
+                            case RESULT_ERROR:
+                                callback.onVmError();
+                                return;
+                            case RESULT_IPADDR:
+                                callback.onIpAddrAvailable(resultData.getString(KEY_VM_IP_ADDR));
+                                return;
+                        }
+                    }
+                };
+        i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver));
+        i.putExtra(VmLauncherService.EXTRA_NOTIFICATION, notification);
+        context.startForegroundService(i);
+    }
+
+    private static ResultReceiver getResultReceiverForIntent(ResultReceiver r) {
+        Parcel parcel = Parcel.obtain();
+        r.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        r = ResultReceiver.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+        return r;
+    }
 
     @Override
     public IBinder onBind(Intent intent) {
         return null;
     }
 
-    private void startForeground(Notification notification) {
-        startForeground(this.hashCode(), notification);
-    }
-
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        if (Objects.equals(
-                intent.getAction(), VmLauncherServices.ACTION_STOP_VM_LAUNCHER_SERVICE)) {
+        if (Objects.equals(intent.getAction(), ACTION_STOP_VM_LAUNCHER_SERVICE)) {
             stopSelf();
             return START_NOT_STICKY;
         }
@@ -86,13 +152,13 @@
         }
         mExecutorService = Executors.newCachedThreadPool();
 
-        ConfigJson json = ConfigJson.from(InstallUtils.getVmConfigPath(this));
+        ConfigJson json = ConfigJson.from(this, InstallUtils.getVmConfigPath(this));
         VirtualMachineConfig.Builder configBuilder = json.toConfigBuilder(this);
         VirtualMachineCustomImageConfig.Builder customImageConfigBuilder =
                 json.toCustomImageConfigBuilder(this);
-        File backupFile = InstallUtils.getBackupFile(this);
-        if (backupFile.exists()) {
-            customImageConfigBuilder.addDisk(Disk.RWDisk(backupFile.getPath()));
+        Path backupFile = InstallUtils.getBackupFile(this);
+        if (Files.exists(backupFile)) {
+            customImageConfigBuilder.addDisk(Disk.RWDisk(backupFile.toString()));
             configBuilder.setCustomImageConfig(customImageConfigBuilder.build());
         }
         VirtualMachineConfig config = configBuilder.build();
@@ -126,34 +192,16 @@
         Notification notification =
                 intent.getParcelableExtra(EXTRA_NOTIFICATION, Notification.class);
 
-        startForeground(notification);
+        startForeground(this.hashCode(), notification);
 
         mResultReceiver.send(RESULT_START, null);
 
+        mPortNotifier = new PortNotifier(this);
         startDebianServer();
 
         return START_NOT_STICKY;
     }
 
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        stopDebianServer();
-        if (mVirtualMachine != null) {
-            if (mVirtualMachine.getStatus() == VirtualMachine.STATUS_RUNNING) {
-                try {
-                    mVirtualMachine.stop();
-                    stopForeground(STOP_FOREGROUND_REMOVE);
-                } catch (VirtualMachineException e) {
-                    Log.e(TAG, "failed to stop a VM instance", e);
-                }
-            }
-            mExecutorService.shutdownNow();
-            mExecutorService = null;
-            mVirtualMachine = null;
-        }
-    }
-
     private void startDebianServer() {
         ServerInterceptor interceptor =
                 new ServerInterceptor() {
@@ -208,6 +256,45 @@
                 });
     }
 
+    @Override
+    public void onIpAddressAvailable(String ipAddr) {
+        android.os.Trace.endAsyncSection("debianBoot", 0);
+        Bundle b = new Bundle();
+        b.putString(VmLauncherService.KEY_VM_IP_ADDR, ipAddr);
+        mResultReceiver.send(VmLauncherService.RESULT_IPADDR, b);
+    }
+
+    @Override
+    public void onActivePortsChanged(Set<String> oldPorts, Set<String> newPorts) {
+        mPortNotifier.onActivePortsChanged(oldPorts, newPorts);
+    }
+
+    public static void stop(Context context) {
+        Intent i = getMyIntent(context);
+        context.stopService(i);
+    }
+
+    @Override
+    public void onDestroy() {
+        mPortNotifier.stop();
+        getSystemService(NotificationManager.class).cancelAll();
+        stopDebianServer();
+        if (mVirtualMachine != null) {
+            if (mVirtualMachine.getStatus() == VirtualMachine.STATUS_RUNNING) {
+                try {
+                    mVirtualMachine.stop();
+                    stopForeground(STOP_FOREGROUND_REMOVE);
+                } catch (VirtualMachineException e) {
+                    Log.e(TAG, "failed to stop a VM instance", e);
+                }
+            }
+            mExecutorService.shutdownNow();
+            mExecutorService = null;
+            mVirtualMachine = null;
+        }
+        super.onDestroy();
+    }
+
     private void stopDebianServer() {
         if (mDebianService != null) {
             mDebianService.killForwarderHost();
@@ -216,12 +303,4 @@
             mServer.shutdown();
         }
     }
-
-    @Override
-    public void onIpAddressAvailable(String ipAddr) {
-        android.os.Trace.endAsyncSection("debianBoot", 0);
-        Bundle b = new Bundle();
-        b.putString(VmLauncherService.KEY_VM_IP_ADDR, ipAddr);
-        mResultReceiver.send(VmLauncherService.RESULT_IPADDR, b);
-    }
 }
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherServices.java b/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherServices.java
deleted file mode 100644
index d6c6786..0000000
--- a/android/TerminalApp/java/com/android/virtualization/terminal/VmLauncherServices.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.virtualization.terminal;
-
-import android.app.Notification;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Parcel;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-import java.util.List;
-
-public class VmLauncherServices {
-    private static final String TAG = "VmLauncherServices";
-
-    private static final String ACTION_START_VM_LAUNCHER_SERVICE =
-            "android.virtualization.START_VM_LAUNCHER_SERVICE";
-
-    public static final String ACTION_STOP_VM_LAUNCHER_SERVICE =
-            "android.virtualization.STOP_VM_LAUNCHER_SERVICE";
-    private static final int RESULT_START = 0;
-    private static final int RESULT_STOP = 1;
-    private static final int RESULT_ERROR = 2;
-    private static final int RESULT_IPADDR = 3;
-    private static final String KEY_VM_IP_ADDR = "ip_addr";
-
-    private static Intent buildVmLauncherServiceIntent(Context context) {
-        Intent i = new Intent();
-        i.setAction(ACTION_START_VM_LAUNCHER_SERVICE);
-
-        Intent intent = new Intent(ACTION_START_VM_LAUNCHER_SERVICE);
-        PackageManager pm = context.getPackageManager();
-        List<ResolveInfo> resolveInfos =
-                pm.queryIntentServices(intent, PackageManager.MATCH_DEFAULT_ONLY);
-        if (resolveInfos == null || resolveInfos.size() != 1) {
-            Log.e(TAG, "cannot find a service to handle ACTION_START_VM_LAUNCHER_SERVICE");
-            return null;
-        }
-        String packageName = resolveInfos.get(0).serviceInfo.packageName;
-
-        i.setPackage(packageName);
-        return i;
-    }
-
-    public static void stopVmLauncherService(Context context) {
-        Intent i = buildVmLauncherServiceIntent(context);
-        context.stopService(i);
-    }
-
-    public static void startVmLauncherService(
-            Context context, VmLauncherServiceCallback callback, Notification notification) {
-        Intent i = buildVmLauncherServiceIntent(context);
-        if (i == null) {
-            return;
-        }
-        ResultReceiver resultReceiver =
-                new ResultReceiver(new Handler(Looper.myLooper())) {
-                    @Override
-                    protected void onReceiveResult(int resultCode, Bundle resultData) {
-                        if (callback == null) {
-                            return;
-                        }
-                        switch (resultCode) {
-                            case RESULT_START:
-                                callback.onVmStart();
-                                return;
-                            case RESULT_STOP:
-                                callback.onVmStop();
-                                return;
-                            case RESULT_ERROR:
-                                callback.onVmError();
-                                return;
-                            case RESULT_IPADDR:
-                                callback.onIpAddrAvailable(resultData.getString(KEY_VM_IP_ADDR));
-                                return;
-                        }
-                    }
-                };
-        i.putExtra(Intent.EXTRA_RESULT_RECEIVER, getResultReceiverForIntent(resultReceiver));
-        i.putExtra(VmLauncherService.EXTRA_NOTIFICATION, notification);
-        context.startForegroundService(i);
-    }
-
-    public interface VmLauncherServiceCallback {
-        void onVmStart();
-
-        void onVmStop();
-
-        void onVmError();
-
-        void onIpAddrAvailable(String ipAddr);
-    }
-
-    private static ResultReceiver getResultReceiverForIntent(ResultReceiver r) {
-        Parcel parcel = Parcel.obtain();
-        r.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-        r = ResultReceiver.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-        return r;
-    }
-}
diff --git a/android/TerminalApp/res/layout/activity_error.xml b/android/TerminalApp/res/layout/activity_error.xml
index 1b5026e..054478f 100644
--- a/android/TerminalApp/res/layout/activity_error.xml
+++ b/android/TerminalApp/res/layout/activity_error.xml
@@ -29,7 +29,7 @@
         android:layout_marginVertical="24dp"
         android:layout_marginHorizontal="24dp"
         android:layout_alignParentTop="true"
-        android:hyphenationFrequency="normal"
+        android:hyphenationFrequency="full"
         android:textSize="48sp" />
 
     <TextView
diff --git a/android/TerminalApp/res/layout/activity_headless.xml b/android/TerminalApp/res/layout/activity_headless.xml
index 8a15dd8..0bcfbea 100644
--- a/android/TerminalApp/res/layout/activity_headless.xml
+++ b/android/TerminalApp/res/layout/activity_headless.xml
@@ -47,13 +47,20 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"/>
         </LinearLayout>
-        <WebView
-            android:id="@+id/webview"
-            android:layout_marginBottom="5dp"
-            android:layout_gravity="fill"
+        <LinearLayout
+            android:id="@+id/webview_container"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:visibility="invisible"/>
+            android:layout_marginBottom="5dp"
+            android:orientation="vertical"
+            android:visibility="gone" >
+            <com.android.virtualization.terminal.TerminalView
+                android:id="@+id/webview"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1" />
+            <include layout="@layout/layout_keyboard" />
+        </LinearLayout>
     </FrameLayout>
 
 </LinearLayout>
diff --git a/android/TerminalApp/res/layout/layout_keyboard.xml b/android/TerminalApp/res/layout/layout_keyboard.xml
new file mode 100644
index 0000000..d8b7e11
--- /dev/null
+++ b/android/TerminalApp/res/layout/layout_keyboard.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+<!--TODO(b/376813452): we might want tablet UI for that-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyboard_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical" >
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_esc"
+            android:text="@string/btn_esc_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_tab"
+            android:text="@string/btn_tab_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_home"
+            android:text="@string/btn_home_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_up"
+            android:text="@string/btn_up_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_end"
+            android:text="@string/btn_end_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_pgup"
+            android:text="@string/btn_pgup_text" />
+    </LinearLayout>
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_ctrl"
+            android:text="@string/btn_ctrl_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_alt"
+            android:text="@string/btn_alt_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_left"
+            android:text="@string/btn_left_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_down"
+            android:text="@string/btn_down_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_right"
+            android:text="@string/btn_right_text" />
+        <Button
+            style="@style/ModifierKeyStyle"
+            android:id="@+id/btn_pgdn"
+            android:text="@string/btn_pgdn_text" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/android/TerminalApp/res/layout/settings_disk_resize.xml b/android/TerminalApp/res/layout/settings_disk_resize.xml
index 21ff070..7b8b9fc 100644
--- a/android/TerminalApp/res/layout/settings_disk_resize.xml
+++ b/android/TerminalApp/res/layout/settings_disk_resize.xml
@@ -29,7 +29,7 @@
         android:layout_width="wrap_content"
         android:text="@string/settings_disk_resize_title"
         android:textSize="48sp"
-        android:hyphenationFrequency="normal"
+        android:hyphenationFrequency="full"
         android:layout_marginBottom="24dp"/>
 
     <androidx.constraintlayout.widget.ConstraintLayout
@@ -71,7 +71,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:maxWidth="150sp"
-            android:hyphenationFrequency="normal"
+            android:hyphenationFrequency="full"
             android:text="@string/settings_disk_resize_resize_cancel"
             android:visibility="invisible"
             android:layout_marginTop="48dp"
@@ -85,7 +85,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:maxWidth="150sp"
-            android:hyphenationFrequency="normal"
+            android:hyphenationFrequency="full"
             android:text="@string/settings_disk_resize_resize_restart_vm_to_apply"
             android:visibility="invisible"
             android:layout_marginTop="48dp"
diff --git a/android/TerminalApp/res/layout/settings_port_forwarding.xml b/android/TerminalApp/res/layout/settings_port_forwarding.xml
index 98ba02c..2d21962 100644
--- a/android/TerminalApp/res/layout/settings_port_forwarding.xml
+++ b/android/TerminalApp/res/layout/settings_port_forwarding.xml
@@ -28,7 +28,7 @@
         android:layout_width="wrap_content"
         android:text="@string/settings_port_forwarding_title"
         android:textSize="48sp"
-        android:hyphenationFrequency="normal"
+        android:hyphenationFrequency="full"
         android:layout_marginBottom="24dp"/>
 
     <androidx.recyclerview.widget.RecyclerView
diff --git a/android/TerminalApp/res/layout/settings_recovery.xml b/android/TerminalApp/res/layout/settings_recovery.xml
index c72447f..d33f9a3 100644
--- a/android/TerminalApp/res/layout/settings_recovery.xml
+++ b/android/TerminalApp/res/layout/settings_recovery.xml
@@ -28,7 +28,7 @@
         android:layout_width="wrap_content"
         android:text="@string/settings_recovery_title"
         android:textSize="48sp"
-        android:hyphenationFrequency="normal"
+        android:hyphenationFrequency="full"
         android:layout_marginStart="24dp"
         android:layout_marginBottom="24dp"/>
     <FrameLayout
diff --git a/android/TerminalApp/res/values-af/strings.xml b/android/TerminalApp/res/values-af/strings.xml
index 03a65a4..a1c3998 100644
--- a/android/TerminalApp/res/values-af/strings.xml
+++ b/android/TerminalApp/res/values-af/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Afdelingherwinningopsies"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Verander na aanvanklike weergawe"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Verwyder almal"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Stel terminaal terug"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data sal uitgevee word"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Bevestig"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Kanselleer"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Instellings"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminaal loop tans"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Klik om die terminaal oop te maak"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Maak toe"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-am/strings.xml b/android/TerminalApp/res/values-am/strings.xml
index 60f2124..5c89e70 100644
--- a/android/TerminalApp/res/values-am/strings.xml
+++ b/android/TerminalApp/res/values-am/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"የክፍልፋይ መልሶ ማግኛ አማራጮች"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"ወደ የመጀመሪያ ሥሪት ለውጥ"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"ሁሉንም አስወግድ"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"ተርሚናልን ዳግም አስጀምር"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ውሂብ ይሰረዛል"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"አረጋግጥ"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"ይቅር"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ቅንብሮች"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ተርሚናል በመሄድ ላይ ነው"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"ተርሚናሉን ለመክፈት ጠቅ ያድርጉ"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"ዝጋ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ar/strings.xml b/android/TerminalApp/res/values-ar/strings.xml
index 1c47648..dae5de6 100644
--- a/android/TerminalApp/res/values-ar/strings.xml
+++ b/android/TerminalApp/res/values-ar/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"تم تخصيص <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"‫<xliff:g id="MAX_SIZE">%1$s</xliff:g> كحد أقصى"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"إلغاء"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"إعادة التشغيل لتطبيق التغييرات"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"إعادة توجيه المنفذ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"ضبط إعادة توجيه المنفذ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"تحاول الوحدة الطرفية فتح منفذ جديد"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"سيتم حذف البيانات"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"تأكيد"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"إلغاء"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"الاحتفاظ بنسخة احتياطية من البيانات في <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"تعذّر الاسترداد بسبب عدم نجاح عملية الاحتفاظ بنسخة احتياطية"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"تعذّر الاسترداد"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"تتعذّر إزالة ملف النسخة الاحتياطية"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"إزالة بيانات النسخة الاحتياطية"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"حذف بيانات النسخة الاحتياطية في <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"الإعدادات"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"الوحدة الطرفية قيد التشغيل"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"انقر لفتح الوحدة الطرفية"</string>
diff --git a/android/TerminalApp/res/values-as/strings.xml b/android/TerminalApp/res/values-as/strings.xml
index 4ff9c33..5375c19 100644
--- a/android/TerminalApp/res/values-as/strings.xml
+++ b/android/TerminalApp/res/values-as/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ডেটাখিনি মচা হ’ব"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"নিশ্চিত কৰক"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"বাতিল কৰক"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ছেটিং"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"টাৰ্মিনেলটো চলি আছে"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"টাৰ্মিনেলটো খুলিবলৈ ক্লিক কৰক"</string>
diff --git a/android/TerminalApp/res/values-az/strings.xml b/android/TerminalApp/res/values-az/strings.xml
index de953f5..f70772b 100644
--- a/android/TerminalApp/res/values-az/strings.xml
+++ b/android/TerminalApp/res/values-az/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Bölmə üzrə bərpa seçimləri"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"İlkin versiyaya dəyişin"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Hamısını silin"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Terminalı sıfırlayın"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data silinəcək"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Təsdiq edin"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Ləğv edin"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Ayarlar"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal işləyir"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Terminalı açmaq üçün klikləyin"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Bağlayın"</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 0b53ab3..2832dcf 100644
--- a/android/TerminalApp/res/values-b+sr+Latn/strings.xml
+++ b/android/TerminalApp/res/values-b+sr+Latn/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Dodeljeno <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Maks. <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Otkaži"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Restartuj i primeni"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Prosleđivanje porta"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Konfigurišite prosleđivanje porta"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminal pokušava da otvori novi port"</string>
@@ -49,15 +48,24 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opcije oporavka particija"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Promeni na početnu verziju"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Uklonite sve"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Resetujte terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Podaci će biti izbrisani"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Potvrdi"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Otkaži"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Napravi rezervnu kopiju podataka na <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Oporavak nije uspeo jer pravljenje rezervne kopije nije uspelo"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Oporavak nije uspeo"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Uklanjanje fajla rezervne kopije nije uspelo"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Uklonite rezervnu kopiju"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Obrišite <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Podešavanja"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal je aktivan"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Kliknite da biste otvorili terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Zatvori"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-be/strings.xml b/android/TerminalApp/res/values-be/strings.xml
index 3f8d8c3..a8022ee 100644
--- a/android/TerminalApp/res/values-be/strings.xml
+++ b/android/TerminalApp/res/values-be/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Прызначана <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Максімальны памер: <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Скасаваць"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Ужыць (перазапуск)"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Пераадрасацыя партоў"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Наладзіць пераадрасацыю партоў"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Тэрмінал спрабуе адкрыць новы порт"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Даныя будуць выдалены"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Пацвердзіць"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Скасаваць"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Стварыць рэзервовую копію даных у <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Аднавіць не ўдалося: рэзервовая копія не створана"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Не ўдалося аднавіць"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Не ўдаецца выдаліць файл рэзервовай копіі"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Выдаліць даныя рэзервовай копіі"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Ачысціць <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Налады"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Тэрмінал запушчаны"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Націсніце, каб адкрыць тэрмінал"</string>
diff --git a/android/TerminalApp/res/values-bg/strings.xml b/android/TerminalApp/res/values-bg/strings.xml
index b769b70..a220607 100644
--- a/android/TerminalApp/res/values-bg/strings.xml
+++ b/android/TerminalApp/res/values-bg/strings.xml
@@ -31,21 +31,20 @@
     <string name="vm_creation_message" msgid="6594953532721367502">"Терминалът се подготвя"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"Терминалът спира"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"Терминалът претърпя срив"</string>
-    <string name="settings_disk_resize_title" msgid="1545791169419914600">"Преоразмеряване на диска"</string>
+    <string name="settings_disk_resize_title" msgid="1545791169419914600">"Преораз­меряване на диска"</string>
     <string name="settings_disk_resize_sub_title" msgid="149418971610906138">"Преоразмеряване/Rootfs"</string>
     <string name="settings_disk_resize_resize_message" msgid="5990475712303845087">"Размерът на диска е зададен"</string>
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Зададено: <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Макс.: <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Отказ"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Рестарт за прилагане"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Пренасочване на портове"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Конфигуриране на пренасочването на портове"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Терминалът се опитва да отвори нов порт"</string>
     <string name="settings_port_forwarding_notification_content" msgid="2167103177775323330">"Заявено отваряне на порта: <xliff:g id="PORT_NUMBER">%d</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>
+    <string name="settings_recovery_title" msgid="6586840079226383285">"Възстановя­ване"</string>
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Опции за възстановяване на дяловете"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Промяна към първоначалната версия"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Премахване на всички"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Данните ще бъдат изтрити"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Потвърждаване"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Отказ"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Създаване на резервно копие на данните в(ъв) <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Възстановяването не бе успешно, защото създаването на резервно копие не бе успешно"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Възстановяването не бе успешно"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Файлът с резервното копие не може да се премахне"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Премахване на резервното копие на данните"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Изчистване на <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Настройки"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Терминалът работи"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Кликнете, за да отворите терминала"</string>
diff --git a/android/TerminalApp/res/values-bn/strings.xml b/android/TerminalApp/res/values-bn/strings.xml
index c2b0591..2c0a7cd 100644
--- a/android/TerminalApp/res/values-bn/strings.xml
+++ b/android/TerminalApp/res/values-bn/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"পার্টিশন আগের অবস্থায় ফেরানোর বিকল্প"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"প্রাথমিক ভার্সনে পরিবর্তন করুন"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"সবকটি সরান"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"টার্মিনাল রিসেট করুন"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ডেটা মুছে ফেলা হবে"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"কনফার্ম করুন"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"বাতিল করুন"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"সেটিংস"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"টার্মিনাল চলছে"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"টার্মিনাল খুলতে ক্লিক করুন"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"বন্ধ করুন"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-bs/strings.xml b/android/TerminalApp/res/values-bs/strings.xml
index be174f4..1f64385 100644
--- a/android/TerminalApp/res/values-bs/strings.xml
+++ b/android/TerminalApp/res/values-bs/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Podaci će se izbrisati"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Potvrdi"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Otkaži"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Postavke"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal je pokrenut"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Kliknite da otvorite terminal"</string>
diff --git a/android/TerminalApp/res/values-ca/strings.xml b/android/TerminalApp/res/values-ca/strings.xml
index 05402d1..29891ab 100644
--- a/android/TerminalApp/res/values-ca/strings.xml
+++ b/android/TerminalApp/res/values-ca/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opcions de recuperació de la partició"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Canvia a la versió inicial"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Suprimeix-ho tot"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Restableix el terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Les dades se suprimiran"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirma"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancel·la"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Configuració"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"El terminal s\'està executant"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Fes clic per obrir el terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Tanca"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-cs/strings.xml b/android/TerminalApp/res/values-cs/strings.xml
index 411cf45..9a4a6a8 100644
--- a/android/TerminalApp/res/values-cs/strings.xml
+++ b/android/TerminalApp/res/values-cs/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Přiděleno <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Max. <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Zrušit"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Je třeba restartovat"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Přesměrování portů"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Nakonfigurovat přesměrování portů"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminál se pokouší otevřít nový port"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data budou smazána"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Potvrdit"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Zrušit"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Zálohovat data do <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Obnovení se nezdařilo, protože záloha selhala"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Obnovení se nezdařilo"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Soubor zálohy se nepodařilo odstranit"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Odstranit data zálohy"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Vyčistit <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Nastavení"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminál běží"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Kliknutím otevřete terminál"</string>
diff --git a/android/TerminalApp/res/values-da/strings.xml b/android/TerminalApp/res/values-da/strings.xml
index d29f9d4..f031abf 100644
--- a/android/TerminalApp/res/values-da/strings.xml
+++ b/android/TerminalApp/res/values-da/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Muligheder for gendannelse af partition"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Skift til oprindelig version"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Fjern alle"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Nulstil terminalen"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Dataene slettes"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Bekræft"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Annuller"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Indstillinger"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminalen kører"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Klik for at åbne terminalen"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Luk"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-de/strings.xml b/android/TerminalApp/res/values-de/strings.xml
index cb1a209..3a672f4 100644
--- a/android/TerminalApp/res/values-de/strings.xml
+++ b/android/TerminalApp/res/values-de/strings.xml
@@ -45,7 +45,7 @@
     <string name="settings_port_forwarding_notification_content" msgid="2167103177775323330">"Port, der geöffnet werden soll: <xliff:g id="PORT_NUMBER">%d</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">"Wiederherstellung"</string>
+    <string name="settings_recovery_title" msgid="6586840079226383285">"Wieder­herstellung"</string>
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Optionen für die Partitionswiederherstellung"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Zur ersten Version wechseln"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Alle entfernen"</string>
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Daten werden gelöscht"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Bestätigen"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Abbrechen"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Einstellungen"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal wird ausgeführt"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Zum Öffnen des Terminals klicken"</string>
diff --git a/android/TerminalApp/res/values-el/strings.xml b/android/TerminalApp/res/values-el/strings.xml
index 6df21e4..9036a04 100644
--- a/android/TerminalApp/res/values-el/strings.xml
+++ b/android/TerminalApp/res/values-el/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Ανατέθηκαν <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Έως <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Ακύρωση"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Επανεκ. για εφαρμογή"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Προώθηση θύρας"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Διαμόρφωση προώθησης θύρας"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Το τερματικό προσπαθεί να ανοίξει μια νέα θύρα"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Τα δεδομένα θα διαγραφούν"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Επιβεβαίωση"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Ακύρωση"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Δημιουργία αντιγράφου ασφαλείας δεδομένων στο <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Αποτυχία ανάκτησης λόγω αποτυχίας δημιουργίας αντιγράφου ασφαλείας"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Αποτυχία ανάκτησης"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Δεν είναι δυνατή η κατάργηση του αρχείου αντιγράφου ασφαλείας"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Κατάργηση δεδομένων αντιγράφου ασφαλείας"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Διαγραφή <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Ρυθμίσεις"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Το τερματικό εκτελείται"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Κάντε κλικ για άνοιγμα του τερματικού"</string>
diff --git a/android/TerminalApp/res/values-en-rAU/strings.xml b/android/TerminalApp/res/values-en-rAU/strings.xml
index 9723565..c6641e1 100644
--- a/android/TerminalApp/res/values-en-rAU/strings.xml
+++ b/android/TerminalApp/res/values-en-rAU/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Partition recovery options"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Change to initial version"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Remove all"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Reset terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data will be deleted"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirm"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancel"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Settings"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal is running"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Click to open the terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Close"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-en-rCA/strings.xml b/android/TerminalApp/res/values-en-rCA/strings.xml
index 39eb287..5cab22a 100644
--- a/android/TerminalApp/res/values-en-rCA/strings.xml
+++ b/android/TerminalApp/res/values-en-rCA/strings.xml
@@ -52,6 +52,15 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data will be deleted"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirm"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancel"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Back up data to <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Recovery failed because backup failed"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Recovery failed"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Cannot remove backup file"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Remove backup data"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Clean up <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="error_title" msgid="7196464038692913778">"Unrecoverable Error"</string>
+    <string name="error_desc" msgid="1939028888570920661">"Failed to recover from an error.\nYou can try restart the app, or try one of recovery option."</string>
+    <string name="error_code" msgid="3585291676855383649">"Error code: <xliff:g id="ERROR_CODE">%s</xliff:g>"</string>
     <string name="service_notification_settings" msgid="1437365721184401135">"Settings"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal is running"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Click to open the terminal"</string>
diff --git a/android/TerminalApp/res/values-en-rGB/strings.xml b/android/TerminalApp/res/values-en-rGB/strings.xml
index 9723565..c6641e1 100644
--- a/android/TerminalApp/res/values-en-rGB/strings.xml
+++ b/android/TerminalApp/res/values-en-rGB/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Partition recovery options"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Change to initial version"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Remove all"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Reset terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data will be deleted"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirm"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancel"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Settings"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal is running"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Click to open the terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Close"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-en-rIN/strings.xml b/android/TerminalApp/res/values-en-rIN/strings.xml
index 9723565..c6641e1 100644
--- a/android/TerminalApp/res/values-en-rIN/strings.xml
+++ b/android/TerminalApp/res/values-en-rIN/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Partition recovery options"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Change to initial version"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Remove all"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Reset terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data will be deleted"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirm"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancel"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Settings"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal is running"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Click to open the terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Close"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-es-rUS/strings.xml b/android/TerminalApp/res/values-es-rUS/strings.xml
index aabc20d..934cb48 100644
--- a/android/TerminalApp/res/values-es-rUS/strings.xml
+++ b/android/TerminalApp/res/values-es-rUS/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> asignados"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"<xliff:g id="MAX_SIZE">%1$s</xliff:g> máx."</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Cancelar"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Reiniciar y aplicar"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Redirección de puertos"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Configurar la redirección de puertos"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"La terminal está intentando abrir un puerto nuevo"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Se borrarán los datos"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirmar"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancelar"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Crear una copia de seguridad de los datos en <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Falló la recuperación porque no se pudo crear la copia de seguridad"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Falló la recuperación"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"No se puede quitar el archivo de copia de seguridad"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Quitar datos de copia de seguridad"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Liberar espacio en <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Configuración"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Se está ejecutando la terminal"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Haz clic para abrir la terminal"</string>
diff --git a/android/TerminalApp/res/values-es/strings.xml b/android/TerminalApp/res/values-es/strings.xml
index b239646..e9c3243 100644
--- a/android/TerminalApp/res/values-es/strings.xml
+++ b/android/TerminalApp/res/values-es/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opciones de recuperación de particiones"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Cambiar a versión inicial"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Quitar todo"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Restablecer terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Los datos se eliminarán"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirmar"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancelar"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Ajustes"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"El terminal se está ejecutando"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Toca para abrir el terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Cerrar"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-et/strings.xml b/android/TerminalApp/res/values-et/strings.xml
index fd6b997..f080cbb 100644
--- a/android/TerminalApp/res/values-et/strings.xml
+++ b/android/TerminalApp/res/values-et/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Andmed kustutatakse"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Kinnita"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Tühista"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Seaded"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal töötab"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Klõpsake terminali avamiseks"</string>
diff --git a/android/TerminalApp/res/values-eu/strings.xml b/android/TerminalApp/res/values-eu/strings.xml
index 99cb7b4..efb6d18 100644
--- a/android/TerminalApp/res/values-eu/strings.xml
+++ b/android/TerminalApp/res/values-eu/strings.xml
@@ -39,7 +39,7 @@
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Utzi"</string>
     <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
     <skip />
-    <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Ataka-birbideratzea"</string>
+    <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Ataka-birbideratzU+2060ea"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Konfiguratu ataka-birbideratzea"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminala beste ataka bat irekitzen saiatzen ari da"</string>
     <string name="settings_port_forwarding_notification_content" msgid="2167103177775323330">"Ataka hau irekitzeko eskatu da: <xliff:g id="PORT_NUMBER">%d</xliff:g>"</string>
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Partizioa berreskuratzeko aukerak"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Aldatu hasierako bertsiora"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Kendu guztiak"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Berrezarri terminala"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Datuak ezabatu egingo dira"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Berretsi"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Utzi"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Ezarpenak"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminala abian da"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Egin klik terminala irekitzeko"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Itxi"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-fa/strings.xml b/android/TerminalApp/res/values-fa/strings.xml
index a07b722..8ea8a03 100644
--- a/android/TerminalApp/res/values-fa/strings.xml
+++ b/android/TerminalApp/res/values-fa/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"‫<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> اختصاص یافته است"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"حداکثر <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"لغو"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"بازراه‌اندازی برای اعمال"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"بازارسال درگاه"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"پیکربندی بازارسال درگاه"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"پایانه می‌خواهد درگاه جدیدی باز کند"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"داده‌ها حذف خواهد شد"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"تأیید کردن"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"لغو کردن"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"پشتیبان‌گیری از داده‌ها در <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"بازیابی انجام نشد چون فایل پشتیبان مشکل داشت"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"بازیابی انجام نشد"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"فایل پشتیبان حذف نشد"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"حذف داده‌های پشتیبان"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"پاک‌سازی <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"تنظیمات"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"پایانه درحال اجرا است"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"برای باز کردن پایانه، کلیک کنید"</string>
diff --git a/android/TerminalApp/res/values-fi/strings.xml b/android/TerminalApp/res/values-fi/strings.xml
index 8f98d19..f31d865 100644
--- a/android/TerminalApp/res/values-fi/strings.xml
+++ b/android/TerminalApp/res/values-fi/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Osion palautusvaihtoehdot"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Vaihda ensimmäiseen versioon"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Poista kaikki"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Nollaa terminaali"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data poistetaan"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Vahvista"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Peru"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Asetukset"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Pääte on käynnissä"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Avaa pääte klikkaamalla"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Sulje"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-fr-rCA/strings.xml b/android/TerminalApp/res/values-fr-rCA/strings.xml
index 743129d..556871d 100644
--- a/android/TerminalApp/res/values-fr-rCA/strings.xml
+++ b/android/TerminalApp/res/values-fr-rCA/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Les données seront supprimées"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirmer"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Annuler"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Paramètres"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Le terminal fonctionne"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Cliquez pour ouvrir le terminal"</string>
diff --git a/android/TerminalApp/res/values-fr/strings.xml b/android/TerminalApp/res/values-fr/strings.xml
index 429d51f..c92db16 100644
--- a/android/TerminalApp/res/values-fr/strings.xml
+++ b/android/TerminalApp/res/values-fr/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Les données seront supprimées"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirmer"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Annuler"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Paramètres"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal en cours d\'exécution"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Cliquez pour ouvrir le terminal"</string>
diff --git a/android/TerminalApp/res/values-gl/strings.xml b/android/TerminalApp/res/values-gl/strings.xml
index f81759f..24d7ec1 100644
--- a/android/TerminalApp/res/values-gl/strings.xml
+++ b/android/TerminalApp/res/values-gl/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opcións de recuperación da partición"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Cambiar á versión inicial"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Quita todo"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Restablecer o terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Eliminaranse os datos"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirmar"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancelar"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Configuración"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"O terminal está en funcionamento"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Fai clic para abrir o terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Pechar"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-gu/strings.xml b/android/TerminalApp/res/values-gu/strings.xml
index c93040a..215ae93 100644
--- a/android/TerminalApp/res/values-gu/strings.xml
+++ b/android/TerminalApp/res/values-gu/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ડેટા ડિલીટ કરવામાં આવશે"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"કન્ફર્મ કરો"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"રદ કરો"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"સેટિંગ"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ટર્મિનલ ચાલી રહ્યું છે"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"ટર્મિનલ ખોલવા માટે ક્લિક કરો"</string>
diff --git a/android/TerminalApp/res/values-hi/strings.xml b/android/TerminalApp/res/values-hi/strings.xml
index e626f28..41e4aa3 100644
--- a/android/TerminalApp/res/values-hi/strings.xml
+++ b/android/TerminalApp/res/values-hi/strings.xml
@@ -34,25 +34,36 @@
     <string name="settings_disk_resize_title" msgid="1545791169419914600">"डिस्क का साइज़ बदलें"</string>
     <string name="settings_disk_resize_sub_title" msgid="149418971610906138">"साइज़ बदलें / Rootfs"</string>
     <string name="settings_disk_resize_resize_message" msgid="5990475712303845087">"डिस्क का साइज़ सेट किया गया"</string>
-    <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"असाइन किया गया साइज़: <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
-    <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"ज़्यादा से ज़्यादा साइज़: <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
+    <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> असाइन किया गया"</string>
+    <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"मैक्सिमम <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"रद्द करें"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"रीस्टार्ट करें"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"पोर्ट फ़ॉरवर्डिंग"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"पोर्ट फ़ॉरवर्डिंग को कॉन्फ़िगर करें"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"टर्मिनल, एक नया पोर्ट खोलने की कोशिश कर रहा है"</string>
     <string name="settings_port_forwarding_notification_content" msgid="2167103177775323330">"पोर्ट को खोलने का अनुरोध किया गया: <xliff:g id="PORT_NUMBER">%d</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>
+    <string name="settings_recovery_title" msgid="6586840079226383285">"इमेज रिकवर करें"</string>
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"इमेज के हिस्से को रिकवर करने के विकल्प"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"शुरुआती वर्शन पर स्विच करें"</string>
-    <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"वीएम की सभी इमेज हटाएं"</string>
+    <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"सभी हटाएं"</string>
     <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"टर्मिनल रीसेट करें"</string>
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"डेटा मिटा दिया जाएगा"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"पुष्टि करें"</string>
-    <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"रद्द करें"</string>
+    <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"अभी नहीं"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"<xliff:g id="PATH">/mnt/backup</xliff:g> पर डेटा का बैक अप लें"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"बैकअप पूरा न होने की वजह से, रिकवर नहीं किया जा सका"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"रिकवर नहीं किया जा सका"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"बैकअप फ़ाइल को हटाया नहीं जा सकता"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"बैकअप डेटा हटाएं"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"<xliff:g id="PATH">/mnt/backup</xliff:g> का बैकअप डेटा हटाएं"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"सेटिंग"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"टर्मिनल चालू है"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"टर्मिनल खोलने के लिए क्लिक करें"</string>
diff --git a/android/TerminalApp/res/values-hr/strings.xml b/android/TerminalApp/res/values-hr/strings.xml
index d08d24b..48ed8c4 100644
--- a/android/TerminalApp/res/values-hr/strings.xml
+++ b/android/TerminalApp/res/values-hr/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opcije oporavka particije"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Vrati na početnu verziju"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Ukloni sve"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Poništavanje terminala"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Podaci će se izbrisati"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Potvrdi"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Odustani"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Postavke"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal je pokrenut"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Kliknite da biste otvorili terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Zatvori"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-hu/strings.xml b/android/TerminalApp/res/values-hu/strings.xml
index 1c2bf7c..c1faa9e 100644
--- a/android/TerminalApp/res/values-hu/strings.xml
+++ b/android/TerminalApp/res/values-hu/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Partíció-helyreállítási lehetőségek"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Váltás az eredeti verzióra"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Az összes eltávolítása"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Terminál visszaállítása"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Az adatok törlődni fognak"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Megerősítés"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Mégse"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Beállítások"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"A terminál fut"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Kattintson a terminál megnyitásához"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Bezárás"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-hy/strings.xml b/android/TerminalApp/res/values-hy/strings.xml
index cfaf8ce..475f5f7 100644
--- a/android/TerminalApp/res/values-hy/strings.xml
+++ b/android/TerminalApp/res/values-hy/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Հատկացված է <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Առավելագույնը՝ <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Չեղարկել"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Կիրառելու համար վերագործարկեք"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Միացքի փոխանցում"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Միացքի փոխանցման կազմաձևում"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Տերմինալը փորձում է նոր միացք բացել"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Տվյալները կջնջվեն"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Հաստատել"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Չեղարկել"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Պահուստավորել տվյալները այստեղ՝ <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Պահուստավորման խափանման պատճառով չհաջողվեց վերականգնել"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Չհաջողվեց վերականգնել"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Հնարավոր չէ հեռացնել պահուստային կրկնօրինակի ֆայլը"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Հեռացնել պահուստավորված տվյալները"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Մաքրել ուղին՝ <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Կարգավորումներ"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Տերմինալն աշխատում է"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Սեղմեք՝ տերմինալը բացելու համար"</string>
diff --git a/android/TerminalApp/res/values-in/strings.xml b/android/TerminalApp/res/values-in/strings.xml
index fc0990a..10436a2 100644
--- a/android/TerminalApp/res/values-in/strings.xml
+++ b/android/TerminalApp/res/values-in/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opsi Pemulihan Partisi"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Ubah ke Versi awal"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Hapus semua"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Reset terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data akan dihapus"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Konfirmasi"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Batal"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Setelan"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal sedang berjalan"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Klik untuk membuka terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Tutup"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-is/strings.xml b/android/TerminalApp/res/values-is/strings.xml
index 61ae876..8b27c7c 100644
--- a/android/TerminalApp/res/values-is/strings.xml
+++ b/android/TerminalApp/res/values-is/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Endurheimtarkostir deildar"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Breyta í upphaflega útgáfu"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Fjarlægja allt"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Endurstilla útstöð"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Gögnum verður eytt"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Staðfesta"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Hætta við"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Stillingar"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Útstöð er í gangi"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Smelltu til að opna útstöðina"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Loka"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-it/strings.xml b/android/TerminalApp/res/values-it/strings.xml
index f25c4f9..f59545f 100644
--- a/android/TerminalApp/res/values-it/strings.xml
+++ b/android/TerminalApp/res/values-it/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Assegnato: <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Massimo: <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Annulla"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Riavvia per applic."</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Port forwarding"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Configura port forwarding"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Il terminale sta tentando di aprire una nuova porta"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"I dati verranno eliminati"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Conferma"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Annulla"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Esegui il backup dei dati su <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Recupero non riuscito a causa di un errore di backup"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Recupero non riuscito"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Impossibile rimuovere il file di backup"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Rimuovi i dati di backup"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Pulisci <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Impostazioni"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Il terminale è in esecuzione"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Tocca per aprire il terminale"</string>
diff --git a/android/TerminalApp/res/values-iw/strings.xml b/android/TerminalApp/res/values-iw/strings.xml
index 63207c6..ed5a4e3 100644
--- a/android/TerminalApp/res/values-iw/strings.xml
+++ b/android/TerminalApp/res/values-iw/strings.xml
@@ -31,7 +31,7 @@
     <string name="vm_creation_message" msgid="6594953532721367502">"הטרמינל בהכנה"</string>
     <string name="vm_stop_message" msgid="3978349856095529255">"המערכת עוצרת את הטרמינל"</string>
     <string name="vm_error_message" msgid="5231867246177661525">"הטרמינל קרס"</string>
-    <string name="settings_disk_resize_title" msgid="1545791169419914600">"שינוי הגודל של הדיסק"</string>
+    <string name="settings_disk_resize_title" msgid="1545791169419914600">"שינוי גודל הדיסק"</string>
     <string name="settings_disk_resize_sub_title" msgid="149418971610906138">"שינוי הגודל / Rootfs"</string>
     <string name="settings_disk_resize_resize_message" msgid="5990475712303845087">"גודל הדיסק הוגדר"</string>
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"הוקצו <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"אפשרויות שחזור של המחיצה"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"שינוי לגרסה הראשונית"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"הסרת הכול"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"אתחול הטרמינל"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"הנתונים יימחקו"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"אישור"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"ביטול"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"הגדרות"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"הטרמינל פועל"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"צריך ללחוץ כדי לפתוח את הטרמינל"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"סגירה"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ja/strings.xml b/android/TerminalApp/res/values-ja/strings.xml
index fd06f1e..b2d3b08 100644
--- a/android/TerminalApp/res/values-ja/strings.xml
+++ b/android/TerminalApp/res/values-ja/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> 割り当て済み"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"最大 <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"キャンセル"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"再起動して適用"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"ポート転送"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"ポート転送を設定する"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"ターミナルが新しいポートを開こうとしています"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"データは削除されます"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"確認"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"キャンセル"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"<xliff:g id="PATH">/mnt/backup</xliff:g> にデータをバックアップする"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"バックアップに失敗したため、復元できませんでした"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"復元できませんでした"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"バックアップ ファイルを削除できません"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"バックアップ データの削除"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"<xliff:g id="PATH">/mnt/backup</xliff:g> をクリーンアップする"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"設定"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ターミナルは実行中です"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"クリックするとターミナルが開きます"</string>
diff --git a/android/TerminalApp/res/values-ka/strings.xml b/android/TerminalApp/res/values-ka/strings.xml
index 4c15040..ff27214 100644
--- a/android/TerminalApp/res/values-ka/strings.xml
+++ b/android/TerminalApp/res/values-ka/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"მონაცემები წაიშლება"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"დადასტურება"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"გაუქმება"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"პარამეტრები"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ტერმინალი გაშვებულია"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"დააწკაპუნეთ ტერმინალის გასახსნელად"</string>
diff --git a/android/TerminalApp/res/values-kk/strings.xml b/android/TerminalApp/res/values-kk/strings.xml
index ef81f12..b937cbe 100644
--- a/android/TerminalApp/res/values-kk/strings.xml
+++ b/android/TerminalApp/res/values-kk/strings.xml
@@ -34,7 +34,7 @@
     <string name="settings_disk_resize_title" msgid="1545791169419914600">"Диск көлемін өзгерту"</string>
     <string name="settings_disk_resize_sub_title" msgid="149418971610906138">"Көлемін өзгерту / Rootfs"</string>
     <string name="settings_disk_resize_resize_message" msgid="5990475712303845087">"Диск көлемі орнатылды."</string>
-    <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> тағайындалды."</string>
+    <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> тағайындалды"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Ең көбі <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Бас тарту"</string>
     <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Бөлікті қалпына келтіру опциялары"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Бастапқы нұсқаға өзгерту"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Барлығын өшіру"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Терминалды бастапқы күйге қайтару"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Деректер жойылады."</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Растау"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Бас тарту"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Параметрлер"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Терминал іске қосылып тұр"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Терминалды ашу үшін басыңыз."</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Жабу"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-km/strings.xml b/android/TerminalApp/res/values-km/strings.xml
index af0ec75..53c4f9c 100644
--- a/android/TerminalApp/res/values-km/strings.xml
+++ b/android/TerminalApp/res/values-km/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ទិន្នន័យនឹងត្រូវបានលុប"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"បញ្ជាក់"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"បោះបង់"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ការកំណត់"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ទែមីណាល់កំពុងដំណើរការ"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"ចុចដើម្បីបើកទែមីណាល់"</string>
diff --git a/android/TerminalApp/res/values-kn/strings.xml b/android/TerminalApp/res/values-kn/strings.xml
index b6d52ef..bd2fb6d 100644
--- a/android/TerminalApp/res/values-kn/strings.xml
+++ b/android/TerminalApp/res/values-kn/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> ನಿಯೋಜಿಸಲಾಗಿದೆ"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"ಗರಿಷ್ಠ <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"ರದ್ದುಮಾಡಿ"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"ಅನ್ವಯಿಸಲು ಮರುಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"ಪೋರ್ಟ್ ಫಾರ್ವರ್ಡ್ ಮಾಡುವಿಕೆ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"ಪೋರ್ಟ್ ಫಾರ್ವರ್ಡ್ ಮಾಡುವಿಕೆಯನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"ಟರ್ಮಿನಲ್‌ ಹೊಸ ಪೋರ್ಟ್‌ ಅನ್ನು ತೆರೆಯಲು ಪ್ರಯತ್ನಿಸುತ್ತಿದೆ"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"ದೃಢೀಕರಿಸಿ"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"ರದ್ದುಮಾಡಿ"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"ಡೇಟಾವನ್ನು <xliff:g id="PATH">/mnt/backup</xliff:g> ಗೆ ಬ್ಯಾಕಪ್‌ ಮಾಡಿ"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"ಬ್ಯಾಕಪ್‌ ವಿಫಲವಾದ ಕಾರಣ ರಿಕವರಿ ವಿಫಲವಾಗಿದೆ"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"ರಿಕವರಿ ವಿಫಲವಾಗಿದೆ"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"ಬ್ಯಾಕಪ್‌ ಫೈಲ್‌ ಅನ್ನು ತೆಗೆದುಹಾಕಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"ಬ್ಯಾಕಪ್‌ ಡೇಟಾವನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"<xliff:g id="PATH">/mnt/backup</xliff:g> ಅನ್ನು ಕ್ಲೀನ್‌ ಅಪ್‌ ಮಾಡಿ"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ಟರ್ಮಿನಲ್‌ ರನ್‌ ಆಗುತ್ತಿದೆ"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"ಟರ್ಮಿನಲ್‌ ಅನ್ನು ತೆರೆಯಲು ಕ್ಲಿಕ್‌ ಮಾಡಿ"</string>
diff --git a/android/TerminalApp/res/values-ko/strings.xml b/android/TerminalApp/res/values-ko/strings.xml
index 897f2bf..4c3d89a 100644
--- a/android/TerminalApp/res/values-ko/strings.xml
+++ b/android/TerminalApp/res/values-ko/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"파티션 복구 옵션"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"최초 버전으로 변경"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"전체 삭제"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"터미널 재설정"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"데이터가 삭제됩니다."</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"확인"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"취소"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"설정"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"터미널이 실행 중입니다"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"터미널을 열려면 클릭하세요."</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"닫기"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ky/strings.xml b/android/TerminalApp/res/values-ky/strings.xml
index dde2665..204050c 100644
--- a/android/TerminalApp/res/values-ky/strings.xml
+++ b/android/TerminalApp/res/values-ky/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Катуу диск бөлүгүн калыбына келтирүү параметрлери"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Баштапкы версияга өзгөртүү"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Баарын өчүрүү"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Терминалды баштапкы абалга келтирүү"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Маалымат өчүрүлөт"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Ырастоо"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Жокко чыгаруу"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Параметрлер"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Терминал иштеп жатат"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Терминалды ачуу үчүн чыкылдатыңыз"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Жабуу"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-lo/strings.xml b/android/TerminalApp/res/values-lo/strings.xml
index 3fff30b..205168b 100644
--- a/android/TerminalApp/res/values-lo/strings.xml
+++ b/android/TerminalApp/res/values-lo/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"ມອບໝາຍແລ້ວ <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"ສູງສຸດ <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"ຍົກເລີກ"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"ຣີສະຕາດເພື່ອນຳໃຊ້"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"ການ​ສົ່ງ​ຕໍ່​ຜອດ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"ຕັ້ງຄ່າການ​ສົ່ງ​ຕໍ່​ຜອດ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"ເທີມິນອນກຳລັງພະຍາຍາມເປີດ​ຜອດໃໝ່"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ຂໍ້ມູນຈະຖືກລຶບ"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"ຢືນຢັນ"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"ຍົກເລີກ"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"ສຳຮອງຂໍ້ມູນໃສ່ <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"ການກູ້ຄືນບໍ່ສຳເລັດຍ້ອນການສຳຮອງຂໍ້ມູນບໍ່ສຳເລັດ"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"ການກູ້ຄືນບໍ່ສຳເລັດ"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"ບໍ່ສາມາດລຶບໄຟລ໌ສຳຮອງຂໍ້ມູນອອກໄດ້"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"ລຶບການສຳຮອງຂໍ້ມູນອອກ"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"ອະນາໄມ <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ການຕັ້ງຄ່າ"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ເທີມິນອນກຳລັງເຮັດວຽກຢູ່"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"ຄລິກເພື່ອເປີດເທີມິນອນ"</string>
diff --git a/android/TerminalApp/res/values-lt/strings.xml b/android/TerminalApp/res/values-lt/strings.xml
index 4cb3326..313eb7b 100644
--- a/android/TerminalApp/res/values-lt/strings.xml
+++ b/android/TerminalApp/res/values-lt/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Priskirta <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Maks. <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Atšaukti"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"P. iš n., kad prit."</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Prievado numerio persiuntimas"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Prievado numerio persiuntimo konfigūravimas"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminalas bando atidaryti naują prievadą"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Duomenys bus ištrinti"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Patvirtinti"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Atšaukti"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Sukurti atsarginę duomenų kopiją čia: <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Nepavyko atkurti, nes nepavyko sukurti atsarginės kopijos"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Nepavyko atkurti"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Nepavyko pašalinti atsarginės kopijos failo"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Pašalinti atsarginės kopijos duomenis"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Išvalyti <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Nustatymai"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminalas veikia"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Spustelėkite, kad atidarytumėte terminalą"</string>
diff --git a/android/TerminalApp/res/values-lv/strings.xml b/android/TerminalApp/res/values-lv/strings.xml
index ceaaae6..ad75e41 100644
--- a/android/TerminalApp/res/values-lv/strings.xml
+++ b/android/TerminalApp/res/values-lv/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Nodalījuma atkopšanas opcijas"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Mainīšana uz sākotnējo versiju"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Noņemt visu"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Termināļa atiestatīšana"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Dati tiks izdzēsti"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Apstiprināt"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Atcelt"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Iestatījumi"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminālis darbojas"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Noklikšķiniet, lai atvērtu termināli"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Aizvērt"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-mk/strings.xml b/android/TerminalApp/res/values-mk/strings.xml
index 86fd666..7bbdc3f 100644
--- a/android/TerminalApp/res/values-mk/strings.xml
+++ b/android/TerminalApp/res/values-mk/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Опции за враќање партиции"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Промени на првата верзија"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Отстрани ги сите"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Ресетирајте го терминалот"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Податоците ќе се избришат"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Потврди"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Откажи"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Поставки"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Терминалот е активен"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Кликнете за да го отворите терминалот"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Затвори"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ml/strings.xml b/android/TerminalApp/res/values-ml/strings.xml
index 232aba7..11639ee 100644
--- a/android/TerminalApp/res/values-ml/strings.xml
+++ b/android/TerminalApp/res/values-ml/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> അസൈൻ ചെയ്‌തു"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"പരമാവധി <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"റദ്ദാക്കുക"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"പ്രയോഗിക്കാൻ റീസ്റ്റാർട്ട് ചെയ്യൂ"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"പോർട്ട് ഫോർവേഡിങ്"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"പോർട്ട് ഫോർവേഡിങ് കോൺഫിഗർ ചെയ്യുക"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"ഒരു പുതിയ പോർട്ട് തുറക്കാൻ ടെർമിനൽ ശ്രമിക്കുന്നു"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ഡാറ്റ ഇല്ലാതാക്കും"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"സ്ഥിരീകരിക്കുക"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"റദ്ദാക്കുക"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"<xliff:g id="PATH">/mnt/backup</xliff:g> എന്നതിലേക്ക് ഡാറ്റ ബാക്കപ്പെടുക്കുക"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"ബാക്കപ്പ് ചെയ്യാനാകാത്തതിനാൽ വീണ്ടെടുക്കാനായില്ല"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"വീണ്ടെടുക്കാനായില്ല"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"ബാക്കപ്പ് ഫയൽ നീക്കം ചെയ്യാനാകില്ല"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"ബാക്കപ്പ് ഡാറ്റ നീക്കം ചെയ്യുക"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"<xliff:g id="PATH">/mnt/backup</xliff:g> ക്ലീനപ്പ് ചെയ്യുക"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ക്രമീകരണം"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ടെർമിനൽ റൺ ചെയ്യുന്നു"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"ടെർമിനൽ തുറക്കാൻ ക്ലിക്ക് ചെയ്യുക"</string>
diff --git a/android/TerminalApp/res/values-mn/strings.xml b/android/TerminalApp/res/values-mn/strings.xml
index 63a8e76..0a751ae 100644
--- a/android/TerminalApp/res/values-mn/strings.xml
+++ b/android/TerminalApp/res/values-mn/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Хуваалтыг сэргээх сонголтууд"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Анхны хувилбар луу өөрчлөх"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Бүгдийг хасах"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Терминалыг шинэчлэх"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Өгөгдлийг устгана"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Баталгаажуулах"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Цуцлах"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Тохиргоо"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Терминал ажиллаж байна"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Терминалыг нээхийн тулд товшино уу"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Хаах"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-mr/strings.xml b/android/TerminalApp/res/values-mr/strings.xml
index 854af10..b184293 100644
--- a/android/TerminalApp/res/values-mr/strings.xml
+++ b/android/TerminalApp/res/values-mr/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"डेटा हटवला जाईल"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"कन्फर्म करा"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"रद्द करा"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"सेटिंग्ज"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"टर्मिनल रन होत आहे"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"टर्मिनल उघडण्यासाठी क्लिक करा"</string>
diff --git a/android/TerminalApp/res/values-ms/strings.xml b/android/TerminalApp/res/values-ms/strings.xml
index fcbe880..be48937 100644
--- a/android/TerminalApp/res/values-ms/strings.xml
+++ b/android/TerminalApp/res/values-ms/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> ditetapkan"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Maksimum <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Batal"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Mulakan semula untuk gunakan"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Kiriman Semula Port"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Konfigurasikan kiriman semula port"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminal sedang cuba membuka port baharu"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data akan dipadamkan"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Sahkan"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Batal"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Sandarkan data kepada <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Pemulihan gagal kerana sandaran telah gagal"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Pemulihan gagal"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Tidak dapat mengalih keluar fail sandaran"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Alih keluar data sandaran"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Bersihkan <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Tetapan"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal sedang dijalankan"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Klik untuk membuka terminal"</string>
diff --git a/android/TerminalApp/res/values-my/strings.xml b/android/TerminalApp/res/values-my/strings.xml
index 7793026..a740324 100644
--- a/android/TerminalApp/res/values-my/strings.xml
+++ b/android/TerminalApp/res/values-my/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ဒေတာကို ဖျက်ပါမည်"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"အတည်ပြုရန်"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"မလုပ်တော့"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ဆက်တင်များ"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"တာမီနယ်ကို ဖွင့်ထားသည်"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"တာမီနယ်ဖွင့်ရန် နှိပ်ပါ"</string>
diff --git a/android/TerminalApp/res/values-nb/strings.xml b/android/TerminalApp/res/values-nb/strings.xml
index 3178000..4c14dea 100644
--- a/android/TerminalApp/res/values-nb/strings.xml
+++ b/android/TerminalApp/res/values-nb/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Gjenopprettingsalternativer for partisjoner"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Bytt til første versjon"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Fjern alle"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Tilbakestill terminalen"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Dataene slettes"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Bekreft"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Avbryt"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Innstillinger"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminalen kjører"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Klikk for å åpne terminalen"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Lukk"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ne/strings.xml b/android/TerminalApp/res/values-ne/strings.xml
index 3646528..3be68ae 100644
--- a/android/TerminalApp/res/values-ne/strings.xml
+++ b/android/TerminalApp/res/values-ne/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"असाइन गरिएको: <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"अधिकतम <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"रद्द गर्नुहोस्"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"परिवर्तन लागू गर्न रिस्टार्ट गर्नुहोस्"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"पोर्ट फर्वार्डिङ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"पोर्ट फर्वार्डिङ कन्फिगर गर्नुहोस्"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"टर्मिनलले एउटा नयाँ पोर्ट खोल्न खोजिरहेको छ"</string>
@@ -49,15 +48,24 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"पार्टिसन रिकभरीसम्बन्धी विकल्पहरू"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"यो संस्करण बदलेर सुरुको संस्करण बनाउनुहोस्"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"सबै हटाउनुहोस्"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"टर्मिनल रिसेट गर्नुहोस्"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"डेटा मेटाइने छ"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"पुष्टि गर्नुहोस्"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"रद्द गर्नुहोस्"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"<xliff:g id="PATH">/mnt/backup</xliff:g> मा डेटा ब्याकअप गर्नुहोस्"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"ब्याकअप गर्न नसकिएकाले रिकभर गर्न सकिएन"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"रिकभर गर्न सकिएन"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"ब्याकअप फाइल हटाउन सकिएन"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"ब्याकअप डेटा हटाउनुहोस्"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"<xliff:g id="PATH">/mnt/backup</xliff:g> हटाउनुहोस्"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"सेटिङ"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"टर्मिनल चलिरहेको छ"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"यो टर्मिनल खोल्न क्लिक गर्नुहोस्"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"बन्द गर्नुहोस्"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-nl/strings.xml b/android/TerminalApp/res/values-nl/strings.xml
index c06ea33..c6e1308 100644
--- a/android/TerminalApp/res/values-nl/strings.xml
+++ b/android/TerminalApp/res/values-nl/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> toegewezen"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"<xliff:g id="MAX_SIZE">%1$s</xliff:g> max."</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Annuleren"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Opnieuw opstarten om toe te passen"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Poort­doorschakeling"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Poortdoorschakeling instellen"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminal probeert een nieuwe poort te openen"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Gegevens worden verwijderd"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Bevestigen"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Annuleren"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Back-up van gegevens maken in <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Herstel is mislukt omdat de back-up is mislukt"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Herstel is mislukt"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Kan back-upbestand niet verwijderen"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Back-upgegevens verwijderen"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"<xliff:g id="PATH">/mnt/backup</xliff:g> opschonen"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Instellingen"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal wordt uitgevoerd"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Klik om de terminal te openen"</string>
diff --git a/android/TerminalApp/res/values-or/strings.xml b/android/TerminalApp/res/values-or/strings.xml
index 00c9f85..00825e6 100644
--- a/android/TerminalApp/res/values-or/strings.xml
+++ b/android/TerminalApp/res/values-or/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"ପାର୍ଟିସନ ରିକଭରି ବିକଳ୍ପ"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"ପ୍ରାରମ୍ଭିକ ଭର୍ସନକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"ସବୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"ଟର୍ମିନାଲ ରିସେଟ କରନ୍ତୁ"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ଡାଟାକୁ ଡିଲିଟ କରାଯିବ"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"ବାତିଲ କରନ୍ତୁ"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ସେଟିଂସ"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ଟର୍ମିନାଲ ଚାଲୁ ଅଛି"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"ଟର୍ମିନାଲ ଖୋଲିବାକୁ କ୍ଲିକ କରନ୍ତୁ"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"ବନ୍ଦ କରନ୍ତୁ"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-pa/strings.xml b/android/TerminalApp/res/values-pa/strings.xml
index 47f7aa6..74a565f 100644
--- a/android/TerminalApp/res/values-pa/strings.xml
+++ b/android/TerminalApp/res/values-pa/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> ਜ਼ਿੰਮੇ ਲਗਾਇਆ ਗਿਆ"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"ਵੱਧੋ-ਵੱਧ <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"ਰੱਦ ਕਰੋ"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"ਲਾਗੂ ਕਰਨ ਲਈ ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"ਪੋਰਟ ਫਾਰਵਰਡਿੰਗ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"ਪੋਰਟ ਫਾਰਵਰਡਿੰਗ ਦਾ ਸੰਰੂਪਣ ਕਰੋ"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"ਟਰਮੀਨਲ ਇੱਕ ਨਵੇਂ ਪੋਰਟ ਨੂੰ ਖੋਲ੍ਹਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰ ਰਿਹਾ ਹੈ"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"ਤਸਦੀਕ ਕਰੋ"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"ਰੱਦ ਕਰੋ"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"<xliff:g id="PATH">/mnt/backup</xliff:g> \'ਤੇ ਡਾਟੇ ਦਾ ਬੈਕਅੱਪ ਲਓ"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"ਮੁੜ-ਹਾਸਲ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ, ਕਿਉਂਕਿ ਬੈਕਅੱਪ ਅਸਫਲ ਰਿਹਾ"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"ਮੁੜ-ਹਾਸਲ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"ਬੈਕਅੱਪ ਫ਼ਾਈਲ ਹਟਾਈ ਨਹੀਂ ਜਾ ਸਕਦੀ"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"ਬੈਕਅੱਪ ਡਾਟਾ ਹਟਾਓ"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"<xliff:g id="PATH">/mnt/backup</xliff:g> ਨੂੰ ਕਲੀਨ ਅੱਪ ਕਰੋ"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ਟਰਮੀਨਲ ਚਾਲੂ ਹੈ"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"ਟਰਮੀਨਲ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਕਲਿੱਕ ਕਰੋ"</string>
diff --git a/android/TerminalApp/res/values-pl/strings.xml b/android/TerminalApp/res/values-pl/strings.xml
index 0f561c8..0e17fb0 100644
--- a/android/TerminalApp/res/values-pl/strings.xml
+++ b/android/TerminalApp/res/values-pl/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Przypisano <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Maksymalny rozmiar <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Anuluj"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Uruchom ponownie"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Przekierowanie portów"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Skonfiguruj przekierowanie portów"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminal próbuje otworzyć nowy port"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Dane zostaną usunięte"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Potwierdź"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Anuluj"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Utwórz kopię zapasową w lokalizacji <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Nie udało się przywrócić danych z powodu błędu kopii zapasowej"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Nie udało się przywrócić"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Nie udało się usunąć pliku kopii zapasowej"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Usuń dane kopii zapasowej"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Zwolnij miejsce w lokalizacji <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Ustawienia"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal jest uruchomiony"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Kliknij, aby otworzyć terminal"</string>
diff --git a/android/TerminalApp/res/values-pt-rPT/strings.xml b/android/TerminalApp/res/values-pt-rPT/strings.xml
index ab08a1d..9d6af92 100644
--- a/android/TerminalApp/res/values-pt-rPT/strings.xml
+++ b/android/TerminalApp/res/values-pt-rPT/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Tamanho atribuído: <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Tamanho máx.: <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Cancelar"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Reiniciar p/ aplicar"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Encaminhamento de portas"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Configure o encaminhamento de portas"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"O terminal está a tentar abrir uma nova porta"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Os dados vão ser eliminados"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirmar"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancelar"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Fazer uma cópia de segurança dos dados para <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"A recuperação falhou porque ocorreu uma falha na cópia de segurança"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Falha na recuperação"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Não é possível remover o ficheiro da cópia de segurança"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Remova os dados da cópia de segurança"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Limpe <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Definições"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"O terminal está em execução"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Clique para abrir o terminal"</string>
diff --git a/android/TerminalApp/res/values-pt/strings.xml b/android/TerminalApp/res/values-pt/strings.xml
index 5848f9a..a6dbef4 100644
--- a/android/TerminalApp/res/values-pt/strings.xml
+++ b/android/TerminalApp/res/values-pt/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opções de recuperação da partição"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Mudar para a versão inicial"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Remover tudo"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Redefinir terminal"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Os dados serão excluídos"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirmar"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Cancelar"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Configurações"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"O terminal está em execução"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Clique para abrir o terminal"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Fechar"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ro/strings.xml b/android/TerminalApp/res/values-ro/strings.xml
index 0a4e791..ee2db81 100644
--- a/android/TerminalApp/res/values-ro/strings.xml
+++ b/android/TerminalApp/res/values-ro/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opțiuni de recuperare a partițiilor"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Schimbă la versiunea inițială"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Elimină-le pe toate"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Resetează terminalul"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Datele se vor șterge"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Confirmă"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Anulează"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Setări"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminalul rulează"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Dă clic pentru a deschide terminalul"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Închide"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ru/strings.xml b/android/TerminalApp/res/values-ru/strings.xml
index 3fd6ed5..30b22e8 100644
--- a/android/TerminalApp/res/values-ru/strings.xml
+++ b/android/TerminalApp/res/values-ru/strings.xml
@@ -45,19 +45,34 @@
     <string name="settings_port_forwarding_notification_content" msgid="2167103177775323330">"Запрашивается разрешение открыть порт <xliff:g id="PORT_NUMBER">%d</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>
+    <string name="settings_recovery_title" msgid="6586840079226383285">"Восста­но­вле­ние"</string>
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Варианты восстановления разделов"</string>
-    <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Восстановить первоначальную версию"</string>
+    <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Перейти к исходной версии"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Удалить все"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Сброс настроек терминала"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Данные будут удалены."</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Подтвердить"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Отмена"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Настройки"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Терминал запущен"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Нажмите, чтобы открыть его."</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Закрыть"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-si/strings.xml b/android/TerminalApp/res/values-si/strings.xml
index 9132eeb..f2d4d8b 100644
--- a/android/TerminalApp/res/values-si/strings.xml
+++ b/android/TerminalApp/res/values-si/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"දත්ත මකනු ඇත"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"තහවුරු කරන්න"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"අවලංගු කරන්න"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"සැකසීම්"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"පර්යන්තය ධාවනය වේ"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"ටර්මිනලය විවෘත කිරීමට ක්ලික් කරන්න"</string>
diff --git a/android/TerminalApp/res/values-sk/strings.xml b/android/TerminalApp/res/values-sk/strings.xml
index f5e4ff7..151a592 100644
--- a/android/TerminalApp/res/values-sk/strings.xml
+++ b/android/TerminalApp/res/values-sk/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Možnosti obnovenia oddielu"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Zmena na pôvodnú verziu"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Odstrániť všetko"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Resetovanie terminálu"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Údaje budú odstránené"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Potvrdiť"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Zrušiť"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Nastavenia"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminál je spustený"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Kliknutím otvorte terminál"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Zavrieť"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sl/strings.xml b/android/TerminalApp/res/values-sl/strings.xml
index 5701219..925170d 100644
--- a/android/TerminalApp/res/values-sl/strings.xml
+++ b/android/TerminalApp/res/values-sl/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Dodeljeno: <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Največja velikost: <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Prekliči"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Znova zaženi za uporabo"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Posredovanje vrat"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Konfiguriranje posredovanja vrat"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminal poskuša odpreti nova vrata"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Podatki bodo izbrisani"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Potrdi"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Prekliči"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Varnostno kopiranje podatkov v <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Obnovitev ni uspela zaradi neuspešnega varnostnega kopiranja"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Obnovitev ni uspela"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Datoteke z varnostno kopijo ni mogoče odstraniti"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Odstranitev varnostno kopiranih podatkov"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Počiščenje poti <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Nastavitve"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal se izvaja"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Kliknite, če želite odpreti terminal"</string>
diff --git a/android/TerminalApp/res/values-sq/strings.xml b/android/TerminalApp/res/values-sq/strings.xml
index afc9e8d..18c1b44 100644
--- a/android/TerminalApp/res/values-sq/strings.xml
+++ b/android/TerminalApp/res/values-sq/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Opsionet e rikuperimit të ndarjes"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Ndrysho në versionin fillestar"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Hiqi të gjitha"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Rivendos terminalin"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Të dhënat do të fshihen"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Konfirmo"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Anulo"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Cilësimet"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminali po ekzekutohet"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Kliko për të hapur terminalin"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Mbyll"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sr/strings.xml b/android/TerminalApp/res/values-sr/strings.xml
index 934fc3b..0184819 100644
--- a/android/TerminalApp/res/values-sr/strings.xml
+++ b/android/TerminalApp/res/values-sr/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"Додељено <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Макс. <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Откажи"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Рестартуј и примени"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Прослеђивање порта"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Конфигуришите прослеђивање порта"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Терминал покушава да отвори нови порт"</string>
@@ -49,15 +48,24 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Опције опоравка партиција"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Промени на почетну верзију"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Уклоните све"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Ресетујте терминал"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Подаци ће бити избрисани"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Потврди"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Откажи"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Направи резервну копију података на <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Опоравак није успео јер прављење резервне копије није успело"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Опоравак није успео"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Уклањање фајла резервне копије није успело"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Уклоните резервну копију"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Обришите <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Подешавања"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Терминал је активан"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Кликните да бисте отворили терминал"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Затвори"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sv/strings.xml b/android/TerminalApp/res/values-sv/strings.xml
index 6fd87a5..24f2696 100644
--- a/android/TerminalApp/res/values-sv/strings.xml
+++ b/android/TerminalApp/res/values-sv/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Återställningsalternativ för partition"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Ändra till ursprunglig version"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Ta bort alla"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Återställ terminalen"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data raderas"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Bekräfta"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Avbryt"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Inställningar"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminalen körs"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Klicka för att öppna terminalen"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Stäng"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-sw/strings.xml b/android/TerminalApp/res/values-sw/strings.xml
index 50920e9..6759537 100644
--- a/android/TerminalApp/res/values-sw/strings.xml
+++ b/android/TerminalApp/res/values-sw/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Chaguo za kurejesha data ya sehemu"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Rudi kwenye Toleo la awali"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Ondoa yote"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Badilisha temino"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Data itafutwa"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Thibitisha"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Acha"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Mipangilio"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Temino inatumika"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Bofya ili ufungue temino"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Funga"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ta/strings.xml b/android/TerminalApp/res/values-ta/strings.xml
index 07efaeb..800185c 100644
--- a/android/TerminalApp/res/values-ta/strings.xml
+++ b/android/TerminalApp/res/values-ta/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> ஒதுக்கப்பட்டது"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"அதிகபட்சம் <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"ரத்துசெய்"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"பயன்படுத்த தொடங்குக"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"போர்ட் அனுப்புதல்"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"போர்ட் அனுப்புதலை உள்ளமைத்தல்"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"டெர்மினல் புதிய போர்ட்டைத் திறக்க முயல்கிறது"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"தரவு நீக்கப்படும்"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"உறுதிசெய்"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"ரத்துசெய்"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"<xliff:g id="PATH">/mnt/backup</xliff:g> இல் உள்ள தரவைக் காப்புப் பிரதி எடுத்தல்"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"காப்புப் பிரதி எடுத்தல் தோல்வியடைந்ததால் மீட்டெடுக்க முடியவில்லை"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"மீட்டெடுக்க முடியவில்லை"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"காப்புப் பிரதி ஃபைலை அகற்ற முடியவில்லை"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"காப்புப் பிரதித் தரவை அகற்றுதல்"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"<xliff:g id="PATH">/mnt/backup</xliff:g> ஐக் காலியாக்குதல்"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"அமைப்புகள்"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"டெர்மினல் இயக்கத்தில் உள்ளது"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"டெர்மினலைத் திறக்க கிளிக் செய்யுங்கள்"</string>
diff --git a/android/TerminalApp/res/values-te/strings.xml b/android/TerminalApp/res/values-te/strings.xml
index 1c670a1..0e9ce4f 100644
--- a/android/TerminalApp/res/values-te/strings.xml
+++ b/android/TerminalApp/res/values-te/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"డేటా తొలగించబడుతుంది"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"నిర్ధారించండి"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"రద్దు చేయండి"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"సెట్టింగ్‌లు"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"టెర్మినల్ రన్ అవుతోంది"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"టెర్మినల్‌ను తెరవడానికి క్లిక్ చేయండి"</string>
diff --git a/android/TerminalApp/res/values-th/strings.xml b/android/TerminalApp/res/values-th/strings.xml
index 4cc93a6..dbcabd3 100644
--- a/android/TerminalApp/res/values-th/strings.xml
+++ b/android/TerminalApp/res/values-th/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"กำหนดขนาด <xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> แล้ว"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"สูงสุด <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"ยกเลิก"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"รีสตาร์ทเพื่อใช้"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"การส่งต่อพอร์ต"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"กำหนดค่าการส่งต่อพอร์ต"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"เทอร์มินัลกำลังพยายามเปิดพอร์ตใหม่"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ระบบจะลบข้อมูล"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"ยืนยัน"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"ยกเลิก"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"สำรองข้อมูลไปยัง <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"กู้คืนไม่สำเร็จเนื่องจากสำรองข้อมูลไม่สำเร็จ"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"การกู้คืนไม่สำเร็จ"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"นำไฟล์ข้อมูลสำรองออกไม่ได้"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"นําข้อมูลสํารองออก"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"ล้าง <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"การตั้งค่า"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"เทอร์มินัลกำลังทำงาน"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"คลิกเพื่อเปิดเทอร์มินัล"</string>
diff --git a/android/TerminalApp/res/values-tl/strings.xml b/android/TerminalApp/res/values-tl/strings.xml
index d8dd2ca..0b079c0 100644
--- a/android/TerminalApp/res/values-tl/strings.xml
+++ b/android/TerminalApp/res/values-tl/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> ang nakatalaga"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"<xliff:g id="MAX_SIZE">%1$s</xliff:g> ang max"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Kanselahin"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"I-restart para gawin"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Pag-forward ng Port"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"I-configure ang pag-forward ng port"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Sinusubukan ng terminal na magbukas ng bagong port"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Made-delete ang data"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Kumpirmahin"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Kanselahin"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Mag-back up ng data sa <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Hindi na-recover dahil hindi gumana ang backup"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Hindi na-recover"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Hindi maalis ang backup file"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Alisin ang backup data"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"I-clean up ang <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Mga Setting"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Gumagana ang terminal"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"I-click para buksan ang terminal"</string>
diff --git a/android/TerminalApp/res/values-tr/strings.xml b/android/TerminalApp/res/values-tr/strings.xml
index c696eda..f4590c7 100644
--- a/android/TerminalApp/res/values-tr/strings.xml
+++ b/android/TerminalApp/res/values-tr/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Bölüm kurtarma seçenekleri"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"İlk sürüme geç"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Tümünü kaldır"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Terminali sıfırla"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Veriler silinecek"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Onayla"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"İptal"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Ayarlar"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal çalışıyor"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Terminali açmak için tıklayın"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Kapat"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-uk/strings.xml b/android/TerminalApp/res/values-uk/strings.xml
index f5a405d..757e7aa 100644
--- a/android/TerminalApp/res/values-uk/strings.xml
+++ b/android/TerminalApp/res/values-uk/strings.xml
@@ -47,17 +47,32 @@
     <string name="settings_port_forwarding_notification_deny" msgid="636848749634710403">"Відхилити"</string>
     <string name="settings_recovery_title" msgid="6586840079226383285">"Відновлення"</string>
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Способи відновлення розділів"</string>
-    <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Зміна на початкову версію"</string>
-    <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Видалити всі"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Змінити на початкову версію"</string>
+    <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Видалити все"</string>
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Скинути налаштування термінала"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Дані буде видалено"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Підтвердити"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Скасувати"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Налаштування"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Термінал запущено"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Натисніть, щоб відкрити термінал"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Закрити"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-ur/strings.xml b/android/TerminalApp/res/values-ur/strings.xml
index 1ffd3c5..473f093 100644
--- a/android/TerminalApp/res/values-ur/strings.xml
+++ b/android/TerminalApp/res/values-ur/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> تفویض کردہ"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"زیادہ سے زیادہ <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"منسوخ کریں"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"لاگو کرنے کے لیے ری سٹارٹ کریں"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"پورٹ فارورڈنگ"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"پورٹ فارورڈنگ کو کنفیگر کریں"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"ٹرمینل ایک نیا پورٹ کھولنے کی کوشش کر رہا ہے"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"ڈیٹا حذف کر دیا جائے گا"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"تصدیق کریں"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"منسوخ کریں"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"‫<xliff:g id="PATH">/mnt/backup</xliff:g> پر ڈیٹا کا بیک اپ لیں"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"بیک اپ ناکام ہونے کی وجہ سے بازیابی ناکام ہو گئی"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"بازیابی ناکام ہو گئی"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"بیک اپ فائل کو ہٹایا نہیں جا سکتا"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"بیک اپ ڈیٹا ہٹائیں"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"‫<xliff:g id="PATH">/mnt/backup</xliff:g> کو ہٹائیں"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"ترتیبات"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"ٹرمینل چل رہا ہے"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"ٹرمینل کھولنے کے لیے کلک کریں"</string>
diff --git a/android/TerminalApp/res/values-uz/strings.xml b/android/TerminalApp/res/values-uz/strings.xml
index c2208ba..63f736b 100644
--- a/android/TerminalApp/res/values-uz/strings.xml
+++ b/android/TerminalApp/res/values-uz/strings.xml
@@ -37,8 +37,7 @@
     <string name="settings_disk_resize_resize_gb_assigned_format" msgid="109301857555401579">"<xliff:g id="ASSIGNED_SIZE">%1$s</xliff:g> ajratilgan"</string>
     <string name="settings_disk_resize_resize_gb_max_format" msgid="6221210151688630371">"Maks <xliff:g id="MAX_SIZE">%1$s</xliff:g>"</string>
     <string name="settings_disk_resize_resize_cancel" msgid="2182388126941686562">"Bekor qilish"</string>
-    <!-- no translation found for settings_disk_resize_resize_restart_vm_to_apply (83303619015991908) -->
-    <skip />
+    <string name="settings_disk_resize_resize_restart_vm_to_apply" msgid="83303619015991908">"Qoʻllash uchun qayta yoqing"</string>
     <string name="settings_port_forwarding_title" msgid="4867439149919324784">"Portni uzatish"</string>
     <string name="settings_port_forwarding_sub_title" msgid="6848040752531535488">"Portni uzatish sozlamalari"</string>
     <string name="settings_port_forwarding_notification_title" msgid="2822798067500254704">"Terminal yangi port ochishga urinmoqda"</string>
@@ -53,6 +52,18 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Maʼlumotlar oʻchib ketadi"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Tasdiqlash"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Bekor qilish"</string>
+    <string name="settings_recovery_reset_dialog_backup_option" msgid="2079431035205584614">"Maʼlumotlarni bu yerga zaxiralash: <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <string name="settings_recovery_error_due_to_backup" msgid="2129959464075410607">"Zaxiralash amalga oshmagani uchun tiklanmadi"</string>
+    <string name="settings_recovery_error" msgid="2451912941535666379">"Tiklanmadi"</string>
+    <string name="settings_recovery_error_during_removing_backup" msgid="6515615177661212463">"Zaxira fayli olib tashlanmadi"</string>
+    <string name="settings_recovery_remove_backup_title" msgid="1540850288876158899">"Zaxira maʼlumotlarini olib tashlash"</string>
+    <string name="settings_recovery_remove_backup_sub_title" msgid="212161719832573475">"Tozalash: <xliff:g id="PATH">/mnt/backup</xliff:g>"</string>
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Sozlamalar"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal ishga tushgan"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"Terminalni ochish uchun bosing"</string>
diff --git a/android/TerminalApp/res/values-vi/strings.xml b/android/TerminalApp/res/values-vi/strings.xml
index 82909db..8801296 100644
--- a/android/TerminalApp/res/values-vi/strings.xml
+++ b/android/TerminalApp/res/values-vi/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Tuỳ chọn khôi phục phân vùng"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Chuyển về phiên bản ban đầu"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Xoá tất cả"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Đặt lại cửa sổ dòng lệnh"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Dữ liệu sẽ bị xoá"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Xác nhận"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Huỷ"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Cài đặt"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Terminal đang chạy"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Nhấp để mở cửa sổ dòng lệnh"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Đóng"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zh-rCN/strings.xml b/android/TerminalApp/res/values-zh-rCN/strings.xml
index e1afa9f..6103fa5 100644
--- a/android/TerminalApp/res/values-zh-rCN/strings.xml
+++ b/android/TerminalApp/res/values-zh-rCN/strings.xml
@@ -53,8 +53,26 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"数据将被删除"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"确认"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"取消"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"设置"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"终端正在运行"</string>
-    <string name="service_notification_content" msgid="3579923802797824545">"点击即可打开终端"</string>
+    <string name="service_notification_content" msgid="3579923802797824545">"点按即可打开终端"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"关闭"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zh-rHK/strings.xml b/android/TerminalApp/res/values-zh-rHK/strings.xml
index b234d1b..0ed0092 100644
--- a/android/TerminalApp/res/values-zh-rHK/strings.xml
+++ b/android/TerminalApp/res/values-zh-rHK/strings.xml
@@ -50,11 +50,29 @@
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"變更至初始版本"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"全部移除"</string>
     <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"重設終端機"</string>
-    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"資料將刪除"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"資料將被刪除"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"確認"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"取消"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"設定"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"終端機執行中"</string>
-    <string name="service_notification_content" msgid="3579923802797824545">"點選即可開啟終端機"</string>
+    <string name="service_notification_content" msgid="3579923802797824545">"按一下即可開啟終端機"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"關閉"</string>
 </resources>
diff --git a/android/TerminalApp/res/values-zh-rTW/strings.xml b/android/TerminalApp/res/values-zh-rTW/strings.xml
index 7447671..fc795d9 100644
--- a/android/TerminalApp/res/values-zh-rTW/strings.xml
+++ b/android/TerminalApp/res/values-zh-rTW/strings.xml
@@ -53,6 +53,24 @@
     <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"資料將刪除"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"確認"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"取消"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"設定"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"終端機運作中"</string>
     <string name="service_notification_content" msgid="3579923802797824545">"點選即可開啟終端機"</string>
diff --git a/android/TerminalApp/res/values-zu/strings.xml b/android/TerminalApp/res/values-zu/strings.xml
index 134dbca..2a40824 100644
--- a/android/TerminalApp/res/values-zu/strings.xml
+++ b/android/TerminalApp/res/values-zu/strings.xml
@@ -49,15 +49,30 @@
     <string name="settings_recovery_sub_title" msgid="1067782421529340576">"Okukhethwa kukho kokubuyisela ukwahlukanisa"</string>
     <string name="settings_recovery_reset_title" msgid="8785305518694186025">"Shintshela Ohlotsheni lokuqala"</string>
     <string name="settings_recovery_reset_sub_title" msgid="5656572074090728544">"Susa konke"</string>
-    <!-- no translation found for settings_recovery_reset_dialog_title (874946981716251094) -->
-    <skip />
-    <!-- no translation found for settings_recovery_reset_dialog_message (6392681199895696206) -->
-    <skip />
+    <string name="settings_recovery_reset_dialog_title" msgid="874946981716251094">"Setha kabusha itheminali"</string>
+    <string name="settings_recovery_reset_dialog_message" msgid="6392681199895696206">"Idatha izosulwa"</string>
     <string name="settings_recovery_reset_dialog_confirm" msgid="431718610013947861">"Qinisekisa"</string>
     <string name="settings_recovery_reset_dialog_cancel" msgid="1666264288208459725">"Khansela"</string>
+    <!-- no translation found for settings_recovery_reset_dialog_backup_option (2079431035205584614) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_due_to_backup (2129959464075410607) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error (2451912941535666379) -->
+    <skip />
+    <!-- no translation found for settings_recovery_error_during_removing_backup (6515615177661212463) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_title (1540850288876158899) -->
+    <skip />
+    <!-- no translation found for settings_recovery_remove_backup_sub_title (212161719832573475) -->
+    <skip />
+    <!-- no translation found for error_title (7196464038692913778) -->
+    <skip />
+    <!-- no translation found for error_desc (1939028888570920661) -->
+    <skip />
+    <!-- no translation found for error_code (3585291676855383649) -->
+    <skip />
     <string name="service_notification_settings" msgid="1437365721184401135">"Amasethingi"</string>
     <string name="service_notification_title" msgid="2918088850910713393">"Itheminali iyasebenza"</string>
-    <!-- no translation found for service_notification_content (3579923802797824545) -->
-    <skip />
+    <string name="service_notification_content" msgid="3579923802797824545">"Chofoza ukuze uvule itheminali"</string>
     <string name="service_notification_quit_action" msgid="4888327875869277455">"Vala"</string>
 </resources>
diff --git a/android/TerminalApp/res/values/keyboard_btn_strings.xml b/android/TerminalApp/res/values/keyboard_btn_strings.xml
new file mode 100644
index 0000000..384c583
--- /dev/null
+++ b/android/TerminalApp/res/values/keyboard_btn_strings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="btn_esc_text" translatable="false">Esc</string>
+    <string name="btn_tab_text" translatable="false">Tab</string>
+    <string name="btn_home_text" translatable="false">Home</string>
+    <string name="btn_up_text" translatable="false">↑</string>
+    <string name="btn_end_text" translatable="false">End</string>
+    <string name="btn_pgup_text" translatable="false">PgUp</string>
+    <string name="btn_ctrl_text" translatable="false">Ctrl</string>
+    <string name="btn_alt_text" translatable="false">Alt</string>
+    <string name="btn_left_text" translatable="false">←</string>
+    <string name="btn_down_text" translatable="false">↓</string>
+    <string name="btn_right_text" translatable="false">→</string>
+    <string name="btn_pgdn_text" translatable="false">PgDn</string>
+</resources>
diff --git a/android/TerminalApp/res/values/strings.xml b/android/TerminalApp/res/values/strings.xml
index 300cbbc..851eaab 100644
--- a/android/TerminalApp/res/values/strings.xml
+++ b/android/TerminalApp/res/values/strings.xml
@@ -20,6 +20,13 @@
     <!-- Application name of this terminal app shown in the launcher. This app provides computer terminal to connect to virtual machine. [CHAR LIMIT=16] -->
     <string name="app_name">Terminal</string>
 
+    <!-- Description of the entire terminal display showing texts. This is read by talkback. [CHAR LIMIT=none] -->
+    <string name="terminal_display">Terminal display</string>
+    <!-- Description of the edit box accepting user input. This is read by talkback. [CHAR LIMIT=none] -->
+    <string name="terminal_input">Cursor</string>
+    <!-- Description of an empty line in the terminal. This is read by talkback. [CHAR LIMIT=none] -->
+    <string name="empty_line">Empty line</string>
+
     <!-- Installer activity title [CHAR LIMIT=none] -->
     <string name="installer_title_text">Install Linux terminal</string>
     <!-- Installer activity description format [CHAR LIMIT=none] -->
@@ -38,6 +45,8 @@
     <string name="installer_notif_desc_text">Linux terminal will be started after finish</string>
     <!-- Toast error message for install failure due to the network issue [CHAR LIMIT=none] -->
     <string name="installer_error_network">Failed to install due to the network issue</string>
+    <!-- Toast error message for install failure because Wi-Fi isn't available although required [CHAR LIMIT=none] -->
+    <string name="installer_error_no_wifi">Failed to install because Wi-Fi isn\'t available</string>
     <!-- Toast error message for install failure due to the unidentified issue [CHAR LIMIT=none] -->
     <string name="installer_error_unknown">Failed to install. Try again.</string>
 
diff --git a/android/TerminalApp/res/values/styles.xml b/android/TerminalApp/res/values/styles.xml
new file mode 100644
index 0000000..ee80862
--- /dev/null
+++ b/android/TerminalApp/res/values/styles.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <style name="ModifierKeyStyle" parent="@style/Widget.Material3.Button.TextButton">
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:paddingHorizontal">0dp</item>
+        <item name="android:hapticFeedbackEnabled">true</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/android/forwarder_host/src/forwarder_host.rs b/android/forwarder_host/src/forwarder_host.rs
index 2138957..ba427f5 100644
--- a/android/forwarder_host/src/forwarder_host.rs
+++ b/android/forwarder_host/src/forwarder_host.rs
@@ -384,6 +384,10 @@
     cid: jint,
     callback: JObject,
 ) {
+    // Clear shutdown event FD before running forwarder host.
+    SHUTDOWN_EVT.write(1).expect("Failed to write shutdown event FD");
+    SHUTDOWN_EVT.read().expect("Failed to consume shutdown event FD");
+
     match run_forwarder_host(cid, env, callback) {
         Ok(_) => {
             info!("forwarder_host is terminated");
diff --git a/docs/custom_vm.md b/docs/custom_vm.md
index 9a9ede4..eaff2a4 100644
--- a/docs/custom_vm.md
+++ b/docs/custom_vm.md
@@ -24,3 +24,22 @@
 
 The `vm` command also has other subcommands for debugging; run
 `/apex/com.android.virt/bin/vm help` for details.
+
+# Terminal app
+## Graphical environment (Wayland, VNC)
+By installing Wayland compositor and VNC backend, you can enable graphical environment.
+One of the options is `sway`, `wayvnc` and `xwayland`(if necessary).
+
+```
+sudo apt install sway wayvnc xwayland
+WLR_BACKENDS=headless WLR_LIBINPUT_NO_DEVICES=1 sway
+WAYLAND_DISPLAY=wayland-1 wayvnc 0.0.0.0 # or use port forwarding
+```
+
+And then, connect to 192.168.0.2:5900(or localhost:5900) with arbitrary VNC client.
+Or, `novnc`(https://github.com/novnc/noVNC/releases). For `novnc` you need to install
+`novnc`, and run `<novnc_path>/utils/novnc_proxy`, and then connect to `http://192.168.0.2:6080/vnc.html`
+(or `localhost:6080` if port forwarding is enabled.)
+
+`weston` with VNC backend might be another option, but it isn't available in
+Debian package repository for bookworm.
\ No newline at end of file
diff --git a/guest/forwarder_guest_launcher/src/main.rs b/guest/forwarder_guest_launcher/src/main.rs
index 0bb3b4d..1da37b4 100644
--- a/guest/forwarder_guest_launcher/src/main.rs
+++ b/guest/forwarder_guest_launcher/src/main.rs
@@ -36,6 +36,7 @@
 
 const NON_PREVILEGED_PORT_RANGE_START: i32 = 1024;
 const TCPSTATES_IP_4: i8 = 4;
+const TCPSTATES_STATE_CLOSE: &str = "CLOSE";
 const TCPSTATES_STATE_LISTEN: &str = "LISTEN";
 
 #[derive(Debug, Deserialize)]
@@ -43,7 +44,7 @@
 struct TcpStateRow {
     ip: i8,
     lport: i32,
-    oldstate: String,
+    rport: i32,
     newstate: String,
 }
 
@@ -142,14 +143,17 @@
         if row.lport < NON_PREVILEGED_PORT_RANGE_START {
             continue;
         }
-        match (row.oldstate.as_str(), row.newstate.as_str()) {
-            (_, TCPSTATES_STATE_LISTEN) => {
+        if row.rport > 0 {
+            continue;
+        }
+        match row.newstate.as_str() {
+            TCPSTATES_STATE_LISTEN => {
                 listening_ports.insert(row.lport);
             }
-            (TCPSTATES_STATE_LISTEN, _) => {
+            TCPSTATES_STATE_CLOSE => {
                 listening_ports.remove(&row.lport);
             }
-            (_, _) => continue,
+            _ => continue,
         }
         send_active_ports_report(listening_ports.clone(), &mut client).await?;
     }
diff --git a/guest/pvmfw/Android.bp b/guest/pvmfw/Android.bp
index 5c767a3..51f7802 100644
--- a/guest/pvmfw/Android.bp
+++ b/guest/pvmfw/Android.bp
@@ -118,6 +118,7 @@
         "libciborium",
         "libdiced_open_dice_nostd",
         "libpvmfw_avb_nostd",
+        "libdiced_sample_inputs_nostd",
         "libzerocopy_nostd",
         "libhex",
     ],
diff --git a/guest/pvmfw/avb/Android.bp b/guest/pvmfw/avb/Android.bp
index bc5cbfe..a1ee626 100644
--- a/guest/pvmfw/avb/Android.bp
+++ b/guest/pvmfw/avb/Android.bp
@@ -230,7 +230,7 @@
     props: [
         {
             name: "com.android.virt.cap",
-            value: "remote_attest|secretkeeper_protection|supports_uefi_boot",
+            value: "remote_attest|trusty_security_vm|secretkeeper_protection|supports_uefi_boot",
         },
     ],
 }
diff --git a/guest/pvmfw/avb/src/verify.rs b/guest/pvmfw/avb/src/verify.rs
index bd700ce..a073502 100644
--- a/guest/pvmfw/avb/src/verify.rs
+++ b/guest/pvmfw/avb/src/verify.rs
@@ -70,6 +70,8 @@
     RemoteAttest,
     /// Secretkeeper protected secrets.
     SecretkeeperProtection,
+    /// Trusty security VM.
+    TrustySecurityVm,
     /// UEFI support for booting guest kernel.
     SupportsUefiBoot,
     /// (internal)
@@ -80,6 +82,7 @@
 impl Capability {
     const KEY: &'static str = "com.android.virt.cap";
     const REMOTE_ATTEST: &'static [u8] = b"remote_attest";
+    const TRUSTY_SECURITY_VM: &'static [u8] = b"trusty_security_vm";
     const SECRETKEEPER_PROTECTION: &'static [u8] = b"secretkeeper_protection";
     const SEPARATOR: u8 = b'|';
     const SUPPORTS_UEFI_BOOT: &'static [u8] = b"supports_uefi_boot";
@@ -98,6 +101,7 @@
         for v in descriptor.value.split(|b| *b == Self::SEPARATOR) {
             let cap = match v {
                 Self::REMOTE_ATTEST => Self::RemoteAttest,
+                Self::TRUSTY_SECURITY_VM => Self::TrustySecurityVm,
                 Self::SECRETKEEPER_PROTECTION => Self::SecretkeeperProtection,
                 Self::SUPPORTS_UEFI_BOOT => Self::SupportsUefiBoot,
                 _ => return Err(PvmfwVerifyError::UnknownVbmetaProperty),
diff --git a/guest/pvmfw/avb/tests/api_test.rs b/guest/pvmfw/avb/tests/api_test.rs
index 72c795c..430c4b3 100644
--- a/guest/pvmfw/avb/tests/api_test.rs
+++ b/guest/pvmfw/avb/tests/api_test.rs
@@ -62,6 +62,7 @@
         &load_latest_trusty_security_vm_signed_kernel()?,
         salt,
         expected_rollback_index,
+        vec![Capability::TrustySecurityVm],
     )
 }
 
@@ -442,10 +443,11 @@
     .map_err(|e| anyhow!("Verification failed. Error: {}", e))?;
 
     assert!(verified_boot_data.has_capability(Capability::RemoteAttest));
+    assert!(verified_boot_data.has_capability(Capability::TrustySecurityVm));
     assert!(verified_boot_data.has_capability(Capability::SecretkeeperProtection));
     assert!(verified_boot_data.has_capability(Capability::SupportsUefiBoot));
     // Fail if this test doesn't actually cover all supported capabilities.
-    assert_eq!(Capability::COUNT, 3);
+    assert_eq!(Capability::COUNT, 4);
 
     Ok(())
 }
diff --git a/guest/pvmfw/avb/tests/utils.rs b/guest/pvmfw/avb/tests/utils.rs
index 0e836d5..61bfbf2 100644
--- a/guest/pvmfw/avb/tests/utils.rs
+++ b/guest/pvmfw/avb/tests/utils.rs
@@ -143,6 +143,7 @@
     kernel: &[u8],
     salt: &[u8],
     expected_rollback_index: u64,
+    capabilities: Vec<Capability>,
 ) -> Result<()> {
     let public_key = load_trusted_public_key()?;
     let verified_boot_data = verify_payload(
@@ -160,7 +161,7 @@
         kernel_digest,
         initrd_digest: None,
         public_key: &public_key,
-        capabilities: vec![],
+        capabilities,
         rollback_index: expected_rollback_index,
     };
     assert_eq!(expected_boot_data, verified_boot_data);
diff --git a/guest/pvmfw/src/dice.rs b/guest/pvmfw/src/dice.rs
index f3a2337..b597309 100644
--- a/guest/pvmfw/src/dice.rs
+++ b/guest/pvmfw/src/dice.rs
@@ -21,7 +21,7 @@
 use ciborium::Value;
 use core::mem::size_of;
 use diced_open_dice::{
-    bcc_handover_main_flow, hash, Config, DiceMode, Hash, InputValues, HIDDEN_SIZE,
+    bcc_handover_main_flow, hash, Config, DiceContext, DiceMode, Hash, InputValues, HIDDEN_SIZE,
 };
 use pvmfw_avb::{Capability, DebugLevel, Digest, VerifiedBootData};
 use zerocopy::AsBytes;
@@ -102,6 +102,7 @@
         instance_hash: Option<Hash>,
         deferred_rollback_protection: bool,
         next_bcc: &mut [u8],
+        context: DiceContext,
     ) -> Result<()> {
         let config = self
             .generate_config_descriptor(instance_hash)
@@ -114,7 +115,7 @@
             self.mode,
             self.make_hidden(salt, deferred_rollback_protection)?,
         );
-        let _ = bcc_handover_main_flow(current_bcc_handover, &dice_inputs, next_bcc)?;
+        let _ = bcc_handover_main_flow(current_bcc_handover, &dice_inputs, next_bcc, context)?;
         Ok(())
     }
 
@@ -177,8 +178,11 @@
     };
     use ciborium::Value;
     use diced_open_dice::DiceArtifacts;
+    use diced_open_dice::DiceContext;
     use diced_open_dice::DiceMode;
+    use diced_open_dice::KeyAlgorithm;
     use diced_open_dice::HIDDEN_SIZE;
+    use diced_sample_inputs::make_sample_bcc_and_cdis;
     use pvmfw_avb::Capability;
     use pvmfw_avb::DebugLevel;
     use pvmfw_avb::Digest;
@@ -298,6 +302,10 @@
         let mut buffer_without_defer = [0; 4096];
         let mut buffer_with_defer = [0; 4096];
         let mut buffer_without_defer_retry = [0; 4096];
+        let context = DiceContext {
+            authority_algorithm: KeyAlgorithm::Ed25519,
+            subject_algorithm: KeyAlgorithm::Ed25519,
+        };
 
         let sample_dice_input: &[u8] = &[
             0xa3, // CDI attest
@@ -321,6 +329,7 @@
                 Some([0u8; 64]),
                 false,
                 &mut buffer_without_defer,
+                context.clone(),
             )
             .unwrap();
         let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer_without_defer).unwrap();
@@ -333,6 +342,7 @@
                 Some([0u8; 64]),
                 true,
                 &mut buffer_with_defer,
+                context.clone(),
             )
             .unwrap();
         let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer_with_defer).unwrap();
@@ -345,6 +355,7 @@
                 Some([0u8; 64]),
                 false,
                 &mut buffer_without_defer_retry,
+                context.clone(),
             )
             .unwrap();
         let bcc_handover3 =
@@ -353,4 +364,82 @@
         assert_ne!(bcc_handover1.cdi_seal(), bcc_handover2.cdi_seal());
         assert_eq!(bcc_handover1.cdi_seal(), bcc_handover3.cdi_seal());
     }
+
+    #[test]
+    fn dice_derivation_with_different_algorithms_is_valid() {
+        let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
+        let bcc_handover0_bytes = to_bcc_handover(&dice_artifacts);
+        let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
+        let inputs = PartialInputs::new(&vb_data).unwrap();
+        let mut buffer = [0; 4096];
+
+        inputs
+            .clone()
+            .write_next_bcc(
+                &bcc_handover0_bytes,
+                &[0u8; HIDDEN_SIZE],
+                Some([0u8; 64]),
+                true,
+                &mut buffer,
+                DiceContext {
+                    authority_algorithm: KeyAlgorithm::Ed25519,
+                    subject_algorithm: KeyAlgorithm::EcdsaP256,
+                },
+            )
+            .expect("Failed to derive Ed25519 -> EcdsaP256 BCC");
+        let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
+        let bcc_handover1_bytes = to_bcc_handover(&bcc_handover1);
+        buffer.fill(0);
+
+        inputs
+            .clone()
+            .write_next_bcc(
+                &bcc_handover1_bytes,
+                &[0u8; HIDDEN_SIZE],
+                Some([0u8; 64]),
+                true,
+                &mut buffer,
+                DiceContext {
+                    authority_algorithm: KeyAlgorithm::EcdsaP256,
+                    subject_algorithm: KeyAlgorithm::EcdsaP384,
+                },
+            )
+            .expect("Failed to derive EcdsaP256 -> EcdsaP384 BCC");
+        let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
+        let bcc_handover2_bytes = to_bcc_handover(&bcc_handover2);
+        buffer.fill(0);
+
+        inputs
+            .clone()
+            .write_next_bcc(
+                &bcc_handover2_bytes,
+                &[0u8; HIDDEN_SIZE],
+                Some([0u8; 64]),
+                true,
+                &mut buffer,
+                DiceContext {
+                    authority_algorithm: KeyAlgorithm::EcdsaP384,
+                    subject_algorithm: KeyAlgorithm::Ed25519,
+                },
+            )
+            .expect("Failed to derive EcdsaP384 -> Ed25519 BCC");
+        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
+    }
+
+    fn to_bcc_handover(dice_artifacts: &dyn DiceArtifacts) -> Vec<u8> {
+        let dice_chain = cbor_util::deserialize::<Value>(dice_artifacts.bcc().unwrap()).unwrap();
+        let bcc_handover = Value::Map(vec![
+            (Value::Integer(1.into()), Value::Bytes(dice_artifacts.cdi_attest().to_vec())),
+            (Value::Integer(2.into()), Value::Bytes(dice_artifacts.cdi_seal().to_vec())),
+            (Value::Integer(3.into()), dice_chain),
+        ]);
+        cbor_util::serialize(&bcc_handover).unwrap()
+    }
 }
diff --git a/guest/pvmfw/src/main.rs b/guest/pvmfw/src/main.rs
index aeced51..612281b 100644
--- a/guest/pvmfw/src/main.rs
+++ b/guest/pvmfw/src/main.rs
@@ -45,7 +45,7 @@
 use bssl_avf::Digester;
 use core::ops::Range;
 use cstr::cstr;
-use diced_open_dice::{bcc_handover_parse, DiceArtifacts, Hidden};
+use diced_open_dice::{bcc_handover_parse, DiceArtifacts, DiceContext, Hidden, VM_KEY_ALGORITHM};
 use libfdt::{Fdt, FdtNode};
 use log::{debug, error, info, trace, warn};
 use pvmfw_avb::verify_payload;
@@ -154,6 +154,11 @@
             return Err(RebootReason::InvalidPayload);
         }
         (false, instance_hash.unwrap())
+    } else if verified_boot_data.has_capability(Capability::TrustySecurityVm) {
+        // The rollback protection of Trusty VMs are handled by AuthMgr, so we don't need to
+        // handle it here.
+        info!("Trusty Security VM detected");
+        (false, instance_hash.unwrap())
     } else {
         info!("Fallback to instance.img based rollback checks");
         let (recorded_entry, mut instance_img, header_index) =
@@ -202,6 +207,13 @@
 
     trace!("BCC leaf subject public key algorithm: {:?}", bcc.leaf_subject_pubkey().cose_alg);
 
+    let dice_context = DiceContext {
+        authority_algorithm: bcc.leaf_subject_pubkey().cose_alg.try_into().map_err(|e| {
+            error!("{e}");
+            RebootReason::InternalError
+        })?,
+        subject_algorithm: VM_KEY_ALGORITHM,
+    };
     dice_inputs
         .write_next_bcc(
             new_bcc_handover.as_ref(),
@@ -209,6 +221,7 @@
             instance_hash,
             defer_rollback_protection,
             next_bcc,
+            dice_context,
         )
         .map_err(|e| {
             error!("Failed to derive next-stage DICE secrets: {e:?}");
diff --git a/guest/trusty/security_vm/launcher/Android.bp b/guest/trusty/security_vm/launcher/Android.bp
index 38e3e42..fea8873 100644
--- a/guest/trusty/security_vm/launcher/Android.bp
+++ b/guest/trusty/security_vm/launcher/Android.bp
@@ -29,8 +29,7 @@
             src: ":trusty_security_vm_signed",
         },
         arm64: {
-            src: ":trusty-test-lk.elf",
-            enabled: true,
+            src: ":trusty_security_vm_signed",
         },
     },
     src: ":empty_file",
@@ -53,6 +52,12 @@
     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: {
diff --git a/libs/dice/open_dice/Android.bp b/libs/dice/open_dice/Android.bp
index c60260e..4241c47 100644
--- a/libs/dice/open_dice/Android.bp
+++ b/libs/dice/open_dice/Android.bp
@@ -19,6 +19,9 @@
         "libopen_dice_cbor_bindgen_nostd",
         "libzeroize_nostd",
     ],
+    features: [
+        "multialg",
+    ],
     whole_static_libs: [
         "libcrypto_baremetal",
     ],
@@ -132,6 +135,7 @@
         "--rustified-enum DiceConfigType",
         "--rustified-enum DiceMode",
         "--rustified-enum DiceResult",
+        "--rustified-enum DicePrincipal",
 
         // By generating only essential functions, we can make bindings concise and
         // optimize compilation time.
@@ -171,7 +175,11 @@
         "libopen_dice_cbor_bindgen.rust_defaults",
         "libopen_dice_bindgen_nostd.rust_defaults",
     ],
-    whole_static_libs: ["libopen_dice_cbor_baremetal"],
+    bindgen_flags: [
+        "--rustified-enum DiceKeyAlgorithm",
+        "--allowlist-type=DiceContext",
+    ],
+    whole_static_libs: ["libopen_dice_cbor_baremetal_multialg"],
 }
 
 rust_defaults {
@@ -227,7 +235,7 @@
     rustlibs: [
         "libopen_dice_cbor_bindgen_nostd",
     ],
-    whole_static_libs: ["libopen_dice_android_baremetal"],
+    whole_static_libs: ["libopen_dice_android_baremetal_multialg"],
 }
 
 rust_test {
diff --git a/libs/dice/open_dice/src/bcc.rs b/libs/dice/open_dice/src/bcc.rs
index 9c9545b..fabd7c7 100644
--- a/libs/dice/open_dice/src/bcc.rs
+++ b/libs/dice/open_dice/src/bcc.rs
@@ -14,13 +14,13 @@
 
 //! This module mirrors the content in open-dice/include/dice/android.h
 
-use crate::dice::{Cdi, CdiValues, DiceArtifacts, InputValues, CDI_SIZE};
+use crate::dice::{context, Cdi, CdiValues, DiceArtifacts, InputValues, CDI_SIZE};
 use crate::error::{check_result, DiceError, Result};
 use open_dice_android_bindgen::{
-    DiceAndroidConfigValues, DiceAndroidFormatConfigDescriptor, DiceAndroidHandoverMainFlow,
-    DiceAndroidHandoverParse, DiceAndroidMainFlow, DICE_ANDROID_CONFIG_COMPONENT_NAME,
-    DICE_ANDROID_CONFIG_COMPONENT_VERSION, DICE_ANDROID_CONFIG_RESETTABLE,
-    DICE_ANDROID_CONFIG_RKP_VM_MARKER, DICE_ANDROID_CONFIG_SECURITY_VERSION,
+    DiceAndroidConfigValues, DiceAndroidFormatConfigDescriptor, DiceAndroidHandoverParse,
+    DiceAndroidMainFlow, DICE_ANDROID_CONFIG_COMPONENT_NAME, DICE_ANDROID_CONFIG_COMPONENT_VERSION,
+    DICE_ANDROID_CONFIG_RESETTABLE, DICE_ANDROID_CONFIG_RKP_VM_MARKER,
+    DICE_ANDROID_CONFIG_SECURITY_VERSION,
 };
 use std::{ffi::CStr, ptr};
 
@@ -101,10 +101,11 @@
         // SAFETY: `DiceAndroidMainFlow` only reads the `current_chain` and CDI values and writes
         // to `next_chain` and next CDI values within its bounds. It also reads `input_values` as a
         // constant input and doesn't store any pointer.
-        // The first argument can be null and is not used in the current implementation.
+        // The first argument is a pointer to a valid |DiceContext_| object for multi-alg open-dice
+        // and a null pointer otherwise.
         unsafe {
             DiceAndroidMainFlow(
-                ptr::null_mut(), // context
+                context(),
                 current_cdi_attest.as_ptr(),
                 current_cdi_seal.as_ptr(),
                 current_chain.as_ptr(),
@@ -127,20 +128,23 @@
 /// A handover combines the DICE chain and CDIs in a single CBOR object.
 /// This function takes the current boot stage's handover bundle and produces a
 /// bundle for the next stage.
+#[cfg(feature = "multialg")]
 pub fn bcc_handover_main_flow(
     current_handover: &[u8],
     input_values: &InputValues,
     next_handover: &mut [u8],
+    ctx: crate::dice::DiceContext,
 ) -> Result<usize> {
     let mut next_handover_size = 0;
+    let mut ctx: open_dice_cbor_bindgen::DiceContext_ = ctx.into();
     check_result(
         // SAFETY: The function only reads `current_handover` and writes to `next_handover`
         // within its bounds,
         // It also reads `input_values` as a constant input and doesn't store any pointer.
-        // The first argument can be null and is not used in the current implementation.
+        // The first argument is a pointer to a valid |DiceContext_| object.
         unsafe {
-            DiceAndroidHandoverMainFlow(
-                ptr::null_mut(), // context
+            open_dice_android_bindgen::DiceAndroidHandoverMainFlow(
+                &mut ctx as *mut _ as *mut std::ffi::c_void,
                 current_handover.as_ptr(),
                 current_handover.len(),
                 input_values.as_ptr(),
diff --git a/libs/dice/open_dice/src/dice.rs b/libs/dice/open_dice/src/dice.rs
index 6404508..206769c 100644
--- a/libs/dice/open_dice/src/dice.rs
+++ b/libs/dice/open_dice/src/dice.rs
@@ -15,7 +15,7 @@
 //! Structs and functions about the types used in DICE.
 //! This module mirrors the content in open-dice/include/dice/dice.h
 
-use crate::error::{check_result, Result};
+use crate::error::{check_result, DiceError, Result};
 use coset::iana;
 pub use open_dice_cbor_bindgen::DiceMode;
 use open_dice_cbor_bindgen::{
@@ -23,9 +23,11 @@
     DiceMainFlow, DICE_CDI_SIZE, DICE_HASH_SIZE, DICE_HIDDEN_SIZE, DICE_ID_SIZE,
     DICE_INLINE_CONFIG_SIZE, DICE_PRIVATE_KEY_SEED_SIZE, DICE_PRIVATE_KEY_SIZE,
 };
+#[cfg(feature = "multialg")]
+use open_dice_cbor_bindgen::{DiceContext_, DiceKeyAlgorithm};
 #[cfg(feature = "serde_derive")]
 use serde_derive::{Deserialize, Serialize};
-use std::{marker::PhantomData, ptr};
+use std::{ffi::c_void, marker::PhantomData, ptr};
 use zeroize::{Zeroize, ZeroizeOnDrop};
 
 /// The size of a DICE hash.
@@ -114,6 +116,69 @@
     }
 }
 
+impl TryFrom<iana::Algorithm> for KeyAlgorithm {
+    type Error = DiceError;
+
+    fn try_from(alg: iana::Algorithm) -> Result<Self> {
+        match alg {
+            iana::Algorithm::EdDSA => Ok(KeyAlgorithm::Ed25519),
+            iana::Algorithm::ES256 => Ok(KeyAlgorithm::EcdsaP256),
+            iana::Algorithm::ES384 => Ok(KeyAlgorithm::EcdsaP384),
+            other => Err(DiceError::UnsupportedKeyAlgorithm(other)),
+        }
+    }
+}
+
+#[cfg(feature = "multialg")]
+impl From<KeyAlgorithm> for DiceKeyAlgorithm {
+    fn from(alg: KeyAlgorithm) -> Self {
+        match alg {
+            KeyAlgorithm::Ed25519 => DiceKeyAlgorithm::kDiceKeyAlgorithmEd25519,
+            KeyAlgorithm::EcdsaP256 => DiceKeyAlgorithm::kDiceKeyAlgorithmP256,
+            KeyAlgorithm::EcdsaP384 => DiceKeyAlgorithm::kDiceKeyAlgorithmP384,
+        }
+    }
+}
+
+/// Represents the context used for DICE operations.
+#[cfg(feature = "multialg")]
+#[derive(Debug, Clone)]
+pub struct DiceContext {
+    /// The algorithm used for the authority key.
+    pub authority_algorithm: KeyAlgorithm,
+    /// The algorithm used for the subject key.
+    pub subject_algorithm: KeyAlgorithm,
+}
+
+#[cfg(feature = "multialg")]
+impl From<DiceContext> for DiceContext_ {
+    fn from(ctx: DiceContext) -> Self {
+        DiceContext_ {
+            authority_algorithm: ctx.authority_algorithm.into(),
+            subject_algorithm: ctx.subject_algorithm.into(),
+        }
+    }
+}
+
+#[cfg(feature = "multialg")]
+const VM_DICE_CONTEXT: DiceContext_ = DiceContext_ {
+    authority_algorithm: DiceKeyAlgorithm::kDiceKeyAlgorithmEd25519,
+    subject_algorithm: DiceKeyAlgorithm::kDiceKeyAlgorithmEd25519,
+};
+
+/// Returns the pointer points to |DiceContext_| for DICE operations when `multialg`
+/// feature is enabled.
+#[cfg(feature = "multialg")]
+pub(crate) fn context() -> *mut c_void {
+    &VM_DICE_CONTEXT as *const DiceContext_ as *mut c_void
+}
+
+/// Returns a null pointer when `multialg` feature is disabled.
+#[cfg(not(feature = "multialg"))]
+pub(crate) fn context() -> *mut c_void {
+    ptr::null_mut()
+}
+
 /// A trait for types that represent Dice artifacts, which include:
 ///
 /// - Attestation CDI
@@ -322,10 +387,9 @@
     check_result(
         // SAFETY: The function only reads the current CDI values and inputs and writes
         // to `next_cdi_certificate` and next CDI values within its bounds.
-        // The first argument can be null and is not used in the current implementation.
         unsafe {
             DiceMainFlow(
-                ptr::null_mut(), // context
+                context(),
                 current_cdi_attest.as_ptr(),
                 current_cdi_seal.as_ptr(),
                 input_values.as_ptr(),
diff --git a/libs/dice/open_dice/src/error.rs b/libs/dice/open_dice/src/error.rs
index bef9a9c..9089432 100644
--- a/libs/dice/open_dice/src/error.rs
+++ b/libs/dice/open_dice/src/error.rs
@@ -29,6 +29,8 @@
     BufferTooSmall(usize),
     /// Platform error.
     PlatformError,
+    /// Unsupported key algorithm.
+    UnsupportedKeyAlgorithm(coset::iana::Algorithm),
 }
 
 /// This makes `DiceError` accepted by anyhow.
@@ -43,6 +45,9 @@
                 write!(f, "Buffer too small; need {buffer_required_size} bytes")
             }
             Self::PlatformError => write!(f, "Platform error"),
+            Self::UnsupportedKeyAlgorithm(algorithm) => {
+                write!(f, "Unsupported key algorithm: {algorithm:?}")
+            }
         }
     }
 }
diff --git a/libs/dice/open_dice/src/lib.rs b/libs/dice/open_dice/src/lib.rs
index a347d46..4d05255 100644
--- a/libs/dice/open_dice/src/lib.rs
+++ b/libs/dice/open_dice/src/lib.rs
@@ -28,10 +28,13 @@
 mod ops;
 mod retry;
 
+#[cfg(feature = "multialg")]
+pub use bcc::bcc_handover_main_flow;
 pub use bcc::{
-    bcc_format_config_descriptor, bcc_handover_main_flow, bcc_handover_parse, bcc_main_flow,
-    BccHandover, DiceConfigValues,
+    bcc_format_config_descriptor, bcc_handover_parse, bcc_main_flow, BccHandover, DiceConfigValues,
 };
+#[cfg(feature = "multialg")]
+pub use dice::DiceContext;
 pub use dice::{
     derive_cdi_certificate_id, derive_cdi_private_key_seed, dice_main_flow, Cdi, CdiValues, Config,
     DiceArtifacts, DiceMode, Hash, Hidden, InlineConfig, InputValues, KeyAlgorithm, PrivateKey,
diff --git a/libs/dice/open_dice/src/ops.rs b/libs/dice/open_dice/src/ops.rs
index 137736f..41951bf 100644
--- a/libs/dice/open_dice/src/ops.rs
+++ b/libs/dice/open_dice/src/ops.rs
@@ -17,13 +17,14 @@
 //! main DICE functions depend on.
 
 use crate::dice::{
-    derive_cdi_private_key_seed, DiceArtifacts, Hash, InputValues, PrivateKey, HASH_SIZE,
+    context, derive_cdi_private_key_seed, DiceArtifacts, Hash, InputValues, PrivateKey, HASH_SIZE,
     PRIVATE_KEY_SEED_SIZE, PRIVATE_KEY_SIZE, VM_KEY_ALGORITHM,
 };
 use crate::error::{check_result, DiceError, Result};
 use alloc::{vec, vec::Vec};
 use open_dice_cbor_bindgen::{
-    DiceGenerateCertificate, DiceHash, DiceKdf, DiceKeypairFromSeed, DiceSign, DiceVerify,
+    DiceGenerateCertificate, DiceHash, DiceKdf, DiceKeypairFromSeed, DicePrincipal, DiceSign,
+    DiceVerify,
 };
 use std::ptr;
 
@@ -75,13 +76,20 @@
 pub fn keypair_from_seed(seed: &[u8; PRIVATE_KEY_SEED_SIZE]) -> Result<(Vec<u8>, PrivateKey)> {
     let mut public_key = vec![0u8; VM_KEY_ALGORITHM.public_key_size()];
     let mut private_key = PrivateKey::default();
+    // This function is used with an open-dice config that uses the same algorithms for the
+    // subject and authority. Therefore, the principal is irrelevant in this context as this
+    // function only derives the key pair cryptographically without caring about which
+    // principal it is for. Hence, we arbitrarily set it to `DicePrincipal::kDicePrincipalSubject`.
+    let principal = DicePrincipal::kDicePrincipalSubject;
     check_result(
         // SAFETY: The function writes to the `public_key` and `private_key` within the given
-        // bounds, and only reads the `seed`. The first argument context is not used in this
-        // function.
+        // bounds, and only reads the `seed`.
+        // The first argument is a pointer to a valid |DiceContext_| object for multi-alg open-dice
+        // and a null pointer otherwise.
         unsafe {
             DiceKeypairFromSeed(
-                ptr::null_mut(), // context
+                context(),
+                principal,
                 seed.as_ptr(),
                 public_key.as_mut_ptr(),
                 private_key.as_mut_ptr(),
@@ -111,11 +119,12 @@
     let mut signature = vec![0u8; VM_KEY_ALGORITHM.signature_size()];
     check_result(
         // SAFETY: The function writes to the `signature` within the given bounds, and only reads
-        // the message and the private key. The first argument context is not used in this
-        // function.
+        // the message and the private key.
+        // The first argument is a pointer to a valid |DiceContext_| object for multi-alg open-dice
+        // and a null pointer otherwise.
         unsafe {
             DiceSign(
-                ptr::null_mut(), // context
+                context(),
                 message.as_ptr(),
                 message.len(),
                 private_key.as_ptr(),
@@ -136,10 +145,11 @@
     }
     check_result(
         // SAFETY: only reads the messages, signature and public key as constant values.
-        // The first argument context is not used in this function.
+        // The first argument is a pointer to a valid |DiceContext_| object for multi-alg open-dice
+        // and a null pointer otherwise.
         unsafe {
             DiceVerify(
-                ptr::null_mut(), // context
+                context(),
                 message.as_ptr(),
                 message.len(),
                 signature.as_ptr(),
@@ -164,11 +174,12 @@
     let mut certificate_actual_size = 0;
     check_result(
         // SAFETY: The function writes to the `certificate` within the given bounds, and only reads
-        // the input values and the key seeds. The first argument context is not used in this
-        // function.
+        // the input values and the key seeds.
+        // The first argument is a pointer to a valid |DiceContext_| object for multi-alg open-dice
+        // and a null pointer otherwise.
         unsafe {
             DiceGenerateCertificate(
-                ptr::null_mut(), // context
+                context(),
                 subject_private_key_seed.as_ptr(),
                 authority_private_key_seed.as_ptr(),
                 input_values.as_ptr(),