Merge "Use select() for build/apex/Android.bp modules" into main
diff --git a/android/FerrochromeApp/AndroidManifest.xml b/android/FerrochromeApp/AndroidManifest.xml
index 7afffe5..d640c4a 100644
--- a/android/FerrochromeApp/AndroidManifest.xml
+++ b/android/FerrochromeApp/AndroidManifest.xml
@@ -6,6 +6,8 @@
     <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
     <uses-permission android:name="android.permission.KILL_ALL_BACKGROUND_PROCESSES" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="com.android.virtualization.vmlauncher.permission.USE_VM_LAUNCHER" />
+
     <queries>
         <intent>
             <action android:name="android.virtualization.VM_LAUNCHER" />
diff --git a/android/VmLauncherApp/AndroidManifest.xml b/android/VmLauncherApp/AndroidManifest.xml
index c6ab1f2..67b7a45 100644
--- a/android/VmLauncherApp/AndroidManifest.xml
+++ b/android/VmLauncherApp/AndroidManifest.xml
@@ -7,6 +7,10 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
     <uses-feature android:name="android.software.virtualization_framework" android:required="true" />
+
+    <permission android:name="com.android.virtualization.vmlauncher.permission.USE_VM_LAUNCHER"
+        android:protectionLevel="signature|preinstalled"/>
+
     <application
         android:label="VmLauncherApp">
         <activity android:name=".MainActivity"
@@ -14,6 +18,7 @@
                   android:configChanges="orientation|screenSize|keyboard|keyboardHidden|navigation|uiMode"
                   android:theme="@style/MyTheme"
                   android:resizeableActivity="false"
+                  android:permission="com.android.virtualization.vmlauncher.permission.USE_VM_LAUNCHER"
                   android:exported="true">
             <intent-filter>
                 <action android:name="android.virtualization.VM_LAUNCHER" />
diff --git a/android/VmLauncherApp/java/com/android/virtualization/vmlauncher/MainActivity.java b/android/VmLauncherApp/java/com/android/virtualization/vmlauncher/MainActivity.java
index 0b93968..a93c173 100644
--- a/android/VmLauncherApp/java/com/android/virtualization/vmlauncher/MainActivity.java
+++ b/android/VmLauncherApp/java/com/android/virtualization/vmlauncher/MainActivity.java
@@ -457,10 +457,16 @@
                                                 + holder.getSurface()
                                                 + ")");
                                 runWithDisplayService(
-                                        (service) ->
-                                                service.setSurface(
+                                        s ->
+                                                s.setSurface(
                                                         holder.getSurface(),
                                                         false /* forCursor */));
+                                // TODO  execute the above and the below togther with the same call
+                                // to runWithDisplayService. Currently this doesn't work because
+                                // setSurface somtimes trigger an exception and as a result
+                                // drawSavedFrameForSurface is skipped.
+                                runWithDisplayService(
+                                        s -> s.drawSavedFrameForSurface(false /* forCursor */));
                             }
 
                             @Override
@@ -544,6 +550,12 @@
     }
 
     @Override
