Merge "Check file contexts only for protected VMs" into main
diff --git a/android/TerminalApp/Android.bp b/android/TerminalApp/Android.bp
index 2711af0..733a72b 100644
--- a/android/TerminalApp/Android.bp
+++ b/android/TerminalApp/Android.bp
@@ -9,7 +9,6 @@
         "java/**/*.kt",
     ],
     resource_dirs: ["res"],
-    asset_dirs: ["assets"],
     static_libs: [
         "androidx-constraintlayout_constraintlayout",
         "androidx.window_window",
diff --git a/android/TerminalApp/assets/.gitkeep b/android/TerminalApp/assets/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/android/TerminalApp/assets/.gitkeep
+++ /dev/null
diff --git a/android/TerminalApp/assets/client.p12 b/android/TerminalApp/assets/client.p12
deleted file mode 100644
index f1f5820..0000000
--- a/android/TerminalApp/assets/client.p12
+++ /dev/null
Binary files differ
diff --git a/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java
new file mode 100644
index 0000000..12f485a
--- /dev/null
+++ b/android/TerminalApp/java/com/android/virtualization/terminal/ImageArchive.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.virtualization.terminal;
+
+import android.os.Build;
+import android.os.Environment;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.Arrays;
+import java.util.function.Function;
+
+/**
+ * ImageArchive models the archive file (images.tar.gz) where VM payload files are in. This class
+ * provides methods for handling the archive file, most importantly installing it.
+ */
+class ImageArchive {
+    private static final String DIR_IN_SDCARD = "linux";
+    private static final String ARCHIVE_NAME = "images.tar.gz";
+    private static final String HOST_URL = "https://dl.google.com/android/ferrochrome/latest";
+
+    // Only one can be non-null
+    private final URL mUrl;
+    private final Path mPath;
+
+    private ImageArchive(URL url) {
+        mUrl = url;
+        mPath = null;
+    }
+
+    private ImageArchive(Path path) {
+        mUrl = null;
+        mPath = path;
+    }
+
+    /** Creates ImageArchive which is located in the sdcard. This archive is for testing only. */
+    public static ImageArchive fromSdCard() {
+        Path dir = Environment.getExternalStoragePublicDirectory(DIR_IN_SDCARD).toPath();
+        Path file = dir.resolve(ARCHIVE_NAME);
+        return new ImageArchive(file);
+    }
+
+    /** Creates ImageArchive which is hosted in the Google server. This is the official archive. */
+    public static ImageArchive fromInternet() {
+        String arch = Arrays.asList(Build.SUPPORTED_ABIS).contains("x86_64") ? "x86_64" : "aarch64";
+        try {
+            URL url = new URL(HOST_URL + "/" + arch + "/" + ARCHIVE_NAME);
+            return new ImageArchive(url);
+        } catch (MalformedURLException e) {
+            // cannot happen
+            throw new RuntimeException(e);
+        }
+    }
+
+    private InputStream getInputStream(Function<InputStream, InputStream> filter)
+            throws IOException {
+        InputStream is = mPath != null ? new FileInputStream(mPath.toFile()) : mUrl.openStream();
+        BufferedInputStream bufStream = new BufferedInputStream(is);
+        return filter == null ? bufStream : filter.apply(bufStream);
+    }
+
+    /**
+     * Installs this ImageArchive to a directory pointed by path. filter can be supplied to provide
+     * an additional input stream which will be used during the installation.
+     */
+    public void installTo(Path path, Function<InputStream, InputStream> filter) throws IOException {
+        try (InputStream stream = getInputStream(filter);
+                GzipCompressorInputStream gzStream = new GzipCompressorInputStream(stream);
+                TarArchiveInputStream tarStream = new TarArchiveInputStream(gzStream)) {
+
+            Files.createDirectories(path);
+            ArchiveEntry entry;
+            while ((entry = tarStream.getNextEntry()) != null) {
+                Path to = path.resolve(entry.getName());
+                if (Files.isDirectory(to)) {
+                    Files.createDirectories(to);
+                } else {
+                    Files.copy(tarStream, to, StandardCopyOption.REPLACE_EXISTING);
+                }
+            }
+        }
+        postInstall();
+    }
+
+    // To save storage, delete the source archive on the disk.
+    private void postInstall() throws IOException {
+        if (mPath != null) {
+            Files.deleteIfExists(mPath);
+        }
+    }
+}
diff --git a/build/debian/fai_config/scripts/AVF/10-systemd b/build/debian/fai_config/scripts/AVF/10-systemd
index a514299..94838bc 100755
--- a/build/debian/fai_config/scripts/AVF/10-systemd
+++ b/build/debian/fai_config/scripts/AVF/10-systemd
@@ -10,3 +10,5 @@
 ln -s /etc/systemd/system/forwarder_guest_launcher.service $target/etc/systemd/system/multi-user.target.wants/forwarder_guest_launcher.service
 ln -s /etc/systemd/system/virtiofs_internal.service $target/etc/systemd/system/multi-user.target.wants/virtiofs_internal.service
 ln -s /etc/systemd/system/backup_mount.service $target/etc/systemd/system/multi-user.target.wants/backup_mount.service
+
+sed -i 's/#LLMNR=yes/LLMNR=no/' $target/etc/systemd/resolved.conf