+    protected void onPause() {
+        super.onPause();
+        runWithDisplayService(s -> s.saveFrameForSurface(false /* forCursor */));
+    }
+
+    @Override
     protected void onStop() {
         super.onStop();
         if (mVirtualMachine != null) {
diff --git a/compos/verify/Android.bp b/android/compos_verify/Android.bp
similarity index 100%
rename from compos/verify/Android.bp
rename to android/compos_verify/Android.bp
diff --git a/compos/verify/native/Android.bp b/android/compos_verify/native/Android.bp
similarity index 100%
rename from compos/verify/native/Android.bp
rename to android/compos_verify/native/Android.bp
diff --git a/compos/verify/native/lib.rs b/android/compos_verify/native/lib.rs
similarity index 100%
rename from compos/verify/native/lib.rs
rename to android/compos_verify/native/lib.rs
diff --git a/compos/verify/native/verify_native.cpp b/android/compos_verify/native/verify_native.cpp
similarity index 100%
rename from compos/verify/native/verify_native.cpp
rename to android/compos_verify/native/verify_native.cpp
diff --git a/compos/verify/native/verify_native.h b/android/compos_verify/native/verify_native.h
similarity index 100%
rename from compos/verify/native/verify_native.h
rename to android/compos_verify/native/verify_native.h
diff --git a/compos/verify/verify.rs b/android/compos_verify/verify.rs
similarity index 100%
rename from compos/verify/verify.rs
rename to android/compos_verify/verify.rs
diff --git a/compos/composd/Android.bp b/android/composd/Android.bp
similarity index 100%
rename from compos/composd/Android.bp
rename to android/composd/Android.bp
diff --git a/compos/composd/aidl/Android.bp b/android/composd/aidl/Android.bp
similarity index 100%
rename from compos/composd/aidl/Android.bp
rename to android/composd/aidl/Android.bp
diff --git a/compos/composd/aidl/android/system/composd/ICompilationTask.aidl b/android/composd/aidl/android/system/composd/ICompilationTask.aidl
similarity index 100%
rename from compos/composd/aidl/android/system/composd/ICompilationTask.aidl
rename to android/composd/aidl/android/system/composd/ICompilationTask.aidl
diff --git a/compos/composd/aidl/android/system/composd/ICompilationTaskCallback.aidl b/android/composd/aidl/android/system/composd/ICompilationTaskCallback.aidl
similarity index 100%
rename from compos/composd/aidl/android/system/composd/ICompilationTaskCallback.aidl
rename to android/composd/aidl/android/system/composd/ICompilationTaskCallback.aidl
diff --git a/compos/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl b/android/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
similarity index 100%
rename from compos/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
rename to android/composd/aidl/android/system/composd/IIsolatedCompilationService.aidl
diff --git a/compos/composd/native/Android.bp b/android/composd/native/Android.bp
similarity index 100%
rename from compos/composd/native/Android.bp
rename to android/composd/native/Android.bp
diff --git a/compos/composd/native/lib.rs b/android/composd/native/lib.rs
similarity index 100%
rename from compos/composd/native/lib.rs
rename to android/composd/native/lib.rs
diff --git a/compos/composd/src/composd_main.rs b/android/composd/src/composd_main.rs
similarity index 100%
rename from compos/composd/src/composd_main.rs
rename to android/composd/src/composd_main.rs
diff --git a/compos/composd/src/fd_server_helper.rs b/android/composd/src/fd_server_helper.rs
similarity index 100%
rename from compos/composd/src/fd_server_helper.rs
rename to android/composd/src/fd_server_helper.rs
diff --git a/compos/composd/src/instance_manager.rs b/android/composd/src/instance_manager.rs
similarity index 100%
rename from compos/composd/src/instance_manager.rs
rename to android/composd/src/instance_manager.rs
diff --git a/compos/composd/src/instance_starter.rs b/android/composd/src/instance_starter.rs
similarity index 100%
rename from compos/composd/src/instance_starter.rs
rename to android/composd/src/instance_starter.rs
diff --git a/compos/composd/src/odrefresh_task.rs b/android/composd/src/odrefresh_task.rs
similarity index 100%
rename from compos/composd/src/odrefresh_task.rs
rename to android/composd/src/odrefresh_task.rs
diff --git a/compos/composd/src/service.rs b/android/composd/src/service.rs
similarity index 100%
rename from compos/composd/src/service.rs
rename to android/composd/src/service.rs
diff --git a/compos/composd_cmd/Android.bp b/android/composd_cmd/Android.bp
similarity index 100%
rename from compos/composd_cmd/Android.bp
rename to android/composd_cmd/Android.bp
diff --git a/compos/composd_cmd/composd_cmd.rs b/android/composd_cmd/composd_cmd.rs
similarity index 100%
rename from compos/composd_cmd/composd_cmd.rs
rename to android/composd_cmd/composd_cmd.rs
diff --git a/authfs/fd_server/Android.bp b/android/fd_server/Android.bp
similarity index 100%
rename from authfs/fd_server/Android.bp
rename to android/fd_server/Android.bp
diff --git a/authfs/TEST_MAPPING b/android/fd_server/TEST_MAPPING
similarity index 100%
copy from authfs/TEST_MAPPING
copy to android/fd_server/TEST_MAPPING
diff --git a/authfs/fd_server/src/aidl.rs b/android/fd_server/src/aidl.rs
similarity index 100%
rename from authfs/fd_server/src/aidl.rs
rename to android/fd_server/src/aidl.rs
diff --git a/authfs/fd_server/src/main.rs b/android/fd_server/src/main.rs
similarity index 100%
rename from authfs/fd_server/src/main.rs
rename to android/fd_server/src/main.rs
diff --git a/compos/apex/Android.bp b/build/compos/Android.bp
similarity index 100%
rename from compos/apex/Android.bp
rename to build/compos/Android.bp
diff --git a/compos/apk/Android.bp b/build/compos/CompOSPayloadApp/Android.bp
similarity index 100%
rename from compos/apk/Android.bp
rename to build/compos/CompOSPayloadApp/Android.bp
diff --git a/compos/apk/AndroidManifest.xml b/build/compos/CompOSPayloadApp/AndroidManifest.xml
similarity index 100%
rename from compos/apk/AndroidManifest.xml
rename to build/compos/CompOSPayloadApp/AndroidManifest.xml
diff --git a/compos/apk/assets/vm_config.json b/build/compos/CompOSPayloadApp/assets/vm_config.json
similarity index 100%
rename from compos/apk/assets/vm_config.json
rename to build/compos/CompOSPayloadApp/assets/vm_config.json
diff --git a/compos/apk/assets/vm_config_staged.json b/build/compos/CompOSPayloadApp/assets/vm_config_staged.json
similarity index 100%
rename from compos/apk/assets/vm_config_staged.json
rename to build/compos/CompOSPayloadApp/assets/vm_config_staged.json
diff --git a/compos/apk/assets/vm_config_system_ext.json b/build/compos/CompOSPayloadApp/assets/vm_config_system_ext.json
similarity index 100%
rename from compos/apk/assets/vm_config_system_ext.json
rename to build/compos/CompOSPayloadApp/assets/vm_config_system_ext.json
diff --git a/compos/apk/assets/vm_config_system_ext_staged.json b/build/compos/CompOSPayloadApp/assets/vm_config_system_ext_staged.json
similarity index 100%
rename from compos/apk/assets/vm_config_system_ext_staged.json
rename to build/compos/CompOSPayloadApp/assets/vm_config_system_ext_staged.json
diff --git a/compos/apex/com.android.compos.avbpubkey b/build/compos/com.android.compos.avbpubkey
similarity index 100%
rename from compos/apex/com.android.compos.avbpubkey
rename to build/compos/com.android.compos.avbpubkey
Binary files differ
diff --git a/compos/apex/com.android.compos.pem b/build/compos/com.android.compos.pem
similarity index 100%
rename from compos/apex/com.android.compos.pem
rename to build/compos/com.android.compos.pem
diff --git a/compos/apex/com.android.compos.pk8 b/build/compos/com.android.compos.pk8
similarity index 100%
rename from compos/apex/com.android.compos.pk8
rename to build/compos/com.android.compos.pk8
Binary files differ
diff --git a/compos/apex/com.android.compos.x509.pem b/build/compos/com.android.compos.x509.pem
similarity index 100%
rename from compos/apex/com.android.compos.x509.pem
rename to build/compos/com.android.compos.x509.pem
diff --git a/compos/apex/composd.rc b/build/compos/composd.rc
similarity index 100%
rename from compos/apex/composd.rc
rename to build/compos/composd.rc
diff --git a/compos/apex/manifest.json b/build/compos/manifest.json
similarity index 100%
rename from compos/apex/manifest.json
rename to build/compos/manifest.json
diff --git a/docs/custom_vm.md b/docs/custom_vm.md
index 6422678..cdeddf5 100644
--- a/docs/custom_vm.md
+++ b/docs/custom_vm.md
@@ -207,28 +207,17 @@
 
 ### Running the VM
 
-First, enable the `VmLauncherApp` app. This needs to be done only once. In the
-future, this step won't be necesssary.
+1. Grant permission to the `VmLauncherApp` if the virt apex is Google-signed.
+    ```shell
+    $ adb shell su root pm grant com.google.android.virtualization.vmlauncher android.permission.USE_CUSTOM_VIRTUAL_MACHINE
+    ```
 
-```
-$ adb root
-$ adb shell pm enable com.android.virtualization.vmlauncher/.MainActivityAlias
-$ adb unroot
-```
+2. Ensure your device is connected to the Internet.
 
-If virt apex is Google-signed, you need to enable the app and grant the
-permission to the app.
-```
-$ adb root
-$ adb shell pm enable com.google.android.virtualization.vmlauncher/com.android.virtualization.vmlauncher.MainActivityAlias
-$ adb shell pm grant com.google.android.virtualization.vmlauncher android.permission.USE_CUSTOM_VIRTUAL_MACHINE
-$ adb unroot
-```
-
-Second, ensure your device is connected to the Internet.
-
-Finally, tap the VmLauncherApp app from the launcher UI. You will see
-Ferrochrome booting!
+3. Launch the app with adb.
+    ```shell
+    $ adb shell su root am start-activity -a android.virtualization.VM_LAUNCHER
+    ```
 
 If it doesn’t work well, try
 
diff --git a/guest/authfs/Android.bp b/guest/authfs/Android.bp
new file mode 100644
index 0000000..b11da3d
--- /dev/null
+++ b/guest/authfs/Android.bp
@@ -0,0 +1,52 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_defaults {
+    name: "authfs_defaults",
+    crate_name: "authfs",
+    edition: "2021",
+    srcs: [":authfs_src"],
+    rustlibs: [
+        "authfs_aidl_interface-rust",
+        "libandroid_logger",
+        "libanyhow",
+        "libauthfs_fsverity_metadata",
+        "libbinder_rs",
+        "libcfg_if",
+        "libclap",
+        "libfsverity_digests_proto_rust",
+        "libfuse_rust",
+        "libhex",
+        "liblibc",
+        "liblog_rust",
+        "libnix",
+        "libopenssl",
+        "libprotobuf",
+        "librpcbinder_rs",
+        "libthiserror",
+    ],
+    prefer_rlib: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    defaults: [
+        "crosvm_defaults",
+        "avf_build_flags_rust",
+    ],
+}
+
+filegroup {
+    name: "authfs_src",
+    srcs: [
+        "src/main.rs",
+    ],
+}
+
+rust_binary {
+    name: "authfs",
+    defaults: ["authfs_defaults"],
+    apex_available: ["com.android.virt"],
+}
diff --git a/authfs/TEST_MAPPING b/guest/authfs/TEST_MAPPING
similarity index 100%
rename from authfs/TEST_MAPPING
rename to guest/authfs/TEST_MAPPING
diff --git a/authfs/src/common.rs b/guest/authfs/src/common.rs
similarity index 100%
rename from authfs/src/common.rs
rename to guest/authfs/src/common.rs
diff --git a/authfs/src/file.rs b/guest/authfs/src/file.rs
similarity index 100%
rename from authfs/src/file.rs
rename to guest/authfs/src/file.rs
diff --git a/authfs/src/file/attr.rs b/guest/authfs/src/file/attr.rs
similarity index 100%
rename from authfs/src/file/attr.rs
rename to guest/authfs/src/file/attr.rs
diff --git a/authfs/src/file/dir.rs b/guest/authfs/src/file/dir.rs
similarity index 100%
rename from authfs/src/file/dir.rs
rename to guest/authfs/src/file/dir.rs
diff --git a/authfs/src/file/remote_file.rs b/guest/authfs/src/file/remote_file.rs
similarity index 100%
rename from authfs/src/file/remote_file.rs
rename to guest/authfs/src/file/remote_file.rs
diff --git a/authfs/src/fsstat.rs b/guest/authfs/src/fsstat.rs
similarity index 100%
rename from authfs/src/fsstat.rs
rename to guest/authfs/src/fsstat.rs
diff --git a/authfs/src/fsverity.rs b/guest/authfs/src/fsverity.rs
similarity index 100%
rename from authfs/src/fsverity.rs
rename to guest/authfs/src/fsverity.rs
diff --git a/authfs/src/fsverity/builder.rs b/guest/authfs/src/fsverity/builder.rs
similarity index 100%
rename from authfs/src/fsverity/builder.rs
rename to guest/authfs/src/fsverity/builder.rs
diff --git a/authfs/src/fsverity/common.rs b/guest/authfs/src/fsverity/common.rs
similarity index 100%
rename from authfs/src/fsverity/common.rs
rename to guest/authfs/src/fsverity/common.rs
diff --git a/authfs/src/fsverity/editor.rs b/guest/authfs/src/fsverity/editor.rs
similarity index 100%
rename from authfs/src/fsverity/editor.rs
rename to guest/authfs/src/fsverity/editor.rs
diff --git a/authfs/src/fsverity/metadata/Android.bp b/guest/authfs/src/fsverity/metadata/Android.bp
similarity index 100%
rename from authfs/src/fsverity/metadata/Android.bp
rename to guest/authfs/src/fsverity/metadata/Android.bp
diff --git a/authfs/src/fsverity/metadata/metadata.hpp b/guest/authfs/src/fsverity/metadata/metadata.hpp
similarity index 100%
rename from authfs/src/fsverity/metadata/metadata.hpp
rename to guest/authfs/src/fsverity/metadata/metadata.hpp
diff --git a/authfs/src/fsverity/metadata/metadata.rs b/guest/authfs/src/fsverity/metadata/metadata.rs
similarity index 100%
rename from authfs/src/fsverity/metadata/metadata.rs
rename to guest/authfs/src/fsverity/metadata/metadata.rs
diff --git a/authfs/src/fsverity/sys.rs b/guest/authfs/src/fsverity/sys.rs
similarity index 100%
rename from authfs/src/fsverity/sys.rs
rename to guest/authfs/src/fsverity/sys.rs
diff --git a/authfs/src/fsverity/verifier.rs b/guest/authfs/src/fsverity/verifier.rs
similarity index 100%
rename from authfs/src/fsverity/verifier.rs
rename to guest/authfs/src/fsverity/verifier.rs
diff --git a/authfs/src/fusefs.rs b/guest/authfs/src/fusefs.rs
similarity index 98%
rename from authfs/src/fusefs.rs
rename to guest/authfs/src/fusefs.rs
index ab75dac..618b8ac 100644
--- a/authfs/src/fusefs.rs
+++ b/guest/authfs/src/fusefs.rs
@@ -99,9 +99,9 @@
     /// Number of `Handle`s (i.e. file descriptors) that are currently referring to the this inode.
     ///
     /// Technically, this does not matter to readonly entries, since they live forever. The
-    /// reference count is only needed for manageing lifetime of writable entries like `VerifiedNew`
-    /// and `VerifiedNewDirectory`. That is, when an entry is deleted, the actual entry needs to
-    /// stay alive until the reference count reaches zero.
+    /// reference count is only needed for manageing lifetime of writable entries like
+    /// `VerifiedNew` and `VerifiedNewDirectory`. That is, when an entry is deleted, the actual
+    /// entry needs to stay alive until the reference count reaches zero.
     ///
     /// Note: This is not to be confused with hardlinks, which AuthFS doesn't currently implement.
     handle_ref_count: AtomicU64,
@@ -192,9 +192,9 @@
     /// The next available inode number.
     next_inode: AtomicU64,
 
-    /// Table for `Handle` to `Arc<DirEntriesSnapshot>` lookup. On `opendir`, a new directory handle
-    /// is created and the snapshot of the current directory is created. This is not super
-    /// efficient, but is the simplest way to be compliant to the FUSE contract (see
+    /// Table for `Handle` to `Arc<DirEntriesSnapshot>` lookup. On `opendir`, a new directory
+    /// handle is created and the snapshot of the current directory is created. This is not
+    /// super efficient, but is the simplest way to be compliant to the FUSE contract (see
     /// `fuse::filesystem::readdir`).
     ///
     /// Currently, no code locks `dir_handle_table` and `inode_table` at the same time to avoid
@@ -822,9 +822,9 @@
         self.handle_inode(&inode, |config| {
             match config {
                 AuthFsEntry::VerifiedNew { editor, .. } => {
-                    // FUSE ioctl is limited, thus we can't implement fs-verity ioctls without a kernel
-                    // change (see b/196635431). Until it's possible, use xattr to expose what we need
-                    // as an authfs specific API.
+                    // FUSE ioctl is limited, thus we can't implement fs-verity ioctls without a
+                    // kernel change (see b/196635431). Until it's possible, use
+                    // xattr to expose what we need as an authfs specific API.
                     if name != CStr::from_bytes_with_nul(b"authfs.fsverity.digest\0").unwrap() {
                         return Err(io::Error::from_raw_os_error(libc::ENODATA));
                     }
diff --git a/authfs/src/fusefs/file.rs b/guest/authfs/src/fusefs/file.rs
similarity index 100%
rename from authfs/src/fusefs/file.rs
rename to guest/authfs/src/fusefs/file.rs
diff --git a/authfs/src/fusefs/mount.rs b/guest/authfs/src/fusefs/mount.rs
similarity index 100%
rename from authfs/src/fusefs/mount.rs
rename to guest/authfs/src/fusefs/mount.rs
diff --git a/authfs/src/main.rs b/guest/authfs/src/main.rs
similarity index 100%
rename from authfs/src/main.rs
rename to guest/authfs/src/main.rs
diff --git a/authfs/service/Android.bp b/guest/authfs_service/Android.bp
similarity index 100%
rename from authfs/service/Android.bp
rename to guest/authfs_service/Android.bp
diff --git a/authfs/TEST_MAPPING b/guest/authfs_service/TEST_MAPPING
similarity index 100%
copy from authfs/TEST_MAPPING
copy to guest/authfs_service/TEST_MAPPING
diff --git a/authfs/service/authfs_service.rc b/guest/authfs_service/authfs_service.rc
similarity index 100%
rename from authfs/service/authfs_service.rc
rename to guest/authfs_service/authfs_service.rc
diff --git a/authfs/service/src/authfs.rs b/guest/authfs_service/src/authfs.rs
similarity index 100%
rename from authfs/service/src/authfs.rs
rename to guest/authfs_service/src/authfs.rs
diff --git a/authfs/service/src/main.rs b/guest/authfs_service/src/main.rs
similarity index 100%
rename from authfs/service/src/main.rs
rename to guest/authfs_service/src/main.rs
diff --git a/compos/compos_key_helper/Android.bp b/guest/compos_key_helper/Android.bp
similarity index 100%
rename from compos/compos_key_helper/Android.bp
rename to guest/compos_key_helper/Android.bp
diff --git a/compos/compos_key_helper/compos_key.cpp b/guest/compos_key_helper/compos_key.cpp
similarity index 100%
rename from compos/compos_key_helper/compos_key.cpp
rename to guest/compos_key_helper/compos_key.cpp
diff --git a/compos/compos_key_helper/compos_key.h b/guest/compos_key_helper/compos_key.h
similarity index 100%
rename from compos/compos_key_helper/compos_key.h
rename to guest/compos_key_helper/compos_key.h
diff --git a/compos/compos_key_helper/compos_key_main.cpp b/guest/compos_key_helper/compos_key_main.cpp
similarity index 100%
rename from compos/compos_key_helper/compos_key_main.cpp
rename to guest/compos_key_helper/compos_key_main.cpp
diff --git a/compos/compos_key_helper/compos_key_test.cpp b/guest/compos_key_helper/compos_key_test.cpp
similarity index 100%
rename from compos/compos_key_helper/compos_key_test.cpp
rename to guest/compos_key_helper/compos_key_test.cpp
diff --git a/compos/compos_key_helper/tests/AndroidTest.xml b/guest/compos_key_helper/tests/AndroidTest.xml
similarity index 100%
rename from compos/compos_key_helper/tests/AndroidTest.xml
rename to guest/compos_key_helper/tests/AndroidTest.xml
diff --git a/compos/Android.bp b/guest/compsvc/Android.bp
similarity index 100%
rename from compos/Android.bp
rename to guest/compsvc/Android.bp
diff --git a/compos/src/artifact_signer.rs b/guest/compsvc/src/artifact_signer.rs
similarity index 100%
rename from compos/src/artifact_signer.rs
rename to guest/compsvc/src/artifact_signer.rs
diff --git a/compos/src/compilation.rs b/guest/compsvc/src/compilation.rs
similarity index 100%
rename from compos/src/compilation.rs
rename to guest/compsvc/src/compilation.rs
diff --git a/compos/src/compos_key.rs b/guest/compsvc/src/compos_key.rs
similarity index 100%
rename from compos/src/compos_key.rs
rename to guest/compsvc/src/compos_key.rs
diff --git a/compos/src/compsvc.rs b/guest/compsvc/src/compsvc.rs
similarity index 100%
rename from compos/src/compsvc.rs
rename to guest/compsvc/src/compsvc.rs
diff --git a/compos/src/compsvc_main.rs b/guest/compsvc/src/compsvc_main.rs
similarity index 100%
rename from compos/src/compsvc_main.rs
rename to guest/compsvc/src/compsvc_main.rs
diff --git a/compos/src/fsverity.rs b/guest/compsvc/src/fsverity.rs
similarity index 100%
rename from compos/src/fsverity.rs
rename to guest/compsvc/src/fsverity.rs
diff --git a/libs/android_display_backend/Android.bp b/libs/android_display_backend/Android.bp
index 32587dd..f682627 100644
--- a/libs/android_display_backend/Android.bp
+++ b/libs/android_display_backend/Android.bp
@@ -46,6 +46,9 @@
         "android.system.virtualizationcommon-ndk",
         "android.system.virtualizationservice-ndk",
     ],
+    static_libs: [
+        "libbase",
+    ],
     shared_libs: [
         "libbinder_ndk",
         "libnativewindow",
diff --git a/libs/android_display_backend/aidl/android/crosvm/ICrosvmAndroidDisplayService.aidl b/libs/android_display_backend/aidl/android/crosvm/ICrosvmAndroidDisplayService.aidl
index e42cdd1..77e3a8c 100644
--- a/libs/android_display_backend/aidl/android/crosvm/ICrosvmAndroidDisplayService.aidl
+++ b/libs/android_display_backend/aidl/android/crosvm/ICrosvmAndroidDisplayService.aidl
@@ -27,4 +27,6 @@
     void setSurface(inout Surface surface, boolean forCursor);
     void setCursorStream(in ParcelFileDescriptor stream);
     void removeSurface(boolean forCursor);
+    void saveFrameForSurface(boolean forCursor);
+    void drawSavedFrameForSurface(boolean forCursor);
 }
diff --git a/libs/android_display_backend/crosvm_android_display_client.cpp b/libs/android_display_backend/crosvm_android_display_client.cpp
index 6e4a793..3802a69 100644
--- a/libs/android_display_backend/crosvm_android_display_client.cpp
+++ b/libs/android_display_backend/crosvm_android_display_client.cpp
@@ -16,6 +16,7 @@
 
 #include <aidl/android/crosvm/BnCrosvmAndroidDisplayService.h>
 #include <aidl/android/system/virtualizationservice_internal/IVirtualizationServiceInternal.h>
+#include <android-base/result.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <system/graphics.h> // for HAL_PIXEL_FORMAT_*
@@ -28,16 +29,16 @@
 using aidl::android::system::virtualizationservice_internal::IVirtualizationServiceInternal;
 using aidl::android::view::Surface;
 
+using android::base::Error;
+using android::base::Result;
+
 namespace {
 
 class SinkANativeWindow_Buffer {
 public:
-    SinkANativeWindow_Buffer() = default;
-    virtual ~SinkANativeWindow_Buffer() = default;
-
-    bool configure(uint32_t width, uint32_t height, int format) {
+    Result<void> configure(uint32_t width, uint32_t height, int format) {
         if (format != HAL_PIXEL_FORMAT_BGRA_8888) {
-            return false;
+            return Error() << "Pixel format " << format << " is not BGRA_8888.";
         }
 
         mBufferBits.resize(width * height * 4);
@@ -48,7 +49,7 @@
                 .format = format,
                 .bits = mBufferBits.data(),
         };
-        return true;
+        return {};
     }
 
     operator ANativeWindow_Buffer&() { return mBuffer; }
@@ -58,16 +59,28 @@
     std::vector<uint8_t> mBufferBits;
 };
 
-// Wrapper which contains the latest available Surface/ANativeWindow
-// from the DisplayService, if available. A Surface/ANativeWindow may
-// not always be available if, for example, the VmLauncherApp on the
-// other end of the DisplayService is not in the foreground / is paused.
+static Result<void> copyBuffer(ANativeWindow_Buffer& from, ANativeWindow_Buffer& to) {
+    if (from.width != to.width || from.height != to.height) {
+        return Error() << "dimension mismatch. from=(" << from.width << ", " << from.height << ") "
+                       << "to=(" << to.width << ", " << to.height << ")";
+    }
+    uint32_t* dst = reinterpret_cast<uint32_t*>(to.bits);
+    uint32_t* src = reinterpret_cast<uint32_t*>(from.bits);
+    size_t bytes_on_line = to.width * 4; // 4 bytes per pixel
+    for (int32_t h = 0; h < to.height; h++) {
+        memcpy(dst + (h * to.stride), src + (h * from.stride), bytes_on_line);
+    }
+    return {};
+}
+
+// Wrapper which contains the latest available Surface/ANativeWindow from the DisplayService, if
+// available. A Surface/ANativeWindow may not always be available if, for example, the VmLauncherApp
+// on the other end of the DisplayService is not in the foreground / is paused.
 class AndroidDisplaySurface {
 public:
-    AndroidDisplaySurface() = default;
-    virtual ~AndroidDisplaySurface() = default;
+    AndroidDisplaySurface(const std::string& name) : mName(name) {}
 
-    void setSurface(Surface* surface) {
+    void setNativeSurface(Surface* surface) {
         {
             std::lock_guard lk(mSurfaceMutex);
             mNativeSurface = std::make_unique<Surface>(surface->release());
@@ -90,7 +103,7 @@
         return mNativeSurface.get();
     }
 
-    void configure(uint32_t width, uint32_t height) {
+    Result<void> configure(uint32_t width, uint32_t height) {
         std::unique_lock lk(mSurfaceMutex);
 
         mRequestedSurfaceDimensions = Rect{
@@ -98,7 +111,13 @@
                 .height = height,
         };
 
-        mSinkBuffer.configure(width, height, kFormat);
+        if (auto ret = mSinkBuffer.configure(width, height, kFormat); !ret.ok()) {
+            return Error() << "Failed to configure sink buffer: " << ret.error();
+        }
+        if (auto ret = mSavedFrameBuffer.configure(width, height, kFormat); !ret.ok()) {
+            return Error() << "Failed to configure saved frame buffer: " << ret.error();
+        }
+        return {};
     }
 
     void waitForNativeSurface() {
@@ -106,7 +125,7 @@
         mNativeSurfaceReady.wait(lk, [this] { return mNativeSurface != nullptr; });
     }
 
-    int lock(ANativeWindow_Buffer* out_buffer) {
+    Result<void> lock(ANativeWindow_Buffer* out_buffer) {
         std::unique_lock lk(mSurfaceMutex);
 
         Surface* surface = mNativeSurface.get();
@@ -114,62 +133,137 @@
             // Surface not currently available but not necessarily an error
             // if, for example, the VmLauncherApp is not in the foreground.
             *out_buffer = mSinkBuffer;
-            return 0;
+            return {};
         }
 
         ANativeWindow* anw = surface->get();
         if (anw == nullptr) {
-            return -1;
+            return Error() << "Failed to get ANativeWindow";
         }
 
         if (mNativeSurfaceNeedsConfiguring) {
             if (!mRequestedSurfaceDimensions) {
-                return -1;
+                return Error() << "Surface dimension is not configured yet!";
             }
             const auto& dims = *mRequestedSurfaceDimensions;
 
             // Ensure locked buffers have our desired format.
             if (ANativeWindow_setBuffersGeometry(anw, dims.width, dims.height, kFormat) != 0) {
-                return -1;
+                return Error() << "Failed to set buffer geometry.";
             }
 
             mNativeSurfaceNeedsConfiguring = false;
         }
 
-        return ANativeWindow_lock(anw, out_buffer, nullptr);
+        if (ANativeWindow_lock(anw, out_buffer, nullptr) != 0) {
+            return Error() << "Failed to lock window";
+        }
+        mLastBuffer = *out_buffer;
+        return {};
     }
 
-    int unlockAndPost() {
+    Result<void> unlockAndPost() {
         std::unique_lock lk(mSurfaceMutex);
 
         Surface* surface = mNativeSurface.get();
         if (surface == nullptr) {
             // Surface not currently available but not necessarily an error
             // if, for example, the VmLauncherApp is not in the foreground.
-            return 0;
+            return {};
         }
 
         ANativeWindow* anw = surface->get();
         if (anw == nullptr) {
-            return -1;
+            return Error() << "Failed to get ANativeWindow";
         }
 
-        return ANativeWindow_unlockAndPost(anw);
+        if (ANativeWindow_unlockAndPost(anw) != 0) {
+            return Error() << "Failed to unlock and post window";
+        }
+        return {};
     }
 
+    // Saves the last frame drawn
+    Result<void> saveFrame() {
+        std::unique_lock lk(mSurfaceMutex);
+        if (auto ret = copyBuffer(mLastBuffer, mSavedFrameBuffer); !ret.ok()) {
+            return Error() << "Failed to copy frame: " << ret.error();
+        }
+        return {};
+    }
+
+    // Draws the saved frame
+    Result<void> drawSavedFrame() {
+        std::unique_lock lk(mSurfaceMutex);
+        Surface* surface = mNativeSurface.get();
+        if (surface == nullptr) {
+            return Error() << "Surface not ready";
+        }
+
+        ANativeWindow* anw = surface->get();
+        if (anw == nullptr) {
+            return Error() << "Failed to get ANativeWindow";
+        }
+
+        // TODO: dedup this and the one in lock(...)
+        if (mNativeSurfaceNeedsConfiguring) {
+            if (!mRequestedSurfaceDimensions) {
+                return Error() << "Surface dimension is not configured yet!";
+            }
+            const auto& dims = *mRequestedSurfaceDimensions;
+
+            // Ensure locked buffers have our desired format.
+            if (ANativeWindow_setBuffersGeometry(anw, dims.width, dims.height, kFormat) != 0) {
+                return Error() << "Failed to set buffer geometry.";
+            }
+
+            mNativeSurfaceNeedsConfiguring = false;
+        }
+
+        ANativeWindow_Buffer buf;
+        if (ANativeWindow_lock(anw, &buf, nullptr) != 0) {
+            return Error() << "Failed to lock window";
+        }
+
+        if (auto ret = copyBuffer(mSavedFrameBuffer, buf); !ret.ok()) {
+            return Error() << "Failed to copy frame: " << ret.error();
+        }
+
+        if (ANativeWindow_unlockAndPost(anw) != 0) {
+            return Error() << "Failed to unlock and post window";
+        }
+        return {};
+    }
+
+    const std::string& name() const { return mName; }
+
 private:
     // Note: crosvm always uses BGRA8888 or BGRX8888. See devices/src/virtio/gpu/mod.rs in
     // crosvm where the SetScanoutBlob command is handled. Let's use BGRA not BGRX with a hope
     // that we will need alpha blending for the cursor surface.
     static constexpr const int kFormat = HAL_PIXEL_FORMAT_BGRA_8888;
 
+    std::string mName;
+
     std::mutex mSurfaceMutex;
     std::unique_ptr<Surface> mNativeSurface;
     std::condition_variable mNativeSurfaceReady;
     bool mNativeSurfaceNeedsConfiguring = true;
 
+    // Buffer which crosvm uses when in background. This is just to not fail crosvm even when
+    // Android-side Surface doesn't exist. The content drawn here is never displayed on the physical
+    // screen.
     SinkANativeWindow_Buffer mSinkBuffer;
 
+    // Buffer which is currently allocated for crosvm to draw onto. This holds the last frame. This
+    // is what gets displayed on the physical screen.
+    ANativeWindow_Buffer mLastBuffer;
+
+    // Copy of mLastBuffer made by the call saveFrameForSurface. This holds the last good (i.e.
+    // non-blank) frame before the VM goes background. When the VM is brought up to foreground,
+    // this is drawn to the physical screen until the VM starts to emit actual frames.
+    SinkANativeWindow_Buffer mSavedFrameBuffer;
+
     struct Rect {
         uint32_t width = 0;
         uint32_t height = 0;
@@ -183,35 +277,50 @@
     virtual ~DisplayService() = default;
 
     ndk::ScopedAStatus setSurface(Surface* surface, bool forCursor) override {
-        if (forCursor) {
-            mCursor.setSurface(surface);
-        } else {
-            mScanout.setSurface(surface);
-        }
+        getSurface(forCursor).setNativeSurface(surface);
         return ::ndk::ScopedAStatus::ok();
     }
 
     ndk::ScopedAStatus removeSurface(bool forCursor) override {
-        if (forCursor) {
-            mCursor.removeSurface();
-        } else {
-            mScanout.removeSurface();
-        }
+        getSurface(forCursor).removeSurface();
         return ::ndk::ScopedAStatus::ok();
     }
 
-    AndroidDisplaySurface* getCursorSurface() { return &mCursor; }
-    AndroidDisplaySurface* getScanoutSurface() { return &mScanout; }
-
     ndk::ScopedFileDescriptor& getCursorStream() { return mCursorStream; }
     ndk::ScopedAStatus setCursorStream(const ndk::ScopedFileDescriptor& in_stream) {
         mCursorStream = ndk::ScopedFileDescriptor(dup(in_stream.get()));
         return ::ndk::ScopedAStatus::ok();
     }
 
+    ndk::ScopedAStatus saveFrameForSurface(bool forCursor) override {
+        if (auto ret = getSurface(forCursor).saveFrame(); !ret.ok()) {
+            std::string msg = std::format("Failed to save frame: {}", ret.error().message());
+            return ::ndk::ScopedAStatus(
+                    AStatus_fromServiceSpecificErrorWithMessage(-1, msg.c_str()));
+        }
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    ndk::ScopedAStatus drawSavedFrameForSurface(bool forCursor) override {
+        if (auto ret = getSurface(forCursor).drawSavedFrame(); !ret.ok()) {
+            std::string msg = std::format("Failed to draw saved frame: {}", ret.error().message());
+            return ::ndk::ScopedAStatus(
+                    AStatus_fromServiceSpecificErrorWithMessage(-1, msg.c_str()));
+        }
+        return ::ndk::ScopedAStatus::ok();
+    }
+
+    AndroidDisplaySurface& getSurface(bool forCursor) {
+        if (forCursor) {
+            return mCursor;
+        } else {
+            return mScanout;
+        }
+    }
+
 private:
-    AndroidDisplaySurface mScanout;
-    AndroidDisplaySurface mCursor;
+    AndroidDisplaySurface mScanout{"scanout"};
+    AndroidDisplaySurface mCursor{"cursor"};
     ndk::ScopedFileDescriptor mCursorStream;
 };
 
@@ -287,21 +396,18 @@
         return nullptr;
     }
 
-    AndroidDisplaySurface* displaySurface = forCursor ? ctx->disp_service->getCursorSurface()
-                                                      : ctx->disp_service->getScanoutSurface();
-    if (displaySurface == nullptr) {
-        ctx->errorf("AndroidDisplaySurface was not created");
-        return nullptr;
+    AndroidDisplaySurface& surface = ctx->disp_service->getSurface(forCursor);
+    if (auto ret = surface.configure(width, height); !ret.ok()) {
+        ctx->errorf("Failed to configure surface %s: %s", surface.name().c_str(),
+                    ret.error().message().c_str());
     }
 
-    displaySurface->configure(width, height);
-
-    displaySurface->waitForNativeSurface(); // this can block
+    surface.waitForNativeSurface(); // this can block
 
     // TODO(b/332785161): if we know that surface can get destroyed dynamically while VM is running,
     // consider calling ANativeWindow_acquire here and _release in destroy_android_surface, so that
     // crosvm doesn't hold a dangling pointer.
-    return displaySurface;
+    return &surface;
 }
 
 extern "C" void destroy_android_surface(struct AndroidDisplayContext*, ANativeWindow*) {
@@ -321,8 +427,10 @@
         return false;
     }
 
-    if (surface->lock(out_buffer) != 0) {
-        ctx->errorf("Failed to lock buffer");
+    auto ret = surface->lock(out_buffer);
+    if (!ret.ok()) {
+        ctx->errorf("Failed to lock surface %s: %s", surface->name().c_str(),
+                    ret.error().message().c_str());
         return false;
     }
 
@@ -351,8 +459,10 @@
         return;
     }
 
-    if (surface->unlockAndPost() != 0) {
-        ctx->errorf("Failed to unlock and post AndroidDisplaySurface.");
-        return;
+    auto ret = surface->unlockAndPost();
+    if (!ret.ok()) {
+        ctx->errorf("Failed to unlock and post for surface %s: %s", surface->name().c_str(),
+                    ret.error().message().c_str());
     }
+    return;
 }
diff --git a/authfs/aidl/Android.bp b/libs/authfs_aidl_interface/Android.bp
similarity index 100%
rename from authfs/aidl/Android.bp
rename to libs/authfs_aidl_interface/Android.bp
diff --git a/authfs/TEST_MAPPING b/libs/authfs_aidl_interface/TEST_MAPPING
similarity index 100%
copy from authfs/TEST_MAPPING
copy to libs/authfs_aidl_interface/TEST_MAPPING
diff --git a/authfs/aidl/com/android/virt/fs/AuthFsConfig.aidl b/libs/authfs_aidl_interface/com/android/virt/fs/AuthFsConfig.aidl
similarity index 100%
rename from authfs/aidl/com/android/virt/fs/AuthFsConfig.aidl
rename to libs/authfs_aidl_interface/com/android/virt/fs/AuthFsConfig.aidl
diff --git a/authfs/aidl/com/android/virt/fs/IAuthFs.aidl b/libs/authfs_aidl_interface/com/android/virt/fs/IAuthFs.aidl
similarity index 100%
rename from authfs/aidl/com/android/virt/fs/IAuthFs.aidl
rename to libs/authfs_aidl_interface/com/android/virt/fs/IAuthFs.aidl
diff --git a/authfs/aidl/com/android/virt/fs/IAuthFsService.aidl b/libs/authfs_aidl_interface/com/android/virt/fs/IAuthFsService.aidl
similarity index 100%
rename from authfs/aidl/com/android/virt/fs/IAuthFsService.aidl
rename to libs/authfs_aidl_interface/com/android/virt/fs/IAuthFsService.aidl
diff --git a/authfs/aidl/com/android/virt/fs/IVirtFdService.aidl b/libs/authfs_aidl_interface/com/android/virt/fs/IVirtFdService.aidl
similarity index 100%
rename from authfs/aidl/com/android/virt/fs/IVirtFdService.aidl
rename to libs/authfs_aidl_interface/com/android/virt/fs/IVirtFdService.aidl
diff --git a/compos/aidl/Android.bp b/libs/compos_aidl_interface/Android.bp
similarity index 100%
rename from compos/aidl/Android.bp
rename to libs/compos_aidl_interface/Android.bp
diff --git a/compos/aidl/com/android/compos/ICompOsService.aidl b/libs/compos_aidl_interface/com/android/compos/ICompOsService.aidl
similarity index 100%
rename from compos/aidl/com/android/compos/ICompOsService.aidl
rename to libs/compos_aidl_interface/com/android/compos/ICompOsService.aidl
diff --git a/compos/common/Android.bp b/libs/libcompos_common/Android.bp
similarity index 100%
rename from compos/common/Android.bp
rename to libs/libcompos_common/Android.bp
diff --git a/compos/common/binder.rs b/libs/libcompos_common/binder.rs
similarity index 100%
rename from compos/common/binder.rs
rename to libs/libcompos_common/binder.rs
diff --git a/compos/common/compos_client.rs b/libs/libcompos_common/compos_client.rs
similarity index 100%
rename from compos/common/compos_client.rs
rename to libs/libcompos_common/compos_client.rs
diff --git a/compos/common/lib.rs b/libs/libcompos_common/lib.rs
similarity index 100%
rename from compos/common/lib.rs
rename to libs/libcompos_common/lib.rs
diff --git a/compos/common/odrefresh.rs b/libs/libcompos_common/odrefresh.rs
similarity index 100%
rename from compos/common/odrefresh.rs
rename to libs/libcompos_common/odrefresh.rs
diff --git a/compos/common/timeouts.rs b/libs/libcompos_common/timeouts.rs
similarity index 100%
rename from compos/common/timeouts.rs
rename to libs/libcompos_common/timeouts.rs
diff --git a/libs/libvmbase/src/console.rs b/libs/libvmbase/src/console.rs
index cd05250..7b01bb6 100644
--- a/libs/libvmbase/src/console.rs
+++ b/libs/libvmbase/src/console.rs
@@ -23,8 +23,8 @@
 // Matches the UART count in crosvm.
 const MAX_CONSOLES: usize = 4;
 
-static CONSOLES: [SpinMutex<Option<Uart>>; MAX_CONSOLES] =
-    [SpinMutex::new(None), SpinMutex::new(None), SpinMutex::new(None), SpinMutex::new(None)];
+static CONSOLES: [Once<SpinMutex<Uart>>; MAX_CONSOLES] =
+    [Once::new(), Once::new(), Once::new(), Once::new()];
 static ADDRESSES: [Once<usize>; MAX_CONSOLES] =
     [Once::new(), Once::new(), Once::new(), Once::new()];
 
@@ -48,10 +48,10 @@
         ADDRESSES[i].call_once(|| base_address);
 
         // Initialize the console driver, for normal console accesses.
-        let mut console = CONSOLES[i].lock();
-        assert!(console.is_none(), "console::init() called more than once");
-        // SAFETY: base_address must be the base of a mapped UART.
-        console.replace(unsafe { Uart::new(base_address) });
+        assert!(!CONSOLES[i].is_completed(), "console::init() called more than once");
+        // SAFETY: The caller promised that base_address is the base of a mapped UART with no
+        // aliases.
+        CONSOLES[i].call_once(|| SpinMutex::new(unsafe { Uart::new(base_address) }));
     }
 }
 
@@ -59,8 +59,7 @@
 ///
 /// Panics if the n-th console was not initialized by calling [`init`] first.
 pub fn writeln(n: usize, format_args: Arguments) {
-    let mut guard = CONSOLES[n].lock();
-    let uart = guard.as_mut().unwrap();
+    let uart = &mut *CONSOLES[n].get().unwrap().lock();
 
     write(uart, format_args).unwrap();
     let _ = uart.write_str("\n");
diff --git a/compos/service/Android.bp b/libs/service-compos/Android.bp
similarity index 100%
rename from compos/service/Android.bp
rename to libs/service-compos/Android.bp
diff --git a/compos/service/java/com/android/server/compos/IsolatedCompilationJobService.java b/libs/service-compos/java/com/android/server/compos/IsolatedCompilationJobService.java
similarity index 89%
rename from compos/service/java/com/android/server/compos/IsolatedCompilationJobService.java
rename to libs/service-compos/java/com/android/server/compos/IsolatedCompilationJobService.java
index 933ac7a..adc0300 100644
--- a/compos/service/java/com/android/server/compos/IsolatedCompilationJobService.java
+++ b/libs/service-compos/java/com/android/server/compos/IsolatedCompilationJobService.java
@@ -52,14 +52,16 @@
         ComponentName serviceName =
                 new ComponentName("android", IsolatedCompilationJobService.class.getName());
 
-        int result = scheduler.schedule(new JobInfo.Builder(STAGED_APEX_JOB_ID, serviceName)
-                // Wait in case more APEXes are staged
-                .setMinimumLatency(TimeUnit.MINUTES.toMillis(60))
-                // We consume CPU, power, and storage
-                .setRequiresDeviceIdle(true)
-                .setRequiresCharging(true)
-                .setRequiresStorageNotLow(true)
-                .build());
+        int result =
+                scheduler.schedule(
+                        new JobInfo.Builder(STAGED_APEX_JOB_ID, serviceName)
+                                // Wait in case more APEXes are staged
+                                .setMinimumLatency(TimeUnit.MINUTES.toMillis(60))
+                                // We consume CPU, power, and storage
+                                .setRequiresDeviceIdle(true)
+                                .setRequiresCharging(true)
+                                .setRequiresStorageNotLow(true)
+                                .build());
         if (result == JobScheduler.RESULT_SUCCESS) {
             IsolatedCompilationMetrics.onCompilationScheduled(
                     IsolatedCompilationMetrics.SCHEDULING_SUCCESS);
@@ -86,13 +88,14 @@
         if (oldJob != null) {
             // We're already running a job, give up on this one
             Log.w(TAG, "Another job is in progress, skipping");
-            return false;  // Already finished
+            return false; // Already finished
         }
 
         IsolatedCompilationMetrics metrics = new IsolatedCompilationMetrics();
 
-        CompilationJob newJob = new CompilationJob(IsolatedCompilationJobService.this::onCompletion,
-                params, metrics);
+        CompilationJob newJob =
+                new CompilationJob(
+                        IsolatedCompilationJobService.this::onCompletion, params, metrics);
         mCurrentJob.set(newJob);
 
         // This can take some time - we need to start up a VM - so we do it on a separate
@@ -108,7 +111,7 @@
                     metrics.onCompilationEnded(IsolatedCompilationMetrics.RESULT_FAILED_TO_START);
                     mCurrentJob.set(null);
                     newJob.stop(); // Just in case it managed to start before failure
-                    jobFinished(params, /*wantReschedule=*/ false);
+                    jobFinished(params, /* wantReschedule= */ false);
                 }
             }
         }.start();
@@ -137,7 +140,7 @@
         // On success we don't need to reschedule.
         // On failure we could reschedule, but that could just use a lot of resources and still
         // fail; instead we just let odsign do compilation on reboot if necessary.
-        jobFinished(params, /*wantReschedule=*/ false);
+        jobFinished(params, /* wantReschedule= */ false);
     }
 
     interface CompilationCallback {
@@ -152,7 +155,9 @@
         private final JobParameters mParams;
         private volatile boolean mStopRequested = false;
 
-        CompilationJob(CompilationCallback callback, JobParameters params,
+        CompilationJob(
+                CompilationCallback callback,
+                JobParameters params,
                 IsolatedCompilationMetrics metrics) {
             mCallback = requireNonNull(callback);
             mParams = params;
diff --git a/compos/service/java/com/android/server/compos/IsolatedCompilationMetrics.java b/libs/service-compos/java/com/android/server/compos/IsolatedCompilationMetrics.java
similarity index 77%
rename from compos/service/java/com/android/server/compos/IsolatedCompilationMetrics.java
rename to libs/service-compos/java/com/android/server/compos/IsolatedCompilationMetrics.java
index f7799a4..0419a55 100644
--- a/compos/service/java/com/android/server/compos/IsolatedCompilationMetrics.java
+++ b/libs/service-compos/java/com/android/server/compos/IsolatedCompilationMetrics.java
@@ -61,10 +61,11 @@
             ArtStatsLog.ISOLATED_COMPILATION_ENDED__COMPILATION_RESULT__RESULT_FAILED_TO_START;
     public static final int RESULT_JOB_CANCELED =
             ArtStatsLog.ISOLATED_COMPILATION_ENDED__COMPILATION_RESULT__RESULT_JOB_CANCELED;
-    public static final int RESULT_COMPILATION_FAILED = ArtStatsLog
-            .ISOLATED_COMPILATION_ENDED__COMPILATION_RESULT__RESULT_COMPILATION_FAILED;
-    public static final int RESULT_UNEXPECTED_COMPILATION_RESULT = ArtStatsLog
-            .ISOLATED_COMPILATION_ENDED__COMPILATION_RESULT__RESULT_UNEXPECTED_COMPILATION_RESULT;
+    public static final int RESULT_COMPILATION_FAILED =
+            ArtStatsLog.ISOLATED_COMPILATION_ENDED__COMPILATION_RESULT__RESULT_COMPILATION_FAILED;
+    public static final int RESULT_UNEXPECTED_COMPILATION_RESULT =
+            ArtStatsLog
+                    .ISOLATED_COMPILATION_ENDED__COMPILATION_RESULT__RESULT_UNEXPECTED_COMPILATION_RESULT;
     public static final int RESULT_COMPOSD_DIED =
             ArtStatsLog.ISOLATED_COMPILATION_ENDED__COMPILATION_RESULT__RESULT_COMPOSD_DIED;
     public static final int RESULT_FAILED_TO_ENABLE_FSVERITY =
@@ -78,8 +79,9 @@
     // Keep this in sync with Result enum in IsolatedCompilationScheduled in
     // frameworks/proto_logging/stats/atoms.proto
 
-    public static final int SCHEDULING_RESULT_UNKNOWN = ArtStatsLog
-            .ISOLATED_COMPILATION_SCHEDULED__SCHEDULING_RESULT__SCHEDULING_RESULT_UNKNOWN;
+    public static final int SCHEDULING_RESULT_UNKNOWN =
+            ArtStatsLog
+                    .ISOLATED_COMPILATION_SCHEDULED__SCHEDULING_RESULT__SCHEDULING_RESULT_UNKNOWN;
     public static final int SCHEDULING_FAILURE =
             ArtStatsLog.ISOLATED_COMPILATION_SCHEDULED__SCHEDULING_RESULT__SCHEDULING_FAILURE;
     public static final int SCHEDULING_SUCCESS =
@@ -104,16 +106,24 @@
         statsLogPostCompilation(result, JobParameters.STOP_REASON_UNDEFINED);
     }
 
-    private void statsLogPostCompilation(@CompilationResult int result,
-                @JobParameters.StopReason int jobStopReason) {
+    private void statsLogPostCompilation(
+            @CompilationResult int result, @JobParameters.StopReason int jobStopReason) {
 
-        long compilationTime = mCompilationStartTimeMs == 0 ? -1
-                : SystemClock.elapsedRealtime() - mCompilationStartTimeMs;
+        long compilationTime =
+                mCompilationStartTimeMs == 0
+                        ? -1
+                        : SystemClock.elapsedRealtime() - mCompilationStartTimeMs;
         mCompilationStartTimeMs = 0;
 
-        ArtStatsLog.write(ArtStatsLog.ISOLATED_COMPILATION_ENDED, compilationTime,
-                result, jobStopReason);
-        Log.i(TAG, "ISOLATED_COMPILATION_ENDED: " + result + ", " + compilationTime
-                + ", " + jobStopReason);
+        ArtStatsLog.write(
+                ArtStatsLog.ISOLATED_COMPILATION_ENDED, compilationTime, result, jobStopReason);
+        Log.i(
+                TAG,
+                "ISOLATED_COMPILATION_ENDED: "
+                        + result
+                        + ", "
+                        + compilationTime
+                        + ", "
+                        + jobStopReason);
     }
 }
diff --git a/compos/service/java/com/android/server/compos/IsolatedCompilationService.java b/libs/service-compos/java/com/android/server/compos/IsolatedCompilationService.java
similarity index 94%
rename from compos/service/java/com/android/server/compos/IsolatedCompilationService.java
rename to libs/service-compos/java/com/android/server/compos/IsolatedCompilationService.java
index b2fcbe0..95e365d 100644
--- a/compos/service/java/com/android/server/compos/IsolatedCompilationService.java
+++ b/libs/service-compos/java/com/android/server/compos/IsolatedCompilationService.java
@@ -60,7 +60,6 @@
             return;
         }
 
-
         JobScheduler scheduler = getContext().getSystemService(JobScheduler.class);
         if (scheduler == null) {
             Log.e(TAG, "No scheduler");
@@ -92,8 +91,9 @@
         private final IPackageManagerNative mPackageNative;
 
         static void registerForStagedApexUpdates(JobScheduler scheduler) {
-            final IPackageManagerNative packageNative = IPackageManagerNative.Stub.asInterface(
-                    ServiceManager.getService("package_native"));
+            final IPackageManagerNative packageNative =
+                    IPackageManagerNative.Stub.asInterface(
+                            ServiceManager.getService("package_native"));
             if (packageNative == null) {
                 Log.e(TAG, "No IPackageManagerNative");
                 return;
@@ -110,8 +110,7 @@
             }
         }
 
-        private StagedApexObserver(JobScheduler scheduler,
-                IPackageManagerNative packageNative) {
+        private StagedApexObserver(JobScheduler scheduler, IPackageManagerNative packageNative) {
             mScheduler = scheduler;
             mPackageNative = packageNative;
         }
diff --git a/compos/benchmark/Android.bp b/tests/ComposBenchmarkApp/Android.bp
similarity index 100%
rename from compos/benchmark/Android.bp
rename to tests/ComposBenchmarkApp/Android.bp
diff --git a/compos/benchmark/AndroidManifest.xml b/tests/ComposBenchmarkApp/AndroidManifest.xml
similarity index 100%
rename from compos/benchmark/AndroidManifest.xml
rename to tests/ComposBenchmarkApp/AndroidManifest.xml
diff --git a/compos/benchmark/AndroidTest.xml b/tests/ComposBenchmarkApp/AndroidTest.xml
similarity index 100%
rename from compos/benchmark/AndroidTest.xml
rename to tests/ComposBenchmarkApp/AndroidTest.xml
diff --git a/compos/benchmark/src/java/com/android/compos/benchmark/ComposBenchmark.java b/tests/ComposBenchmarkApp/src/java/com/android/compos/benchmark/ComposBenchmark.java
similarity index 100%
rename from compos/benchmark/src/java/com/android/compos/benchmark/ComposBenchmark.java
rename to tests/ComposBenchmarkApp/src/java/com/android/compos/benchmark/ComposBenchmark.java
diff --git a/compos/tests/Android.bp b/tests/ComposHostTestCases/Android.bp
similarity index 100%
rename from compos/tests/Android.bp
rename to tests/ComposHostTestCases/Android.bp
diff --git a/compos/tests/AndroidTest.xml b/tests/ComposHostTestCases/AndroidTest.xml
similarity index 100%
rename from compos/tests/AndroidTest.xml
rename to tests/ComposHostTestCases/AndroidTest.xml
diff --git a/compos/tests/java/android/compos/test/ComposTestCase.java b/tests/ComposHostTestCases/java/android/compos/test/ComposTestCase.java
similarity index 90%
rename from compos/tests/java/android/compos/test/ComposTestCase.java
rename to tests/ComposHostTestCases/java/android/compos/test/ComposTestCase.java
index b31f4f3..7a35829 100644
--- a/compos/tests/java/android/compos/test/ComposTestCase.java
+++ b/tests/ComposHostTestCases/java/android/compos/test/ComposTestCase.java
@@ -54,8 +54,7 @@
     // Binaries used in test. (These paths are valid both in host and Microdroid.)
     private static final String ODREFRESH_BIN = "/apex/com.android.art/bin/odrefresh";
     private static final String COMPOSD_CMD_BIN = "/apex/com.android.compos/bin/composd_cmd";
-    private static final String COMPOS_VERIFY_BIN =
-            "/apex/com.android.compos/bin/compos_verify";
+    private static final String COMPOS_VERIFY_BIN = "/apex/com.android.compos/bin/compos_verify";
 
     private static final String COMPOS_APEXDATA_DIR = "/data/misc/apexdata/com.android.compos";
 
@@ -111,10 +110,13 @@
         android.tryRun("rm", "-rf", ODREFRESH_OUTPUT_DIR);
 
         if (mBackupSystemServerCompilerFilter != null) {
-            CLog.d("Restore dalvik.vm.systemservercompilerfilter to "
-                    + mBackupSystemServerCompilerFilter);
-            getDevice().setProperty(SYSTEM_SERVER_COMPILER_FILTER_PROP_NAME,
-                    mBackupSystemServerCompilerFilter);
+            CLog.d(
+                    "Restore dalvik.vm.systemservercompilerfilter to "
+                            + mBackupSystemServerCompilerFilter);
+            getDevice()
+                    .setProperty(
+                            SYSTEM_SERVER_COMPILER_FILTER_PROP_NAME,
+                            mBackupSystemServerCompilerFilter);
         }
     }
 
@@ -143,8 +145,8 @@
         }
 
         // Save the expected checksum for the output directory.
-        String expectedChecksumSnapshot = checksumDirectoryContentPartial(android,
-                ODREFRESH_OUTPUT_DIR);
+        String expectedChecksumSnapshot =
+                checksumDirectoryContentPartial(android, ODREFRESH_OUTPUT_DIR);
 
         // --check may delete the output.
         CommandResult result = runOdrefresh(android, "--check");
@@ -166,8 +168,8 @@
         assertVmBccIsValid();
 
         // Save the actual checksum for the output directory.
-        String actualChecksumSnapshot = checksumDirectoryContentPartial(android,
-                ODREFRESH_OUTPUT_DIR);
+        String actualChecksumSnapshot =
+                checksumDirectoryContentPartial(android, ODREFRESH_OUTPUT_DIR);
 
         // Expect the output of Comp OS to be the same as compiled on Android.
         assertThat(actualChecksumSnapshot).isEqualTo(expectedChecksumSnapshot);
@@ -185,11 +187,12 @@
         assertThat(bcc_file).isNotNull();
 
         // Add the BCC to test artifacts, in case it is ill-formed or otherwise interesting.
-        mTestLogs.addTestLog(bcc_file.getPath(), LogDataType.UNKNOWN,
-                new FileInputStreamSource(bcc_file));
+        mTestLogs.addTestLog(
+                bcc_file.getPath(), LogDataType.UNKNOWN, new FileInputStreamSource(bcc_file));
 
         // Find the validator binary - note that it's specified as a dependency in our Android.bp.
-        File validator = getTestInformation().getDependencyFile("hwtrust", /*targetFirst=*/ false);
+        File validator =
+                getTestInformation().getDependencyFile("hwtrust", /* targetFirst= */ false);
 
         CommandResult result =
                 new RunUtil()
diff --git a/authfs/Android.bp b/tests/authfs/Android.bp
similarity index 60%
rename from authfs/Android.bp
rename to tests/authfs/Android.bp
index e04d5e1..aa814eb 100644
--- a/authfs/Android.bp
+++ b/tests/authfs/Android.bp
@@ -1,51 +1,3 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-rust_defaults {
-    name: "authfs_defaults",
-    crate_name: "authfs",
-    srcs: [
-        "src/main.rs",
-    ],
-    edition: "2021",
-    rustlibs: [
-        "authfs_aidl_interface-rust",
-        "libandroid_logger",
-        "libanyhow",
-        "libauthfs_fsverity_metadata",
-        "libbinder_rs",
-        "libcfg_if",
-        "libclap",
-        "libfsverity_digests_proto_rust",
-        "libfuse_rust",
-        "libhex",
-        "liblibc",
-        "liblog_rust",
-        "libnix",
-        "libopenssl",
-        "libprotobuf",
-        "librpcbinder_rs",
-        "libthiserror",
-    ],
-    prefer_rlib: true,
-    target: {
-        darwin: {
-            enabled: false,
-        },
-    },
-    defaults: [
-        "crosvm_defaults",
-        "avf_build_flags_rust",
-    ],
-}
-
-rust_binary {
-    name: "authfs",
-    defaults: ["authfs_defaults"],
-    apex_available: ["com.android.virt"],
-}
-
 rust_test {
     name: "authfs_device_test_src_lib",
     defaults: ["authfs_defaults"],
diff --git a/authfs/TEST_MAPPING b/tests/authfs/TEST_MAPPING
similarity index 100%
copy from authfs/TEST_MAPPING
copy to tests/authfs/TEST_MAPPING
diff --git a/authfs/tests/benchmarks/Android.bp b/tests/authfs/benchmarks/Android.bp
similarity index 100%
rename from authfs/tests/benchmarks/Android.bp
rename to tests/authfs/benchmarks/Android.bp
diff --git a/authfs/tests/benchmarks/AndroidTest.xml b/tests/authfs/benchmarks/AndroidTest.xml
similarity index 100%
rename from authfs/tests/benchmarks/AndroidTest.xml
rename to tests/authfs/benchmarks/AndroidTest.xml
diff --git a/authfs/tests/benchmarks/src/java/com/android/fs/benchmarks/AuthFsBenchmarks.java b/tests/authfs/benchmarks/src/java/com/android/fs/benchmarks/AuthFsBenchmarks.java
similarity index 99%
rename from authfs/tests/benchmarks/src/java/com/android/fs/benchmarks/AuthFsBenchmarks.java
rename to tests/authfs/benchmarks/src/java/com/android/fs/benchmarks/AuthFsBenchmarks.java
index 085d06e..abda3e3 100644
--- a/authfs/tests/benchmarks/src/java/com/android/fs/benchmarks/AuthFsBenchmarks.java
+++ b/tests/authfs/benchmarks/src/java/com/android/fs/benchmarks/AuthFsBenchmarks.java
@@ -18,7 +18,6 @@
 
 import static com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestMetrics;
 
-
 import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeTrue;
 
diff --git a/authfs/tests/benchmarks/src/measure_io.cpp b/tests/authfs/benchmarks/src/measure_io.cpp
similarity index 100%
rename from authfs/tests/benchmarks/src/measure_io.cpp
rename to tests/authfs/benchmarks/src/measure_io.cpp
diff --git a/authfs/tests/common/Android.bp b/tests/authfs/common/Android.bp
similarity index 100%
rename from authfs/tests/common/Android.bp
rename to tests/authfs/common/Android.bp
diff --git a/authfs/tests/common/src/java/com/android/fs/common/AuthFsTestRule.java b/tests/authfs/common/src/java/com/android/fs/common/AuthFsTestRule.java
similarity index 100%
rename from authfs/tests/common/src/java/com/android/fs/common/AuthFsTestRule.java
rename to tests/authfs/common/src/java/com/android/fs/common/AuthFsTestRule.java
diff --git a/authfs/tests/common/src/open_then_run.rs b/tests/authfs/common/src/open_then_run.rs
similarity index 100%
rename from authfs/tests/common/src/open_then_run.rs
rename to tests/authfs/common/src/open_then_run.rs
diff --git a/authfs/tests/hosttests/Android.bp b/tests/authfs/hosttests/Android.bp
similarity index 100%
rename from authfs/tests/hosttests/Android.bp
rename to tests/authfs/hosttests/Android.bp
diff --git a/authfs/tests/hosttests/AndroidTest.xml b/tests/authfs/hosttests/AndroidTest.xml
similarity index 100%
rename from authfs/tests/hosttests/AndroidTest.xml
rename to tests/authfs/hosttests/AndroidTest.xml
diff --git a/authfs/tests/hosttests/java/src/com/android/fs/AuthFsHostTest.java b/tests/authfs/hosttests/java/src/com/android/fs/AuthFsHostTest.java
similarity index 87%
rename from authfs/tests/hosttests/java/src/com/android/fs/AuthFsHostTest.java
rename to tests/authfs/hosttests/java/src/com/android/fs/AuthFsHostTest.java
index d0a7c66..0a27506 100644
--- a/authfs/tests/hosttests/java/src/com/android/fs/AuthFsHostTest.java
+++ b/tests/authfs/hosttests/java/src/com/android/fs/AuthFsHostTest.java
@@ -75,8 +75,8 @@
     @BeforeClassWithInfo
     public static void beforeClassWithDevice(TestInformation testInfo) throws Exception {
         AuthFsTestRule.setUpAndroid(testInfo);
-        assumeTrue(AuthFsTestRule.getDevice().supportsMicrodroid(/*protectedVm=*/ true));
-        AuthFsTestRule.startMicrodroid(/*protectedVm=*/ true);
+        assumeTrue(AuthFsTestRule.getDevice().supportsMicrodroid(/* protectedVm= */ true));
+        AuthFsTestRule.startMicrodroid(/* protectedVm= */ true);
         sAndroid = AuthFsTestRule.getAndroid();
         sMicrodroid = AuthFsTestRule.getMicrodroid();
     }
@@ -114,7 +114,7 @@
         // Setup
         runFdServerOnAndroid(
                 "--open-ro 3:input.4k --open-ro 4:input.4k.fsv_meta --open-ro"
-                    + " 6:input.4k1 --open-ro 7:input.4k1.fsv_meta",
+                        + " 6:input.4k1 --open-ro 7:input.4k1.fsv_meta",
                 "--ro-fds 3:4 --ro-fds 6:7");
         runAuthFsOnMicrodroid(
                 "--remote-ro-file 3:" + DIGEST_4K + " --remote-ro-file 6:" + DIGEST_4K1);
@@ -135,8 +135,7 @@
     public void testReadWithFsverityVerification_TamperedMerkleTree() throws Exception {
         // Setup
         runFdServerOnAndroid(
-                "--open-ro 3:input.4m --open-ro 4:input.4m.fsv_meta.bad_merkle",
-                "--ro-fds 3:4");
+                "--open-ro 3:input.4m --open-ro 4:input.4m.fsv_meta.bad_merkle", "--ro-fds 3:4");
         runAuthFsOnMicrodroid("--remote-ro-file 3:" + DIGEST_4M);
 
         // Verify
@@ -190,8 +189,12 @@
         // Action
         // Tampering with the first 2 4K-blocks of the backing file.
         assertThat(
-                writeZerosAtFileOffset(sAndroid, backendPath,
-                        /* offset */ 0, /* number */ 8192, /* writeThrough */ false))
+                        writeZerosAtFileOffset(
+                                sAndroid,
+                                backendPath,
+                                /* offset */ 0, /* number */
+                                8192, /* writeThrough */
+                                false))
                 .isSuccess();
 
         // Verify
@@ -199,21 +202,33 @@
         // when the content is inconsistent to the known hash. Use direct I/O to avoid simply
         // writing to the filesystem cache.
         assertThat(
-                writeZerosAtFileOffset(sMicrodroid, destPath,
-                        /* offset */ 0, /* number */ 1024, /* writeThrough */ true))
+                        writeZerosAtFileOffset(
+                                sMicrodroid,
+                                destPath,
+                                /* offset */ 0, /* number */
+                                1024, /* writeThrough */
+                                true))
                 .isFailed();
 
         // A full 4K write does not require to read back, so write can succeed even if the backing
         // block has already been tampered.
         assertThat(
-                writeZerosAtFileOffset(sMicrodroid, destPath,
-                        /* offset */ 4096, /* number */ 4096, /* writeThrough */ false))
+                        writeZerosAtFileOffset(
+                                sMicrodroid,
+                                destPath,
+                                /* offset */ 4096, /* number */
+                                4096, /* writeThrough */
+                                false))
                 .isSuccess();
 
         // Otherwise, a partial write with correct backing file should still succeed.
         assertThat(
-                writeZerosAtFileOffset(sMicrodroid, destPath,
-                        /* offset */ 8192, /* number */ 1024, /* writeThrough */ false))
+                        writeZerosAtFileOffset(
+                                sMicrodroid,
+                                destPath,
+                                /* offset */ 8192, /* number */
+                                1024, /* writeThrough */
+                                false))
                 .isSuccess();
     }
 
@@ -231,8 +246,12 @@
         // Action
         // Tampering with the first 4K-block of the backing file.
         assertThat(
-                writeZerosAtFileOffset(sAndroid, backendPath,
-                        /* offset */ 0, /* number */ 4096, /* writeThrough */ false))
+                        writeZerosAtFileOffset(
+                                sAndroid,
+                                backendPath,
+                                /* offset */ 0, /* number */
+                                4096, /* writeThrough */
+                                false))
                 .isSuccess();
 
         // Verify
@@ -258,8 +277,12 @@
         // Action
         // Tampering with the last 4K-block of the backing file.
         assertThat(
-                writeZerosAtFileOffset(sAndroid, backendPath,
-                        /* offset */ 4096, /* number */ 1, /* writeThrough */ false))
+                        writeZerosAtFileOffset(
+                                sAndroid,
+                                backendPath,
+                                /* offset */ 4096, /* number */
+                                1, /* writeThrough */
+                                false))
                 .isSuccess();
 
         // Verify
@@ -470,15 +493,22 @@
         sAndroid.run("test -f " + androidOutputPath);
 
         // Action
-        String output = sMicrodroid.run(
-                // Open the file for append and read
-                "exec 4>>" + outputPath + " 5<" + outputPath + "; "
-                // Delete the file from the directory
-                + "rm " + outputPath + "; "
-                // Append more data to the file descriptor
-                + "echo -n 456 >&4; "
-                // Print the whole file from the file descriptor
-                + "cat <&5");
+        String output =
+                sMicrodroid.run(
+                        // Open the file for append and read
+                        "exec 4>>"
+                                + outputPath
+                                + " 5<"
+                                + outputPath
+                                + "; "
+                                // Delete the file from the directory
+                                + "rm "
+                                + outputPath
+                                + "; "
+                                // Append more data to the file descriptor
+                                + "echo -n 456 >&4; "
+                                // Print the whole file from the file descriptor
+                                + "cat <&5");
 
         // Verify
         // Output contains all written data, while the files are deleted.
@@ -531,27 +561,33 @@
 
         // Verify
         String[] actual = sMicrodroid.run("cd " + authfsOutputDir + "; find |sort").split("\n");
-        String[] expected = new String[] {
-                ".",
-                "./dir",
-                "./dir/dir2",
-                "./dir/dir2/dir3",
-                "./dir/dir2/dir3/file1",
-                "./dir/dir2/dir3/file2",
-                "./dir/dir2/dir3/file3",
-                "./file"};
+        String[] expected =
+                new String[] {
+                    ".",
+                    "./dir",
+                    "./dir/dir2",
+                    "./dir/dir2/dir3",
+                    "./dir/dir2/dir3/file1",
+                    "./dir/dir2/dir3/file2",
+                    "./dir/dir2/dir3/file3",
+                    "./file"
+                };
         assertEquals(expected, actual);
 
         // Add more entries.
         sMicrodroid.run("mkdir -p " + authfsOutputDir + "/dir2");
         sMicrodroid.run("touch " + authfsOutputDir + "/file2");
         // Check new entries. Also check that the types are correct.
-        actual = sMicrodroid.run(
-                "cd " + authfsOutputDir + "; find -maxdepth 1 -type f |sort").split("\n");
+        actual =
+                sMicrodroid
+                        .run("cd " + authfsOutputDir + "; find -maxdepth 1 -type f |sort")
+                        .split("\n");
         expected = new String[] {"./file", "./file2"};
         assertEquals(expected, actual);
-        actual = sMicrodroid.run(
-                "cd " + authfsOutputDir + "; find -maxdepth 1 -type d |sort").split("\n");
+        actual =
+                sMicrodroid
+                        .run("cd " + authfsOutputDir + "; find -maxdepth 1 -type d |sort")
+                        .split("\n");
         expected = new String[] {".", "./dir", "./dir2"};
         assertEquals(expected, actual);
     }
@@ -687,8 +723,9 @@
                 "yes $'\\x01' | tr -d '\\n' | dd bs=1 count=" + numberOfOnes + " of=" + filePath);
     }
 
-    private static CommandResult checkReadAt(CommandRunner runner, String filePath, long offset,
-            long size) throws DeviceNotAvailableException {
+    private static CommandResult checkReadAt(
+            CommandRunner runner, String filePath, long offset, long size)
+            throws DeviceNotAvailableException {
         String cmd = "dd if=" + filePath + " of=/dev/null bs=1 count=" + size;
         if (offset > 0) {
             cmd += " skip=" + offset;
@@ -696,10 +733,15 @@
         return runner.runForResult(cmd);
     }
 
-    private CommandResult writeZerosAtFileOffset(CommandRunner runner, String filePath, long offset,
-            long numberOfZeros, boolean writeThrough) throws DeviceNotAvailableException {
-        String cmd = "dd if=/dev/zero of=" + filePath + " bs=1 count=" + numberOfZeros
-                + " conv=notrunc";
+    private CommandResult writeZerosAtFileOffset(
+            CommandRunner runner,
+            String filePath,
+            long offset,
+            long numberOfZeros,
+            boolean writeThrough)
+            throws DeviceNotAvailableException {
+        String cmd =
+                "dd if=/dev/zero of=" + filePath + " bs=1 count=" + numberOfZeros + " conv=notrunc";
         if (offset > 0) {
             cmd += " seek=" + offset;
         }
diff --git a/authfs/testdata/README.md b/tests/authfs/testdata/README.md
similarity index 100%
rename from authfs/testdata/README.md
rename to tests/authfs/testdata/README.md
diff --git a/authfs/testdata/cert.der b/tests/authfs/testdata/cert.der
similarity index 100%
rename from authfs/testdata/cert.der
rename to tests/authfs/testdata/cert.der
Binary files differ
diff --git a/authfs/testdata/cert.pem b/tests/authfs/testdata/cert.pem
similarity index 100%
rename from authfs/testdata/cert.pem
rename to tests/authfs/testdata/cert.pem
diff --git a/authfs/testdata/input.4k b/tests/authfs/testdata/input.4k
similarity index 100%
rename from authfs/testdata/input.4k
rename to tests/authfs/testdata/input.4k
Binary files differ
diff --git a/authfs/testdata/input.4k.fsv_meta b/tests/authfs/testdata/input.4k.fsv_meta
similarity index 100%
rename from authfs/testdata/input.4k.fsv_meta
rename to tests/authfs/testdata/input.4k.fsv_meta
Binary files differ
diff --git a/authfs/testdata/input.4k1 b/tests/authfs/testdata/input.4k1
similarity index 100%
rename from authfs/testdata/input.4k1
rename to tests/authfs/testdata/input.4k1
Binary files differ
diff --git a/authfs/testdata/input.4k1.fsv_meta b/tests/authfs/testdata/input.4k1.fsv_meta
similarity index 100%
rename from authfs/testdata/input.4k1.fsv_meta
rename to tests/authfs/testdata/input.4k1.fsv_meta
Binary files differ
diff --git a/authfs/testdata/input.4m b/tests/authfs/testdata/input.4m
similarity index 100%
rename from authfs/testdata/input.4m
rename to tests/authfs/testdata/input.4m
Binary files differ
diff --git a/authfs/testdata/input.4m.fsv_meta b/tests/authfs/testdata/input.4m.fsv_meta
similarity index 100%
rename from authfs/testdata/input.4m.fsv_meta
rename to tests/authfs/testdata/input.4m.fsv_meta
Binary files differ
diff --git a/authfs/testdata/input.4m.fsv_meta.bad_merkle b/tests/authfs/testdata/input.4m.fsv_meta.bad_merkle
similarity index 100%
rename from authfs/testdata/input.4m.fsv_meta.bad_merkle
rename to tests/authfs/testdata/input.4m.fsv_meta.bad_merkle
Binary files differ
diff --git a/authfs/testdata/key.pem b/tests/authfs/testdata/key.pem
similarity index 100%
rename from authfs/testdata/key.pem
rename to tests/authfs/testdata/key.pem
diff --git a/demo_accessor/README.md b/tests/vm_accessor/README.md
similarity index 92%
rename from demo_accessor/README.md
rename to tests/vm_accessor/README.md
index a3959a5..c85cf3c 100644
--- a/demo_accessor/README.md
+++ b/tests/vm_accessor/README.md
@@ -28,7 +28,7 @@
 ```shell
 adb remount -R || adb wait-for-device  # Remount to push apex to /system_ext
 adb root && adb remount                # Ensure it's rebooted.
-adb push $ANDROID_PRODUCT_OUT/system_ext/com.android.virt.accessor_demo.apex /system_ext/apex
+adb push $ANDROID_PRODUCT_OUT/system_ext/apex/com.android.virt.accessor_demo.apex /system_ext/apex
 adb reboot && adb wait-for-device      # Ensure that newly pushed apex at /system_ext is installed
 ```
 
diff --git a/demo_accessor/accessor/Android.bp b/tests/vm_accessor/accessor/Android.bp
similarity index 100%
rename from demo_accessor/accessor/Android.bp
rename to tests/vm_accessor/accessor/Android.bp
diff --git a/demo_accessor/accessor/src/accessor.rs b/tests/vm_accessor/accessor/src/accessor.rs
similarity index 100%
rename from demo_accessor/accessor/src/accessor.rs
rename to tests/vm_accessor/accessor/src/accessor.rs
diff --git a/demo_accessor/accessor/src/main.rs b/tests/vm_accessor/accessor/src/main.rs
similarity index 100%
rename from demo_accessor/accessor/src/main.rs
rename to tests/vm_accessor/accessor/src/main.rs
diff --git a/demo_accessor/accessor/src/run.rs b/tests/vm_accessor/accessor/src/run.rs
similarity index 100%
rename from demo_accessor/accessor/src/run.rs
rename to tests/vm_accessor/accessor/src/run.rs
diff --git a/demo_accessor/accessor_vm/Android.bp b/tests/vm_accessor/accessor_vm/Android.bp
similarity index 100%
rename from demo_accessor/accessor_vm/Android.bp
rename to tests/vm_accessor/accessor_vm/Android.bp
diff --git a/demo_accessor/accessor_vm/AndroidManifest.xml b/tests/vm_accessor/accessor_vm/AndroidManifest.xml
similarity index 100%
rename from demo_accessor/accessor_vm/AndroidManifest.xml
rename to tests/vm_accessor/accessor_vm/AndroidManifest.xml
diff --git a/demo_accessor/accessor_vm/assets/config.json b/tests/vm_accessor/accessor_vm/assets/config.json
similarity index 100%
rename from demo_accessor/accessor_vm/assets/config.json
rename to tests/vm_accessor/accessor_vm/assets/config.json
diff --git a/demo_accessor/accessor_vm/src/main.rs b/tests/vm_accessor/accessor_vm/src/main.rs
similarity index 100%
rename from demo_accessor/accessor_vm/src/main.rs
rename to tests/vm_accessor/accessor_vm/src/main.rs
diff --git a/demo_accessor/aidl/Android.bp b/tests/vm_accessor/aidl/Android.bp
similarity index 100%
rename from demo_accessor/aidl/Android.bp
rename to tests/vm_accessor/aidl/Android.bp
diff --git a/demo_accessor/aidl/com/android/virt/accessor_demo/vm_service/IAccessorVmService.aidl b/tests/vm_accessor/aidl/com/android/virt/accessor_demo/vm_service/IAccessorVmService.aidl
similarity index 100%
rename from demo_accessor/aidl/com/android/virt/accessor_demo/vm_service/IAccessorVmService.aidl
rename to tests/vm_accessor/aidl/com/android/virt/accessor_demo/vm_service/IAccessorVmService.aidl
diff --git a/demo_accessor/apex/Android.bp b/tests/vm_accessor/apex/Android.bp
similarity index 100%
rename from demo_accessor/apex/Android.bp
rename to tests/vm_accessor/apex/Android.bp
diff --git a/demo_accessor/apex/accessor_demo-file_contexts b/tests/vm_accessor/apex/accessor_demo-file_contexts
similarity index 100%
rename from demo_accessor/apex/accessor_demo-file_contexts
rename to tests/vm_accessor/apex/accessor_demo-file_contexts
diff --git a/demo_accessor/apex/accessor_demo.init.rc b/tests/vm_accessor/apex/accessor_demo.init.rc
similarity index 100%
rename from demo_accessor/apex/accessor_demo.init.rc
rename to tests/vm_accessor/apex/accessor_demo.init.rc
diff --git a/demo_accessor/apex/accessor_demo.xml b/tests/vm_accessor/apex/accessor_demo.xml
similarity index 100%
rename from demo_accessor/apex/accessor_demo.xml
rename to tests/vm_accessor/apex/accessor_demo.xml
diff --git a/demo_accessor/apex/manifest.json b/tests/vm_accessor/apex/manifest.json
similarity index 100%
rename from demo_accessor/apex/manifest.json
rename to tests/vm_accessor/apex/manifest.json
diff --git a/demo_accessor/test/Android.bp b/tests/vm_accessor/test/Android.bp
similarity index 100%
rename from demo_accessor/test/Android.bp
rename to tests/vm_accessor/test/Android.bp
diff --git a/demo_accessor/test/AndroidTest.xml b/tests/vm_accessor/test/AndroidTest.xml
similarity index 100%
rename from demo_accessor/test/AndroidTest.xml
rename to tests/vm_accessor/test/AndroidTest.xml
diff --git a/demo_accessor/test/src/test.rs b/tests/vm_accessor/test/src/test.rs
similarity index 100%
rename from demo_accessor/test/src/test.rs
rename to tests/vm_accessor/test/src/test.rs