Snap for 8730993 from 9436194c79a6d9681d3109de641476c7a0f0d971 to mainline-tzdata3-release

Change-Id: I25c43a0fdcc0bcca9a78bc7edd9559a14ea02810
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_not_pre_installed_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
index b2035c8..f87c6b9 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim_not_pre_installed.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v1_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v1_apex.asciipb
index e108ba3..03cf8a0 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v1_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v1_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v1.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_additional_file_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
index 9211e61..c93ee73 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_additional_file.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
index a5d0827..d5922e1 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_additional_folder.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apex.asciipb
index 9f834b3..18e12ee 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
index d684672..00f9f6c 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb
deleted file mode 100644
index 918ce0c..0000000
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb
+++ /dev/null
@@ -1,15 +0,0 @@
-drops {
-  android_build_drop {
-    build_id: "8572644"
-    target: "CtsShim"
-    source_file: "aosp_arm64/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex"
-  }
-  dest_file: "shim/prebuilts//arm/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex"
-  version: ""
-  version_group: ""
-  git_project: "platform/system/apex"
-  git_branch: "tm-dev"
-  transform: TRANSFORM_NONE
-  transform_options {
-  }
-}
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
index 275064d..861ffa3 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_different_certificate.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
index 3b24219..79de375 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_different_package_name.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
index 866da01..91f5ef2 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_no_hashtree.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_rebootless_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
index 2f99030..e8f2283 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_rebootless.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
index abaf998..e56d855 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_sdk_target_p.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
index 5bf4e32..ec3b1d6 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
index ff3a295..a8b55ab 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_signed_bob.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
index af3c9b3..23567d8 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_signed_bob_rot.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
index 45e3352..84c7328 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
index 078ac5a..ed4ca4b 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_unsigned_payload.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
index 0798f5f..5fb0fb2 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_with_post_install_hook.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
index 44a33be..38f20a0 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_with_pre_install_hook.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
index 19099b5..ac823c9 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_without_apk_in_apex.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
index 6db5911..0281ed4 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v2_wrong_sha.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_apex.asciipb
index d0c5a40..50c821d 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v3.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_rebootless_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
index 179ba8d..f900c46 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v3_rebootless.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
index 15d980c..d908d0e 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v3_signed_bob.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
index 01313db..cb1a634 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__arm_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_arm64/com.android.apex.cts.shim.v3_signed_bob_rot.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_not_pre_installed_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
index 1673a81..0d09fcb 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_not_pre_installed_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim_not_pre_installed.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v1_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v1_apex.asciipb
index 83580fe..742bca4 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v1_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v1_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v1.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_additional_file_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
index 5c23eea..783107c 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_additional_file_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_additional_file.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
index 36df5ad..5ab45ea 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_additional_folder_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_additional_folder.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apex.asciipb
index c2d9242..aee50ef 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
index 92dba07..9eb21ee 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apk_in_apex_sdk_target_p_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb
deleted file mode 100644
index a3228fb..0000000
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_apk_in_apex_upgrades_apex.asciipb
+++ /dev/null
@@ -1,15 +0,0 @@
-drops {
-  android_build_drop {
-    build_id: "8572644"
-    target: "CtsShim"
-    source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex"
-  }
-  dest_file: "shim/prebuilts//x86/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex"
-  version: ""
-  version_group: ""
-  git_project: "platform/system/apex"
-  git_branch: "tm-dev"
-  transform: TRANSFORM_NONE
-  transform_options {
-  }
-}
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
index 1534301..670489d 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_different_certificate_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_different_certificate.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
index b8e1de5..c5d28ff 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_different_package_name_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_different_package_name.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
index d9c58de..17ae6c5 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_no_hashtree_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_no_hashtree.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_rebootless_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
index 0c4bbda..c817a79 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_rebootless_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_rebootless.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
index 826a238..b121049 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_sdk_target_p_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_sdk_target_p.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
index 3199a49..39e49e1 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_sign_payload_with_different_key_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
index eb0acfa..2056dc1 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_signed_bob.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
index 19268fc..229b0f3 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_rot_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_signed_bob_rot.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
index c86aef6..fc464db 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_signed_bob_rot_rollback_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
index 1f0f41d..cffcd60 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_unsigned_payload_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_unsigned_payload.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
index def0f0d..c2168d8 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_with_post_install_hook_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_with_post_install_hook.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
index 2a1c96f..1f2469a 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_with_pre_install_hook_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_with_pre_install_hook.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
index ad5a295..986a459 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_without_apk_in_apex_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_without_apk_in_apex.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
index 21c2689..d53ab6c 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v2_wrong_sha_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v2_wrong_sha.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_apex.asciipb
index 84113df..ca8bade 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v3.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_rebootless_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
index cc3a401..e2c369f 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_rebootless_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v3_rebootless.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
index ab5a34e..ea06694 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_signed_bob_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v3_signed_bob.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
index 6d51168..3d41a84 100644
--- a/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
+++ b/.prebuilt_info/prebuilt_info_shim_prebuilts__x86_com_android_apex_cts_shim_v3_signed_bob_rot_apex.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "8572644"
+    build_id: "7552332"
     target: "CtsShim"
     source_file: "aosp_x86_64/com.android.apex.cts.shim.v3_signed_bob_rot.apex"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/system/apex"
-  git_branch: "tm-dev"
+  git_branch: "sc-dev"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/Android.bp b/Android.bp
index e17f64c..b198f25 100644
--- a/Android.bp
+++ b/Android.bp
@@ -28,6 +28,7 @@
     ],
 }
 
+// TODO(b/178585590): delete this after testing linking strategy
 soong_config_module_type {
     name: "library_linking_strategy_apex_defaults",
     module_type: "apex_defaults",
diff --git a/apexd/Android.bp b/apexd/Android.bp
index ce5d170..ba2de03 100644
--- a/apexd/Android.bp
+++ b/apexd/Android.bp
@@ -87,7 +87,6 @@
     "libavb",
     "libdm",
     "libext2_uuid",
-    "libsigningutils",
     "libverity_tree",
     "libvold_binder",
     "libxml2",
@@ -149,11 +148,11 @@
     "libapexd-deps",
   ],
   srcs: [
-    "apex_classpath.cpp",
     "apex_database.cpp",
     "apexd.cpp",
     "apexd_lifecycle.cpp",
     "apexd_loop.cpp",
+    "apexd_prepostinstall.cpp",
     "apexd_private.cpp",
     "apexd_session.cpp",
     "apexd_verity.cpp",
@@ -213,9 +212,7 @@
   static_libs: [
     "lib_apex_session_state_proto",
     "lib_apex_manifest_proto",
-    "lib_microdroid_metadata_proto",
     "libavb",
-    "libverity_tree",
   ],
   static: {
     whole_static_libs: ["libc++fs"],
@@ -237,7 +234,6 @@
     "apex_file_repository.cpp",
     "apex_manifest.cpp",
     "apex_shim.cpp",
-    "apexd_verity.cpp",
   ],
   host_supported: true,
   target: {
@@ -251,7 +247,6 @@
   export_header_lib_headers: [
     "libutils_headers",
   ],
-  export_include_dirs: ["."],
 }
 
 genrule {
@@ -341,17 +336,6 @@
 }
 
 genrule {
-  // Extract the root digest with avbtool
-  name: "apex.apexd_test_erofs_digest",
-  out: ["apex.apexd_test_erofs_digest.txt"],
-  srcs: [":apex.apexd_test_erofs"],
-  tools: ["avbtool"],
-  cmd: "unzip -q $(in) -d $(genDir) apex_payload.img && " +
-       "$(location avbtool) print_partition_digests --image $(genDir)/apex_payload.img " +
-       "| cut -c 3-| tee $(out)"
-}
-
-genrule {
   // Generates an apex which has same module name as apex.apexd_test.apex, but
   // is actually signed with a different key.
   name: "gen_key_mismatch_apex",
@@ -430,18 +414,18 @@
   ],
   data: [
     ":apex.apexd_test",
-    ":apex.apexd_test_erofs",
     ":apex.apexd_test_f2fs",
     ":apex.apexd_test_digest",
-    ":apex.apexd_test_erofs_digest",
     ":apex.apexd_test_f2fs_digest",
-    ":apex.apexd_test_classpath",
     ":apex.apexd_test_different_app",
     ":apex.apexd_test_no_hashtree",
     ":apex.apexd_test_no_hashtree_2",
     ":apex.apexd_test_no_inst_key",
     ":apex.apexd_test_f2fs_no_inst_key",
     ":apex.apexd_test_nocode",
+    ":apex.apexd_test_postinstall",
+    ":apex.apexd_test_preinstall",
+    ":apex.apexd_test_prepostinstall.fail",
     ":apex.apexd_test_v2",
     ":apex.corrupted_b146895998",
     ":apex.banned_name",
@@ -470,7 +454,6 @@
     ":com.android.apex.compressed.v1_original",
     ":com.android.apex.compressed.v2",
     ":com.android.apex.compressed.v2_original",
-    ":com.android.sepolicy",
     ":gen_manifest_mismatch_compressed_apex_v2",
     "apexd_testdata/com.android.apex.test_package.avbpubkey",
     "apexd_testdata/com.android.apex.compressed.avbpubkey",
@@ -491,7 +474,6 @@
     ":test.rebootless_apex_priv_app_in_apex",
   ],
   srcs: [
-    "apex_classpath_test.cpp",
     "apex_database_test.cpp",
     "apex_file_test.cpp",
     "apex_file_repository_test.cpp",
@@ -546,12 +528,3 @@
   api_dir: "apex-info-list-api",
   gen_writer: true,
 }
-
-xsd_config {
-  name: "apex-info-list-tinyxml",
-  srcs: ["ApexInfoList.xsd"],
-  package_name: "com.android.apex",
-  api_dir: "apex-info-list-api",
-  gen_writer: true,
-  tinyxml: true,
-}
diff --git a/apexd/AndroidTest.xml b/apexd/AndroidTest.xml
index bc2eae6..6f65f4e 100644
--- a/apexd/AndroidTest.xml
+++ b/apexd/AndroidTest.xml
@@ -33,6 +33,8 @@
       <option name="remount-system" value="true" />
       <option name="push" value="apex.apexd_test.apex->/system_ext/apex/apex.apexd_test.apex" />
       <option name="push" value="apex.apexd_test_different_app.apex->/system_ext/apex/apex.apexd_test_different_app.apex" />
+      <option name="push" value="apex.apexd_test_postinstall.apex->/system_ext/apex/apex.apexd_test_postinstall.apex" />
+      <option name="push" value="apex.apexd_test_preinstall.apex->/system_ext/apex/apex.apexd_test_preinstall.apex" />
     </target_preparer>
 
     <!-- system_server might still hold a reference to apexservice. This means that apexd is still
diff --git a/apexd/ApexInfoList.xsd b/apexd/ApexInfoList.xsd
index a327fc6..440b975 100644
--- a/apexd/ApexInfoList.xsd
+++ b/apexd/ApexInfoList.xsd
@@ -33,7 +33,6 @@
       <xs:attribute name="isFactory" type="xs:boolean" use="required"/>
       <xs:attribute name="isActive" type="xs:boolean" use="required"/>
       <xs:attribute name="lastUpdateMillis" type="xs:long"/>
-      <xs:attribute name="provideSharedApexLibs" type="xs:boolean" use="required"/>
     </xs:complexType>
   </xs:element>
 </xs:schema>
diff --git a/apexd/TEST_MAPPING b/apexd/TEST_MAPPING
index bcf6133..77ff9b8 100644
--- a/apexd/TEST_MAPPING
+++ b/apexd/TEST_MAPPING
@@ -2,9 +2,6 @@
   "presubmit": [
     {
       "name": "ApexTestCases"
-    },
-    {
-      "name": "MicrodroidHostTestCases"
     }
   ],
   "imports": [
diff --git a/apexd/aidl/android/apex/ApexInfo.aidl b/apexd/aidl/android/apex/ApexInfo.aidl
index fb590f2..9cc4d75 100644
--- a/apexd/aidl/android/apex/ApexInfo.aidl
+++ b/apexd/aidl/android/apex/ApexInfo.aidl
@@ -24,18 +24,4 @@
     @utf8InCpp String versionName;
     boolean isFactory;
     boolean isActive;
-
-    // Populated only for getStagedApex() API
-    boolean hasClassPathJars;
-
-    // Will be set to true if during this boot a different APEX package of the APEX was
-    // activated, than in the previous boot.
-    // This can happen in the following situations:
-    //  1. It was part of the staged session that was applied during this boot.
-    //  2. A compressed system APEX was decompressed during this boot.
-    //  3. apexd failed to activate an APEX on /data/apex/active (that was successfully
-    //    activated during last boot) and needed to fallback to pre-installed counterpart.
-    // Note: this field can only be set to true during boot, after boot is completed
-    //  (sys.boot_completed = 1) value of this field will always be false.
-    boolean activeApexChanged;
 }
diff --git a/apexd/aidl/android/apex/IApexService.aidl b/apexd/aidl/android/apex/IApexService.aidl
index d33970c..2d77a82 100644
--- a/apexd/aidl/android/apex/IApexService.aidl
+++ b/apexd/aidl/android/apex/IApexService.aidl
@@ -29,7 +29,6 @@
 
    ApexSessionInfo[] getSessions();
    ApexSessionInfo getStagedSessionInfo(int session_id);
-   ApexInfo[] getStagedApexInfos(in ApexSessionParams params);
    ApexInfo[] getActivePackages();
    ApexInfo[] getAllPackages();
 
@@ -76,6 +75,26 @@
     * Not meant for use outside of testing. The call will not be
     * functional on user builds.
     */
+   void activatePackage(in @utf8InCpp String package_path);
+   /**
+    * Not meant for use outside of testing. The call will not be
+    * functional on user builds.
+    */
+   void deactivatePackage(in @utf8InCpp String package_path);
+   /**
+    * Not meant for use outside of testing. The call will not be
+    * functional on user builds.
+    */
+   void preinstallPackages(in @utf8InCpp List<String> package_tmp_paths);
+   /**
+    * Not meant for use outside of testing. The call will not be
+    * functional on user builds.
+    */
+   void postinstallPackages(in @utf8InCpp List<String> package_tmp_paths);
+   /**
+    * Not meant for use outside of testing. The call will not be
+    * functional on user builds.
+    */
    void stagePackages(in @utf8InCpp List<String> package_tmp_paths);
    /**
     * Not meant for use outside of testing. The call will not be
diff --git a/apexd/apex-info-list-api/current.txt b/apexd/apex-info-list-api/current.txt
index 8e8615f..8db5a9a 100644
--- a/apexd/apex-info-list-api/current.txt
+++ b/apexd/apex-info-list-api/current.txt
@@ -9,7 +9,6 @@
     method public String getModuleName();
     method public String getModulePath();
     method public String getPreinstalledModulePath();
-    method public boolean getProvideSharedApexLibs();
     method public long getVersionCode();
     method public String getVersionName();
     method public void setIsActive(boolean);
@@ -18,7 +17,6 @@
     method public void setModuleName(String);
     method public void setModulePath(String);
     method public void setPreinstalledModulePath(String);
-    method public void setProvideSharedApexLibs(boolean);
     method public void setVersionCode(long);
     method public void setVersionName(String);
   }
diff --git a/apexd/apex_classpath.cpp b/apexd/apex_classpath.cpp
deleted file mode 100644
index 68b3fdb..0000000
--- a/apexd/apex_classpath.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include "apex_classpath.h"
-
-#include <android-base/file.h>
-#include <android-base/scopeguard.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <logwrap/logwrap.h>
-
-#include <fstream>
-#include <regex>
-
-namespace android {
-namespace apex {
-
-using ::android::base::Error;
-using ::android::base::StringPrintf;
-
-android::base::Result<ClassPath> ClassPath::DeriveClassPath(
-    const std::vector<std::string>& temp_mounted_apex_paths,
-    const std::string& sdkext_module_name) {
-  if (temp_mounted_apex_paths.empty()) {
-    return Error()
-           << "Invalid argument: There are no APEX to derive claspath from";
-  }
-  // Call derive_classpath binary to generate required information
-
-  // Prefer using the binary from staged session if possible
-  std::string apex_of_binary =
-      StringPrintf("/apex/%s", sdkext_module_name.c_str());
-  for (const auto& temp_mounted_apex_path : temp_mounted_apex_paths) {
-    if (temp_mounted_apex_path.starts_with(apex_of_binary + "@")) {
-      apex_of_binary = temp_mounted_apex_path;
-      break;
-    }
-  }
-  std::string binary_path =
-      StringPrintf("%s/bin/derive_classpath", apex_of_binary.c_str());
-  std::string scan_dirs_flag =
-      StringPrintf("--scan-dirs=%s",
-                   android::base::Join(temp_mounted_apex_paths, ",").c_str());
-
-  // Create a temp file to write output
-  auto temp_output_path = "/apex/derive_classpath_temp";
-  auto cleanup = [temp_output_path]() {
-    android::base::RemoveFileIfExists(temp_output_path);
-  };
-  auto scope_guard = android::base::make_scope_guard(cleanup);
-  // Cleanup to ensure we are creating an empty file
-  cleanup();
-  // Create the empty file where derive_classpath will write into
-  std::ofstream _(temp_output_path);
-
-  const char* const argv[] = {binary_path.c_str(), scan_dirs_flag.c_str(),
-                              temp_output_path};
-  auto rc = logwrap_fork_execvp(arraysize(argv), argv, nullptr, false, LOG_ALOG,
-                                false, nullptr);
-  if (rc != 0) {
-    return Error() << "Running derive_classpath failed; binary path: " +
-                          binary_path;
-  }
-
-  return ClassPath::ParseFromFile(temp_output_path);
-}
-
-// Parse the string output into structured information
-// The raw output from derive_classpath has the following format:
-// ```
-// export BOOTCLASSPATH path/to/jar1:/path/to/jar2
-// export DEX2OATBOOTCLASSPATH
-// export SYSTEMSERVERCLASSPATH path/to/some/jar
-android::base::Result<ClassPath> ClassPath::ParseFromFile(
-    const std::string& file_path) {
-  ClassPath result;
-
-  std::string contents;
-  auto read_status = android::base::ReadFileToString(file_path, &contents,
-                                                     /*follow_symlinks=*/false);
-  if (!read_status) {
-    return Error() << "Failed to read classpath info from file";
-  }
-
-  // Jars in apex have the following format: /apex/<package-name>/*
-  const std::regex capture_apex_package_name("^/apex/([^/]+)/");
-
-  for (const auto& line : android::base::Split(contents, "\n")) {
-    // Split the line by space. The second element determines which type of
-    // classpath we are dealing with and the third element are the jars
-    // separated by :
-    auto tokens = android::base::Split(line, " ");
-    if (tokens.size() < 3) {
-      continue;
-    }
-    auto jars_list = tokens[2];
-    for (const auto& jar_path : android::base::Split(jars_list, ":")) {
-      std::smatch match;
-      if (std::regex_search(jar_path, match, capture_apex_package_name)) {
-        auto package_name = match[1];
-        result.AddPackageWithClasspathJars(package_name);
-      }
-    }
-  }
-  return result;
-}
-
-void ClassPath::AddPackageWithClasspathJars(const std::string& package) {
-  packages_with_classpath_jars.insert(package);
-}
-
-bool ClassPath::HasClassPathJars(const std::string& package) {
-  return packages_with_classpath_jars.find(package) !=
-         packages_with_classpath_jars.end();
-}
-
-}  // namespace apex
-}  // namespace android
diff --git a/apexd/apex_classpath.h b/apexd/apex_classpath.h
deleted file mode 100644
index de3d07f..0000000
--- a/apexd/apex_classpath.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#ifndef ANDROID_APEXD_APEX_CLASSPATH_H_
-#define ANDROID_APEXD_APEX_CLASSPATH_H_
-
-#include <android-base/result.h>
-
-#include <set>
-#include <string>
-
-namespace android {
-namespace apex {
-
-/**
- * An utility class that contains logic to extract classpath fragments
- * information from mounted APEX.
- *
- * The bulk of the work is done by derive_classpath binary, which is found
- * inside sdkext module. This class is a wrapper for calling that binary and
- * parsing its string output into a structured object.
- */
-class ClassPath {
-  static constexpr const char* kSdkExtModuleName = "com.android.sdkext";
-
- public:
-  static android::base::Result<ClassPath> DeriveClassPath(
-      const std::vector<std::string>& temp_mounted_apex_paths,
-      const std::string& sdkext_module_name = kSdkExtModuleName);
-
-  bool HasClassPathJars(const std::string& package);
-
-  // Exposed for testing only
-  static android::base::Result<ClassPath> ParseFromFile(
-      const std::string& file_path);
-
- private:
-  void AddPackageWithClasspathJars(const std::string& package);
-
-  std::set<std::string> packages_with_classpath_jars;
-};
-
-}  // namespace apex
-}  // namespace android
-
-#endif  // ANDROID_APEXD_APEXD_CHECKPOINT_H_
diff --git a/apexd/apex_classpath_test.cpp b/apexd/apex_classpath_test.cpp
deleted file mode 100644
index efa4f3f..0000000
--- a/apexd/apex_classpath_test.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include "apex_classpath.h"
-
-#include <android-base/file.h>
-#include <android-base/result-gmock.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <fstream>
-#include <string>
-
-namespace android {
-namespace apex {
-
-using android::base::WriteStringToFile;
-using android::base::testing::Ok;
-using android::base::testing::WithMessage;
-using ::testing::HasSubstr;
-
-TEST(ApexClassPathUnitTest, ParseFromFile) {
-  TemporaryFile output;
-  WriteStringToFile(
-      "export BOOTCLASSPATH /apex/a/jar1:/apex/b/jar2\n"
-      "export SYSTEMSERVERCLASSPATH\n"
-      "export UNEXPECTED /apex/c/\n",
-      output.path);
-  auto result = ClassPath::ParseFromFile(output.path);
-  ASSERT_THAT(result, Ok());
-
-  ASSERT_THAT(result->HasClassPathJars("a"), true);
-  ASSERT_THAT(result->HasClassPathJars("b"), true);
-  ASSERT_THAT(result->HasClassPathJars("c"), true);
-  ASSERT_THAT(result->HasClassPathJars("d"), false);
-}
-
-TEST(ApexClassPathUnitTest, ParseFromFileJarsNotInApex) {
-  TemporaryFile output;
-  // We accept jars with regex: /apex/<package-name>/*
-  WriteStringToFile("export BOOTCLASSPATH a:b\n", output.path);
-  auto result = ClassPath::ParseFromFile(output.path);
-  ASSERT_THAT(result, Ok());
-
-  ASSERT_THAT(result->HasClassPathJars("a"), false);
-  ASSERT_THAT(result->HasClassPathJars("b"), false);
-}
-
-TEST(ApexClassPathUnitTest, ParseFromFilePackagesWithSamePrefix) {
-  TemporaryFile output;
-  WriteStringToFile(
-      "export BOOTCLASSPATH /apex/media/:/apex/mediaprovider\n"
-      "export SYSTEMSERVERCLASSPATH /apex/mediafoo/\n",
-      output.path);
-  auto result = ClassPath::ParseFromFile(output.path);
-  ASSERT_THAT(result, Ok());
-
-  ASSERT_THAT(result->HasClassPathJars("media"), true);
-  // "/apex/mediaprovider" did not end with /
-  ASSERT_THAT(result->HasClassPathJars("mediaprovider"), false);
-  // A prefix of an apex name present should not be accepted
-  ASSERT_THAT(result->HasClassPathJars("m"), false);
-}
-
-TEST(ApexClassPathUnitTest, ParseFromFileDoesNotExist) {
-  auto result = ClassPath::ParseFromFile("/file/does/not/exist");
-  ASSERT_THAT(result, HasError(WithMessage(HasSubstr(
-                          "Failed to read classpath info from file"))));
-}
-
-TEST(ApexClassPathUnitTest, ParseFromFileEmptyJars) {
-  TemporaryFile output;
-  WriteStringToFile(
-      "export BOOTCLASSPATH\n"
-      "export SYSTEMSERVERCLASSPATH \n"
-      "export DEX2OATBOOTCLASSPATH \n",
-      output.path);
-  auto result = ClassPath::ParseFromFile(output.path);
-  ASSERT_THAT(result, Ok());
-}
-
-TEST(ApexClassPathUnitTest, DeriveClassPathNoStagedApex) {
-  auto result = ClassPath::DeriveClassPath({});
-  ASSERT_THAT(
-      result,
-      HasError(WithMessage(HasSubstr(
-          "Invalid argument: There are no APEX to derive claspath from"))));
-}
-
-TEST(ApexClassPathUnitTest, DeriveClassPathPreferBinaryInStagedApex) {
-  // Default location uses provided package name to compose binary path
-  auto result = ClassPath::DeriveClassPath({"/apex/temp@123"}, "different");
-  ASSERT_THAT(result,
-              HasError(WithMessage(HasSubstr(
-                  "binary path: /apex/different/bin/derive_classpath"))));
-
-  // When staged apex has same package name, we use that location instead
-  result = ClassPath::DeriveClassPath({"/apex/temp@123"}, "temp");
-  ASSERT_THAT(result,
-              HasError(WithMessage(HasSubstr(
-                  "binary path: /apex/temp@123/bin/derive_classpath"))));
-}
-
-}  // namespace apex
-}  // namespace android
diff --git a/apexd/apex_constants.h b/apexd/apex_constants.h
index edb51c3..798afd5 100644
--- a/apexd/apex_constants.h
+++ b/apexd/apex_constants.h
@@ -66,17 +66,6 @@
 static constexpr const char* kApexStatusStarting = "starting";
 static constexpr const char* kApexStatusActivated = "activated";
 static constexpr const char* kApexStatusReady = "ready";
-static constexpr const char* kMultiApexSelectPersistPrefix =
-    "persist.vendor.apex.";
-static constexpr const char* kMultiApexSelectBootconfigPrefix =
-    "ro.boot.vendor.apex.";
-
-static constexpr const char* kVmPayloadMetadataPartitionProp =
-    "apexd.payload_metadata.path";
-static constexpr const std::chrono::seconds kBlockApexWaitTime(10);
-
-static constexpr const char* kMetadataSepolicyStagedDir =
-    "/metadata/sepolicy/staged";
 
 // Banned APEX names
 static const std::unordered_set<std::string> kBannedApexName = {
diff --git a/apexd/apex_file.cpp b/apexd/apex_file.cpp
index 9ed48aa..c043def 100644
--- a/apexd/apex_file.cpp
+++ b/apexd/apex_file.cpp
@@ -16,25 +16,25 @@
 
 #include "apex_file.h"
 
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/scopeguard.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
 #include <fcntl.h>
-#include <libavb/libavb.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <ziparchive/zip_archive.h>
 
 #include <filesystem>
 #include <fstream>
 #include <span>
 
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/scopeguard.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
+#include <libavb/libavb.h>
+#include <ziparchive/zip_archive.h>
+
 #include "apex_constants.h"
 #include "apexd_utils.h"
-#include "apexd_verity.h"
 
 using android::base::borrowed_fd;
 using android::base::ErrnoError;
@@ -60,10 +60,9 @@
   const char* magic;
 };
 constexpr const FsMagic kFsType[] = {{"f2fs", 1024, 4, "\x10\x20\xf5\xf2"},
-                                     {"ext4", 1024 + 0x38, 2, "\123\357"},
-                                     {"erofs", 1024, 4, "\xe2\xe1\xf5\xe0"}};
+                                     {"ext4", 1024 + 0x38, 2, "\123\357"}};
 
-Result<std::string> RetrieveFsType(borrowed_fd fd, uint32_t image_offset) {
+Result<std::string> RetrieveFsType(borrowed_fd fd, int32_t image_offset) {
   for (const auto& fs : kFsType) {
     char buf[fs.len];
     if (!ReadFullyAtOffset(fd, buf, fs.len, image_offset + fs.offset)) {
@@ -79,7 +78,7 @@
 }  // namespace
 
 Result<ApexFile> ApexFile::Open(const std::string& path) {
-  std::optional<uint32_t> image_offset;
+  std::optional<int32_t> image_offset;
   std::optional<size_t> image_size;
   std::string manifest_content;
   std::string pubkey;
@@ -88,15 +87,14 @@
 
   unique_fd fd(open(path.c_str(), O_RDONLY | O_BINARY | O_CLOEXEC));
   if (fd < 0) {
-    return ErrnoError() << "Failed to open package " << path << ": "
-                        << "I/O error";
+    return Error() << "Failed to open package " << path << ": "
+                   << "I/O error";
   }
 
   ZipArchiveHandle handle;
   auto handle_guard =
       android::base::make_scope_guard([&handle] { CloseArchive(handle); });
-  int ret = OpenArchiveFd(fd.get(), path.c_str(), &handle,
-                          /*assume_ownership=*/false);
+  int ret = OpenArchiveFd(fd.get(), path.c_str(), &handle, false);
   if (ret < 0) {
     return Error() << "Failed to open package " << path << ": "
                    << ErrorCodeString(ret);
@@ -183,6 +181,16 @@
 
 static constexpr int kVbMetaMaxSize = 64 * 1024;
 
+std::string BytesToHex(const uint8_t* bytes, size_t bytes_len) {
+  std::ostringstream s;
+
+  s << std::hex << std::setfill('0');
+  for (size_t i = 0; i < bytes_len; i++) {
+    s << std::setw(2) << static_cast<int>(bytes[i]);
+  }
+  return s.str();
+}
+
 std::string GetSalt(const AvbHashtreeDescriptor& desc,
                     const uint8_t* trailing_data) {
   const uint8_t* desc_salt = trailing_data + desc.partition_name_len;
diff --git a/apexd/apex_file.h b/apexd/apex_file.h
index 56077bb..60d5feb 100644
--- a/apexd/apex_file.h
+++ b/apexd/apex_file.h
@@ -42,15 +42,12 @@
 class ApexFile {
  public:
   static android::base::Result<ApexFile> Open(const std::string& path);
-
   ApexFile() = delete;
   ApexFile(ApexFile&&) = default;
   ApexFile& operator=(ApexFile&&) = default;
 
   const std::string& GetPath() const { return apex_path_; }
-  const std::optional<uint32_t>& GetImageOffset() const {
-    return image_offset_;
-  }
+  const std::optional<int32_t>& GetImageOffset() const { return image_offset_; }
   const std::optional<size_t>& GetImageSize() const { return image_size_; }
   const ::apex::proto::ApexManifest& GetManifest() const { return manifest_; }
   const std::string& GetBundledPublicKey() const { return apex_pubkey_; }
@@ -62,7 +59,7 @@
 
  private:
   ApexFile(const std::string& apex_path,
-           const std::optional<uint32_t>& image_offset,
+           const std::optional<int32_t>& image_offset,
            const std::optional<size_t>& image_size,
            ::apex::proto::ApexManifest manifest, const std::string& apex_pubkey,
            const std::optional<std::string>& fs_type, bool is_compressed)
@@ -75,7 +72,7 @@
         is_compressed_(is_compressed) {}
 
   std::string apex_path_;
-  std::optional<uint32_t> image_offset_;
+  std::optional<int32_t> image_offset_;
   std::optional<size_t> image_size_;
   ::apex::proto::ApexManifest manifest_;
   std::string apex_pubkey_;
diff --git a/apexd/apex_file_repository.cpp b/apexd/apex_file_repository.cpp
index e82feb4..c50d136 100644
--- a/apexd/apex_file_repository.cpp
+++ b/apexd/apex_file_repository.cpp
@@ -18,19 +18,17 @@
 
 #include "apex_file_repository.h"
 
+#include <unordered_map>
+
 #include <android-base/file.h>
 #include <android-base/properties.h>
 #include <android-base/result.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
-#include <microdroid/metadata.h>
-
-#include <unordered_map>
 
 #include "apex_constants.h"
 #include "apex_file.h"
 #include "apexd_utils.h"
-#include "apexd_verity.h"
 
 using android::base::EndsWith;
 using android::base::Error;
@@ -40,24 +38,6 @@
 namespace android {
 namespace apex {
 
-std::string ConsumeApexPackageSuffix(const std::string& path) {
-  std::string_view path_view(path);
-  android::base::ConsumeSuffix(&path_view, kApexPackageSuffix);
-  android::base::ConsumeSuffix(&path_view, kCompressedApexPackageSuffix);
-  return std::string(path_view);
-}
-
-std::string GetApexSelectFilenameFromProp(
-    const std::vector<std::string>& prefixes, const std::string& apex_name) {
-  for (const std::string& prefix : prefixes) {
-    const std::string& filename = GetProperty(prefix + apex_name, "");
-    if (filename != "") {
-      return ConsumeApexPackageSuffix(filename);
-    }
-  }
-  return "";
-}
-
 Result<void> ApexFileRepository::ScanBuiltInDir(const std::string& dir) {
   LOG(INFO) << "Scanning " << dir << " for pre-installed ApexFiles";
   if (access(dir.c_str(), F_OK) != 0 && errno == ENOENT) {
@@ -80,59 +60,6 @@
     }
 
     const std::string& name = apex_file->GetManifest().name();
-
-    // Check if this APEX name is treated as a multi-install APEX.
-    //
-    // Note: apexd is a oneshot service which runs at boot, but can be restarted
-    // when needed (such as staging an APEX update). If a multi-install select
-    // property changes between boot and when apexd restarts, the LOG messages
-    // below will report the version that will be activated on next reboot,
-    // which may differ from the currently-active version.
-    std::string select_filename = GetApexSelectFilenameFromProp(
-        multi_install_select_prop_prefixes_, name);
-    if (!select_filename.empty()) {
-      std::string path;
-      if (!android::base::Realpath(apex_file->GetPath(), &path)) {
-        LOG(ERROR) << "Unable to resolve realpath of APEX with path "
-                   << apex_file->GetPath();
-        continue;
-      }
-      if (enforce_multi_install_partition_ &&
-          !android::base::StartsWith(path, "/vendor/apex/")) {
-        LOG(ERROR) << "Multi-install APEX " << path
-                   << " can only be preinstalled on /vendor/apex/.";
-        continue;
-      }
-
-      auto& keys = multi_install_public_keys_[name];
-      keys.insert(apex_file->GetBundledPublicKey());
-      if (keys.size() > 1) {
-        LOG(ERROR) << "Multi-install APEXes for " << name
-                   << " have different public keys.";
-        // If any versions of a multi-installed APEX differ in public key,
-        // then no version should be installed.
-        if (auto it = pre_installed_store_.find(name);
-            it != pre_installed_store_.end()) {
-          pre_installed_store_.erase(it);
-        }
-        continue;
-      }
-
-      if (ConsumeApexPackageSuffix(android::base::Basename(path)) ==
-          select_filename) {
-        LOG(INFO) << "Found APEX at path " << path << " for multi-install APEX "
-                  << name;
-        // Add the APEX file to the store if its filename matches the property.
-        pre_installed_store_.emplace(name, std::move(*apex_file));
-      } else {
-        LOG(INFO) << "Skipping APEX at path " << path
-                  << " because it does not match expected multi-install"
-                  << " APEX property for " << name;
-      }
-
-      continue;
-    }
-
     auto it = pre_installed_store_.find(name);
     if (it == pre_installed_store_.end()) {
       pre_installed_store_.emplace(name, std::move(*apex_file));
@@ -157,7 +84,6 @@
                  << " (" << name << ") has unexpectedly changed";
     }
   }
-  multi_install_public_keys_.clear();
   return {};
 }
 
@@ -176,130 +102,6 @@
   return {};
 }
 
-Result<int> ApexFileRepository::AddBlockApex(
-    const std::string& metadata_partition) {
-  CHECK(!block_disk_path_.has_value())
-      << "AddBlockApex() can't be called twice.";
-
-  auto metadata_ready = WaitForFile(metadata_partition, kBlockApexWaitTime);
-  if (!metadata_ready.ok()) {
-    LOG(ERROR) << "Error waiting for metadata_partition : "
-               << metadata_ready.error();
-    return {};
-  }
-
-  // TODO(b/185069443) consider moving the logic to find disk_path from
-  // metadata_partition to its own library
-  LOG(INFO) << "Scanning " << metadata_partition << " for host apexes";
-  if (access(metadata_partition.c_str(), F_OK) != 0 && errno == ENOENT) {
-    LOG(WARNING) << metadata_partition << " does not exist. Skipping";
-    return {};
-  }
-
-  std::string metadata_realpath;
-  if (!android::base::Realpath(metadata_partition, &metadata_realpath)) {
-    LOG(WARNING) << "Can't get realpath of " << metadata_partition
-                 << ". Skipping";
-    return {};
-  }
-
-  std::string_view metadata_path_view(metadata_realpath);
-  if (!android::base::ConsumeSuffix(&metadata_path_view, "1")) {
-    LOG(WARNING) << metadata_realpath << " is not a first partition. Skipping";
-    return {};
-  }
-
-  block_disk_path_ = std::string(metadata_path_view);
-
-  // Read the payload metadata.
-  // "metadata" can be overridden by microdroid_manager. To ensure that
-  // "microdroid" is started with the same/unmodified set of host APEXes,
-  // microdroid stores APEXes' pubkeys in its encrypted instance disk. Next
-  // time, microdroid checks if there's pubkeys in the instance disk and use
-  // them to activate APEXes. Microdroid_manager passes pubkeys in instance.img
-  // via the following file.
-  if (auto exists = PathExists("/apex/vm-payload-metadata");
-      exists.ok() && *exists) {
-    metadata_realpath = "/apex/vm-payload-metadata";
-    LOG(INFO) << "Overriding metadata to " << metadata_realpath;
-  }
-  auto metadata = android::microdroid::ReadMetadata(metadata_realpath);
-  if (!metadata.ok()) {
-    LOG(WARNING) << "Failed to load metadata from " << metadata_realpath
-                 << ". Skipping: " << metadata.error();
-    return {};
-  }
-
-  int ret = 0;
-
-  // subsequent partitions are APEX archives.
-  static constexpr const int kFirstApexPartition = 2;
-  for (int i = 0; i < metadata->apexes_size(); i++) {
-    const auto& apex_config = metadata->apexes(i);
-
-    const std::string apex_path =
-        *block_disk_path_ + std::to_string(i + kFirstApexPartition);
-
-    auto apex_ready = WaitForFile(apex_path, kBlockApexWaitTime);
-    if (!apex_ready.ok()) {
-      return Error() << "Error waiting for apex file : " << apex_ready.error();
-    }
-
-    auto apex_file = ApexFile::Open(apex_path);
-    if (!apex_file.ok()) {
-      return Error() << "Failed to open " << apex_path << " : "
-                     << apex_file.error();
-    }
-
-    // When metadata specifies the public key of the apex, it should match the
-    // bundled key. Otherwise we accept it.
-    if (apex_config.public_key() != "" &&
-        apex_config.public_key() != apex_file->GetBundledPublicKey()) {
-      return Error() << "public key doesn't match: " << apex_path;
-    }
-
-    const std::string& name = apex_file->GetManifest().name();
-
-    BlockApexOverride overrides;
-
-    // A block device doesn't have an inherent timestamp, so it is carried in
-    // the metadata.
-    if (int64_t last_update_seconds = apex_config.last_update_seconds();
-        last_update_seconds != 0) {
-      overrides.last_update_seconds = last_update_seconds;
-    }
-
-    // When metadata specifies the root digest of the apex, it should be used
-    // when activating the apex. So we need to keep it.
-    if (auto root_digest = apex_config.root_digest(); root_digest != "") {
-      overrides.block_apex_root_digest =
-          BytesToHex(reinterpret_cast<const uint8_t*>(root_digest.data()),
-                     root_digest.size());
-    }
-
-    if (overrides.last_update_seconds.has_value() ||
-        overrides.block_apex_root_digest.has_value()) {
-      block_apex_overrides_.emplace(name, std::move(overrides));
-    }
-
-    // APEX should be unique.
-    for (const auto* store : {&pre_installed_store_, &data_store_}) {
-      auto it = store->find(name);
-      if (it != store->end()) {
-        return Error() << "duplicate of " << name << " found in "
-                       << it->second.GetPath();
-      }
-    }
-    // Depending on whether the APEX was a factory version in the host or not,
-    // put it to different stores.
-    auto& store = apex_config.is_factory() ? pre_installed_store_ : data_store_;
-    store.emplace(name, std::move(*apex_file));
-
-    ret++;
-  }
-  return {ret};
-}
-
 // TODO(b/179497746): AddDataApex should not concern with filtering out invalid
 //   apex.
 Result<void> ApexFileRepository::AddDataApex(const std::string& data_dir) {
@@ -326,19 +128,10 @@
 
     const std::string& name = apex_file->GetManifest().name();
     if (!HasPreInstalledVersion(name)) {
-      LOG(ERROR) << "Skipping " << file << " : no preinstalled apex";
+      LOG(ERROR) << "Skipping " << file << " : no preisntalled apex";
       // Ignore data apex without corresponding pre-installed apex
       continue;
     }
-
-    std::string select_filename = GetApexSelectFilenameFromProp(
-        multi_install_select_prop_prefixes_, name);
-    if (!select_filename.empty()) {
-      LOG(WARNING) << "APEX " << name << " is a multi-installed APEX."
-                   << " Any updated version in /data will always overwrite"
-                   << " the multi-installed preinstalled version, if possible.";
-    }
-
     auto pre_installed_public_key = GetPublicKey(name);
     if (!pre_installed_public_key.ok() ||
         apex_file->GetBundledPublicKey() != *pre_installed_public_key) {
@@ -379,14 +172,6 @@
     const std::string& name) const {
   auto it = pre_installed_store_.find(name);
   if (it == pre_installed_store_.end()) {
-    // Special casing for APEXes backed by block devices, i.e. APEXes in VM.
-    // Inside a VM, we fall back to find the key from data_store_. This is
-    // because an APEX is put to either pre_installed_store_ or data_store,
-    // depending on whether it was a factory APEX or not in the host.
-    it = data_store_.find(name);
-    if (it != data_store_.end() && IsBlockApex(it->second)) {
-      return it->second.GetBundledPublicKey();
-    }
     return Error() << "No preinstalled apex found for package " << name;
   }
   return it->second.GetBundledPublicKey();
@@ -414,24 +199,6 @@
   return it->second.GetPath();
 }
 
-std::optional<std::string> ApexFileRepository::GetBlockApexRootDigest(
-    const std::string& name) const {
-  auto it = block_apex_overrides_.find(name);
-  if (it == block_apex_overrides_.end()) {
-    return std::nullopt;
-  }
-  return it->second.block_apex_root_digest;
-}
-
-std::optional<int64_t> ApexFileRepository::GetBlockApexLastUpdateSeconds(
-    const std::string& name) const {
-  auto it = block_apex_overrides_.find(name);
-  if (it == block_apex_overrides_.end()) {
-    return std::nullopt;
-  }
-  return it->second.last_update_seconds;
-}
-
 bool ApexFileRepository::HasPreInstalledVersion(const std::string& name) const {
   return pre_installed_store_.find(name) != pre_installed_store_.end();
 }
@@ -454,11 +221,6 @@
   return it->second.GetPath() == apex.GetPath() || IsDecompressedApex(apex);
 }
 
-bool ApexFileRepository::IsBlockApex(const ApexFile& apex) const {
-  return block_disk_path_.has_value() &&
-         apex.GetPath().starts_with(*block_disk_path_);
-}
-
 std::vector<ApexFileRef> ApexFileRepository::GetPreInstalledApexFiles() const {
   std::vector<ApexFileRef> result;
   for (const auto& it : pre_installed_store_) {
diff --git a/apexd/apex_file_repository.h b/apexd/apex_file_repository.h
index 1a1cf94..e9ccf7e 100644
--- a/apexd/apex_file_repository.h
+++ b/apexd/apex_file_repository.h
@@ -16,18 +16,15 @@
 
 #pragma once
 
-#include <android-base/result.h>
-
 #include <functional>
-#include <optional>
 #include <string>
 #include <unordered_map>
-#include <unordered_set>
 #include <vector>
-
 #include "apex_constants.h"
 #include "apex_file.h"
 
+#include <android-base/result.h>
+
 namespace android {
 namespace apex {
 
@@ -42,15 +39,10 @@
 // mounts apexes (e.g. apexd, otapreopt_chroot).
 class ApexFileRepository final {
  public:
-  // c-tors and d-tor are exposed for testing.
+  // c-tor and d-tor are exposed for testing.
   explicit ApexFileRepository(
       const std::string& decompression_dir = kApexDecompressedDir)
       : decompression_dir_(decompression_dir){};
-  explicit ApexFileRepository(
-      bool enforce_multi_install_partition,
-      const std::vector<std::string>& multi_install_select_prop_prefixes)
-      : multi_install_select_prop_prefixes_(multi_install_select_prop_prefixes),
-        enforce_multi_install_partition_(enforce_multi_install_partition){};
 
   ~ApexFileRepository() {
     pre_installed_store_.clear();
@@ -68,24 +60,6 @@
   android::base::Result<void> AddPreInstalledApex(
       const std::vector<std::string>& prebuilt_dirs);
 
-  // Populate instance by collecting host-provided apex files via
-  // |metadata_partition|. Host can provide its apexes to a VM instance via the
-  // virtual disk image which has partitions: (see
-  // /packages/modules/Virtualization/microdroid for the details)
-  //  - metadata partition(/dev/block/vd*1) should be accessed by
-  //  setting the system property apexd.payload_metadata.prop. On microdroid,
-  //  this is /dev/block/by-name/payload-metadata.
-  //  - each subsequence partition(/dev/block/vd*{2,3,..}) represents an APEX
-  //  archive.
-  // It will fail if there is more than one apex with the same name in
-  // pre-installed and block apexes. Note: this call is **not thread safe** and
-  // is expected to be performed in a single thread during initialization of
-  // apexd. After initialization is finished, all queries to the instance are
-  // thread safe.
-  // This will return the number of block apexes that were added.
-  android::base::Result<int> AddBlockApex(
-      const std::string& metadata_partition);
-
   // Populate instance by collecting data apex files from the given |data_dir|.
   // Note: this call is **not thread safe** and is expected to be performed in a
   // single thread during initialization of apexd. After initialization is
@@ -104,14 +78,6 @@
   android::base::Result<const std::string> GetDataPath(
       const std::string& name) const;
 
-  // Returns root digest of an apex with the given |name| for block apexes.
-  std::optional<std::string> GetBlockApexRootDigest(
-      const std::string& name) const;
-
-  // Returns timestamp to be used for the block apex of the given |name|.
-  std::optional<int64_t> GetBlockApexLastUpdateSeconds(
-      const std::string& name) const;
-
   // Checks whether there is a pre-installed version of an apex with the given
   // |name|.
   bool HasPreInstalledVersion(const std::string& name) const;
@@ -125,9 +91,6 @@
   // Checks if given |apex| is decompressed from a pre-installed APEX
   bool IsDecompressedApex(const ApexFile& apex) const;
 
-  // Checks if given |apex| is loaded from block device.
-  bool IsBlockApex(const ApexFile& apex) const;
-
   // Returns reference to all pre-installed APEX on device
   std::vector<ApexFileRef> GetPreInstalledApexFiles() const;
 
@@ -152,9 +115,7 @@
   void Reset(const std::string& decompression_dir = kApexDecompressedDir) {
     pre_installed_store_.clear();
     data_store_.clear();
-    block_apex_overrides_.clear();
     decompression_dir_ = decompression_dir;
-    block_disk_path_.reset();
   }
 
  private:
@@ -169,41 +130,9 @@
   android::base::Result<void> ScanBuiltInDir(const std::string& dir);
 
   std::unordered_map<std::string, ApexFile> pre_installed_store_, data_store_;
-
-  // Multi-installed APEX name -> all encountered public keys for this APEX.
-  std::unordered_map<std::string, std::unordered_set<std::string>>
-      multi_install_public_keys_;
-
-  // Prefixes used when looking for multi-installed APEX sysprops.
-  // Order matters: the first non-empty prop value is returned.
-  std::vector<std::string> multi_install_select_prop_prefixes_ = {
-      // Check persist props first, to allow users to override bootconfig.
-      kMultiApexSelectPersistPrefix,
-      kMultiApexSelectBootconfigPrefix,
-  };
-
-  // Allows multi-install APEXes outside of expected partitions.
-  // Only set false in tests.
-  bool enforce_multi_install_partition_ = true;
-
   // Decompression directory which will be used to determine if apex is
   // decompressed or not
   std::string decompression_dir_;
-
-  // Disk path where block apexes are read from. AddBlockApex() sets this.
-  std::optional<std::string> block_disk_path_;
-
-  // Information from the metadata for block apexes, overriding the file data.
-  struct BlockApexOverride {
-    // Root digest for the APEX. When specified in block apex config, it
-    // should be used/checked when activating the apex to avoid
-    // TOCTOU(time-of-check to time-of-use).
-    std::optional<std::string> block_apex_root_digest;
-    // The last update time of the APEX.
-    std::optional<int64_t> last_update_seconds;
-  };
-
-  std::unordered_map<std::string, BlockApexOverride> block_apex_overrides_;
 };
 
 }  // namespace apex
diff --git a/apexd/apex_file_repository_test.cpp b/apexd/apex_file_repository_test.cpp
index bf73092..c1f5d53 100644
--- a/apexd/apex_file_repository_test.cpp
+++ b/apexd/apex_file_repository_test.cpp
@@ -14,22 +14,20 @@
  * limitations under the License.
  */
 
-#include "apex_file_repository.h"
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <errno.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <microdroid/metadata.h>
-#include <sys/stat.h>
-
 #include <filesystem>
 #include <string>
 
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include "apex_file.h"
+#include "apex_file_repository.h"
 #include "apexd_test_utils.h"
 #include "apexd_verity.h"
 
@@ -162,90 +160,6 @@
       "");
 }
 
-TEST(ApexFileRepositoryTest, InitializeMultiInstalledSuccess) {
-  // Prepare test data.
-  TemporaryDir td;
-  std::string apex_file = GetTestFile("apex.apexd_test.apex");
-  fs::copy(apex_file, StringPrintf("%s/version_a.apex", td.path));
-  fs::copy(apex_file, StringPrintf("%s/version_b.apex", td.path));
-  std::string apex_name = ApexFile::Open(apex_file)->GetManifest().name();
-
-  std::string persist_prefix = "debug.apexd.test.persistprefix.";
-  std::string bootconfig_prefix = "debug.apexd.test.bootconfigprefix.";
-  ApexFileRepository instance(/*enforce_multi_install_partition=*/false,
-                              /*multi_install_select_prop_prefixes=*/{
-                                  persist_prefix, bootconfig_prefix});
-
-  auto test_fn = [&](const std::string& selected_filename) {
-    ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({td.path})));
-    auto ret = instance.GetPreinstalledPath(apex_name);
-    ASSERT_TRUE(IsOk(ret));
-    ASSERT_EQ(StringPrintf("%s/%s", td.path, selected_filename.c_str()), *ret);
-    instance.Reset();
-  };
-
-  // Start with version_a in bootconfig.
-  android::base::SetProperty(bootconfig_prefix + apex_name, "version_a.apex");
-  test_fn("version_a.apex");
-  // Developer chooses version_b with persist prop.
-  android::base::SetProperty(persist_prefix + apex_name, "version_b.apex");
-  test_fn("version_b.apex");
-  // Developer goes back to version_a with persist prop.
-  android::base::SetProperty(persist_prefix + apex_name, "version_a.apex");
-  test_fn("version_a.apex");
-
-  android::base::SetProperty(persist_prefix + apex_name, "");
-  android::base::SetProperty(bootconfig_prefix + apex_name, "");
-}
-
-TEST(ApexFileRepositoryTest, InitializeMultiInstalledSkipsForDifferingKeys) {
-  // Prepare test data.
-  TemporaryDir td;
-  fs::copy(GetTestFile("apex.apexd_test.apex"),
-           StringPrintf("%s/version_a.apex", td.path));
-  fs::copy(GetTestFile("apex.apexd_test_different_key.apex"),
-           StringPrintf("%s/version_b.apex", td.path));
-  std::string apex_name =
-      ApexFile::Open(GetTestFile("apex.apexd_test.apex"))->GetManifest().name();
-  std::string prop_prefix = "debug.apexd.test.bootconfigprefix.";
-  std::string prop = prop_prefix + apex_name;
-  android::base::SetProperty(prop, "version_a.apex");
-
-  ApexFileRepository instance(
-      /*enforce_multi_install_partition=*/false,
-      /*multi_install_select_prop_prefixes=*/{prop_prefix});
-  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({td.path})));
-  // Neither version should be have been installed.
-  ASSERT_FALSE(IsOk(instance.GetPreinstalledPath(apex_name)));
-
-  android::base::SetProperty(prop, "");
-}
-
-TEST(ApexFileRepositoryTest, InitializeMultiInstalledSkipsForInvalidPartition) {
-  // Prepare test data.
-  TemporaryDir td;
-  // Note: These test files are on /data, which is not a valid partition for
-  // multi-installed APEXes.
-  fs::copy(GetTestFile("apex.apexd_test.apex"),
-           StringPrintf("%s/version_a.apex", td.path));
-  fs::copy(GetTestFile("apex.apexd_test.apex"),
-           StringPrintf("%s/version_b.apex", td.path));
-  std::string apex_name =
-      ApexFile::Open(GetTestFile("apex.apexd_test.apex"))->GetManifest().name();
-  std::string prop_prefix = "debug.apexd.test.bootconfigprefix.";
-  std::string prop = prop_prefix + apex_name;
-  android::base::SetProperty(prop, "version_a.apex");
-
-  ApexFileRepository instance(
-      /*enforce_multi_install_partition=*/true,
-      /*multi_install_select_prop_prefixes=*/{prop_prefix});
-  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({td.path})));
-  // Neither version should be have been installed.
-  ASSERT_FALSE(IsOk(instance.GetPreinstalledPath(apex_name)));
-
-  android::base::SetProperty(prop, "");
-}
-
 TEST(ApexFileRepositoryTest,
      InitializeSameNameDifferentPathAbortsCompressedApex) {
   // Prepare test data.
@@ -588,236 +502,5 @@
       "");
 }
 
-struct ApexFileRepositoryTestAddBlockApex : public ::testing::Test {
-  TemporaryDir test_dir;
-
-  struct PayloadMetadata {
-    android::microdroid::Metadata metadata;
-    std::string path;
-    PayloadMetadata(const std::string& path) : path(path) {}
-    PayloadMetadata& apex(const std::string& name,
-                          const std::string& public_key = "",
-                          const std::string& root_digest = "",
-                          int64_t last_update_seconds = 0,
-                          bool is_factory = true) {
-      auto apex = metadata.add_apexes();
-      apex->set_name(name);
-      apex->set_public_key(public_key);
-      apex->set_root_digest(root_digest);
-      apex->set_last_update_seconds(last_update_seconds);
-      apex->set_is_factory(is_factory);
-      return *this;
-    }
-    ~PayloadMetadata() {
-      metadata.set_version(1);
-      std::ofstream out(path);
-      android::microdroid::WriteMetadata(metadata, out);
-    }
-  };
-};
-
-TEST_F(ApexFileRepositoryTestAddBlockApex,
-       ScansPayloadDisksAndAddApexFilesToPreInstalled) {
-  // prepare payload disk
-  //  <test-dir>/vdc1 : metadata
-  //            /vdc2 : apex.apexd_test.apex
-  //            /vdc3 : apex.apexd_test_different_app.apex
-
-  const auto& test_apex_foo = GetTestFile("apex.apexd_test.apex");
-  const auto& test_apex_bar = GetTestFile("apex.apexd_test_different_app.apex");
-
-  const std::string metadata_partition_path = test_dir.path + "/vdc1"s;
-  const std::string apex_foo_path = test_dir.path + "/vdc2"s;
-  const std::string apex_bar_path = test_dir.path + "/vdc3"s;
-
-  PayloadMetadata(metadata_partition_path)
-      .apex(test_apex_foo)
-      .apex(test_apex_bar);
-  auto loop_device1 = WriteBlockApex(test_apex_foo, apex_foo_path);
-  auto loop_device2 = WriteBlockApex(test_apex_bar, apex_bar_path);
-
-  // call ApexFileRepository::AddBlockApex()
-  ApexFileRepository instance;
-  auto status = instance.AddBlockApex(metadata_partition_path);
-  ASSERT_RESULT_OK(status);
-
-  auto apex_foo = ApexFile::Open(apex_foo_path);
-  ASSERT_RESULT_OK(apex_foo);
-  // block apexes can be identified with IsBlockApex
-  ASSERT_TRUE(instance.IsBlockApex(*apex_foo));
-
-  // "block" apexes are treated as "pre-installed"
-  auto ret_foo = instance.GetPreInstalledApex("com.android.apex.test_package");
-  ASSERT_THAT(ret_foo, ApexFileEq(ByRef(*apex_foo)));
-
-  auto apex_bar = ApexFile::Open(apex_bar_path);
-  ASSERT_RESULT_OK(apex_bar);
-  auto ret_bar =
-      instance.GetPreInstalledApex("com.android.apex.test_package_2");
-  ASSERT_THAT(ret_bar, ApexFileEq(ByRef(*apex_bar)));
-}
-
-TEST_F(ApexFileRepositoryTestAddBlockApex,
-       ScansOnlySpecifiedInMetadataPartition) {
-  // prepare payload disk
-  //  <test-dir>/vdc1 : metadata with apex.apexd_test.apex only
-  //            /vdc2 : apex.apexd_test.apex
-  //            /vdc3 : apex.apexd_test_different_app.apex
-
-  const auto& test_apex_foo = GetTestFile("apex.apexd_test.apex");
-  const auto& test_apex_bar = GetTestFile("apex.apexd_test_different_app.apex");
-
-  const std::string metadata_partition_path = test_dir.path + "/vdc1"s;
-  const std::string apex_foo_path = test_dir.path + "/vdc2"s;
-  const std::string apex_bar_path = test_dir.path + "/vdc3"s;
-
-  // metadata lists only "foo"
-  PayloadMetadata(metadata_partition_path).apex(test_apex_foo);
-  auto loop_device1 = WriteBlockApex(test_apex_foo, apex_foo_path);
-  auto loop_device2 = WriteBlockApex(test_apex_bar, apex_bar_path);
-
-  // call ApexFileRepository::AddBlockApex()
-  ApexFileRepository instance;
-  auto status = instance.AddBlockApex(metadata_partition_path);
-  ASSERT_RESULT_OK(status);
-
-  // foo is added, but bar is not
-  auto ret_foo = instance.GetPreinstalledPath("com.android.apex.test_package");
-  ASSERT_TRUE(IsOk(ret_foo));
-  ASSERT_EQ(apex_foo_path, *ret_foo);
-  auto ret_bar =
-      instance.GetPreinstalledPath("com.android.apex.test_package_2");
-  ASSERT_FALSE(IsOk(ret_bar));
-}
-
-TEST_F(ApexFileRepositoryTestAddBlockApex, FailsWhenTheresDuplicateNames) {
-  // prepare payload disk
-  //  <test-dir>/vdc1 : metadata with v1 and v2 of apex.apexd_test
-  //            /vdc2 : apex.apexd_test.apex
-  //            /vdc3 : apex.apexd_test_v2.apex
-
-  const auto& test_apex_foo = GetTestFile("apex.apexd_test.apex");
-  const auto& test_apex_bar = GetTestFile("apex.apexd_test_v2.apex");
-
-  const std::string metadata_partition_path = test_dir.path + "/vdc1"s;
-  const std::string apex_foo_path = test_dir.path + "/vdc2"s;
-  const std::string apex_bar_path = test_dir.path + "/vdc3"s;
-
-  PayloadMetadata(metadata_partition_path)
-      .apex(test_apex_foo)
-      .apex(test_apex_bar);
-  auto loop_device1 = WriteBlockApex(test_apex_foo, apex_foo_path);
-  auto loop_device2 = WriteBlockApex(test_apex_bar, apex_bar_path);
-
-  ApexFileRepository instance;
-  auto status = instance.AddBlockApex(metadata_partition_path);
-  ASSERT_FALSE(IsOk(status));
-}
-
-TEST_F(ApexFileRepositoryTestAddBlockApex, GetBlockApexRootDigest) {
-  // prepare payload disk with root digest
-  //  <test-dir>/vdc1 : metadata with apex.apexd_test.apex only
-  //            /vdc2 : apex.apexd_test.apex
-
-  const auto& test_apex_foo = GetTestFile("apex.apexd_test.apex");
-
-  const std::string metadata_partition_path = test_dir.path + "/vdc1"s;
-  const std::string apex_foo_path = test_dir.path + "/vdc2"s;
-
-  // root digest is stored as bytes in metadata and as hexadecimal in
-  // ApexFileRepository
-  const std::string root_digest = "root_digest";
-  const std::string hex_root_digest = BytesToHex(
-      reinterpret_cast<const uint8_t*>(root_digest.data()), root_digest.size());
-
-  // metadata lists "foo"
-  PayloadMetadata(metadata_partition_path)
-      .apex(test_apex_foo, /*public_key=*/"", root_digest);
-  auto loop_device1 = WriteBlockApex(test_apex_foo, apex_foo_path);
-
-  // call ApexFileRepository::AddBlockApex()
-  ApexFileRepository instance;
-  auto status = instance.AddBlockApex(metadata_partition_path);
-  ASSERT_TRUE(IsOk(status));
-
-  ASSERT_EQ(hex_root_digest,
-            instance.GetBlockApexRootDigest("com.android.apex.test_package"));
-}
-
-TEST_F(ApexFileRepositoryTestAddBlockApex, GetBlockApexLastUpdateSeconds) {
-  // prepare payload disk with last update time
-  //  <test-dir>/vdc1 : metadata with apex.apexd_test.apex only
-  //            /vdc2 : apex.apexd_test.apex
-
-  const auto& test_apex_foo = GetTestFile("apex.apexd_test.apex");
-
-  const std::string metadata_partition_path = test_dir.path + "/vdc1"s;
-  const std::string apex_foo_path = test_dir.path + "/vdc2"s;
-
-  const int64_t last_update_seconds = 123456789;
-
-  // metadata lists "foo"
-  PayloadMetadata(metadata_partition_path)
-      .apex(test_apex_foo, /*public_key=*/"", /*root_digest=*/"",
-            last_update_seconds);
-  auto loop_device1 = WriteBlockApex(test_apex_foo, apex_foo_path);
-
-  // call ApexFileRepository::AddBlockApex()
-  ApexFileRepository instance;
-  auto status = instance.AddBlockApex(metadata_partition_path);
-  ASSERT_TRUE(IsOk(status));
-
-  ASSERT_EQ(last_update_seconds, instance.GetBlockApexLastUpdateSeconds(
-                                     "com.android.apex.test_package"));
-}
-
-TEST_F(ApexFileRepositoryTestAddBlockApex, VerifyPublicKeyWhenAddingBlockApex) {
-  // prepare payload disk
-  //  <test-dir>/vdc1 : metadata with apex.apexd_test.apex only
-  //            /vdc2 : apex.apexd_test.apex
-
-  const auto& test_apex_foo = GetTestFile("apex.apexd_test.apex");
-
-  const std::string metadata_partition_path = test_dir.path + "/vdc1"s;
-  const std::string apex_foo_path = test_dir.path + "/vdc2"s;
-
-  // metadata lists "foo"
-  PayloadMetadata(metadata_partition_path)
-      .apex(test_apex_foo, /*public_key=*/"wrong public key");
-  auto loop_device1 = WriteBlockApex(test_apex_foo, apex_foo_path);
-
-  // call ApexFileRepository::AddBlockApex()
-  ApexFileRepository instance;
-  auto status = instance.AddBlockApex(metadata_partition_path);
-  ASSERT_FALSE(IsOk(status));
-}
-
-TEST_F(ApexFileRepositoryTestAddBlockApex, RespectIsFactoryBitFromMetadata) {
-  // prepare payload disk
-  //  <test-dir>/vdc1 : metadata with apex.apexd_test.apex only
-  //            /vdc2 : apex.apexd_test.apex
-
-  const auto& test_apex_foo = GetTestFile("apex.apexd_test.apex");
-
-  const std::string metadata_partition_path = test_dir.path + "/vdc1"s;
-  const std::string apex_foo_path = test_dir.path + "/vdc2"s;
-  auto loop_device1 = WriteBlockApex(test_apex_foo, apex_foo_path);
-
-  for (const bool is_factory : {true, false}) {
-    // metadata lists "foo"
-    PayloadMetadata(metadata_partition_path)
-        .apex(test_apex_foo, /*public_key=*/"", /*root_digest=*/"",
-              /*last_update_seconds=*/0, is_factory);
-
-    // call ApexFileRepository::AddBlockApex()
-    ApexFileRepository instance;
-    auto status = instance.AddBlockApex(metadata_partition_path);
-    ASSERT_TRUE(IsOk(status))
-        << "failed to add block apex with is_factory=" << is_factory;
-    ASSERT_EQ(is_factory,
-              instance.HasPreInstalledVersion("com.android.apex.test_package"));
-  }
-}
-
 }  // namespace apex
 }  // namespace android
diff --git a/apexd/apex_file_test.cpp b/apexd/apex_file_test.cpp
index a9d83a2..3da7448 100644
--- a/apexd/apex_file_test.cpp
+++ b/apexd/apex_file_test.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <limits>
 #include <string>
 
 #include <android-base/file.h>
@@ -45,9 +44,7 @@
 };
 
 constexpr const ApexFileTestParam kParameters[] = {
-    {"ext4", "apex.apexd_test"},
-    {"f2fs", "apex.apexd_test_f2fs"},
-    {"erofs", "apex.apexd_test_erofs"}};
+    {"ext4", "apex.apexd_test"}, {"f2fs", "apex.apexd_test_f2fs"}};
 
 class ApexFileTest : public ::testing::TestWithParam<ApexFileTestParam> {};
 
@@ -58,7 +55,7 @@
   Result<ApexFile> apex_file = ApexFile::Open(file_path);
   ASSERT_TRUE(apex_file.ok());
 
-  uint32_t zip_image_offset;
+  int32_t zip_image_offset;
   size_t zip_image_size;
   {
     ZipArchiveHandle handle;
@@ -72,7 +69,7 @@
     ASSERT_EQ(0, rc);
 
     zip_image_offset = entry.offset;
-    EXPECT_EQ(zip_image_offset % 4096, 0U);
+    EXPECT_EQ(zip_image_offset % 4096, 0);
     zip_image_size = entry.uncompressed_length;
     EXPECT_EQ(zip_image_size, entry.compressed_length);
   }
@@ -81,21 +78,6 @@
   EXPECT_EQ(zip_image_size, apex_file->GetImageSize().value());
 }
 
-TEST_P(ApexFileTest, OpenBlockApex) {
-  const std::string file_path = kTestDataDir + GetParam().prefix + ".apex";
-  Result<ApexFile> apex_file = ApexFile::Open(file_path);
-  ASSERT_RESULT_OK(apex_file);
-
-  TemporaryFile temp_file;
-  auto loop_device = WriteBlockApex(file_path, temp_file.path);
-
-  Result<ApexFile> apex_file_sized = ApexFile::Open(temp_file.path);
-  ASSERT_RESULT_OK(apex_file_sized);
-
-  EXPECT_EQ(apex_file->GetImageOffset(), apex_file_sized->GetImageOffset());
-  EXPECT_EQ(apex_file->GetImageSize(), apex_file_sized->GetImageSize());
-}
-
 TEST(ApexFileTest, GetOffsetMissingFile) {
   const std::string file_path = kTestDataDir + "missing.apex";
   Result<ApexFile> apex_file = ApexFile::Open(file_path);
@@ -241,7 +223,7 @@
       ::testing::HasSubstr("Cannot verify ApexVerity of compressed APEX"));
 }
 
-TEST(ApexFileTest, DISABLED_DecompressCompressedApex) {
+TEST(ApexFileTest, DecompressCompressedApex) {
   const std::string file_path =
       kTestDataDir + "com.android.apex.compressed.v1.capex";
   Result<ApexFile> apex_file = ApexFile::Open(file_path);
diff --git a/apexd/apex_shim.cpp b/apexd/apex_shim.cpp
index 441c971..0031c3f 100644
--- a/apexd/apex_shim.cpp
+++ b/apexd/apex_shim.cpp
@@ -53,17 +53,8 @@
     "apex_manifest.pb",
     "etc/hash.txt",
     "app/CtsShim/CtsShim.apk",
-    "app/CtsShim@1/CtsShim.apk",
-    "app/CtsShim@2/CtsShim.apk",
-    "app/CtsShim@3/CtsShim.apk",
     "app/CtsShimTargetPSdk/CtsShimTargetPSdk.apk",
-    "app/CtsShimTargetPSdk@1/CtsShimTargetPSdk.apk",
-    "app/CtsShimTargetPSdk@2/CtsShimTargetPSdk.apk",
-    "app/CtsShimTargetPSdk@3/CtsShimTargetPSdk.apk",
     "priv-app/CtsShimPriv/CtsShimPriv.apk",
-    "priv-app/CtsShimPriv@1/CtsShimPriv.apk",
-    "priv-app/CtsShimPriv@2/CtsShimPriv.apk",
-    "priv-app/CtsShimPriv@3/CtsShimPriv.apk",
 };
 
 Result<std::string> CalculateSha512(const std::string& path) {
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index ff60ed7..e0562f0 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -14,9 +14,24 @@
  * limitations under the License.
  */
 
-#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
-
 #include "apexd.h"
+#include "apex_file_repository.h"
+#include "apexd_private.h"
+
+#include "apex_constants.h"
+#include "apex_database.h"
+#include "apex_file.h"
+#include "apex_manifest.h"
+#include "apex_shim.h"
+#include "apexd_checkpoint.h"
+#include "apexd_lifecycle.h"
+#include "apexd_loop.h"
+#include "apexd_prepostinstall.h"
+#include "apexd_rollback_utils.h"
+#include "apexd_session.h"
+#include "apexd_utils.h"
+#include "apexd_verity.h"
+#include "com_android_apex.h"
 
 #include <ApexProperties.sysprop.h>
 #include <android-base/chrono_utils.h>
@@ -29,16 +44,17 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
-#include <dirent.h>
-#include <fcntl.h>
 #include <google/protobuf/util/message_differencer.h>
 #include <libavb/libavb.h>
 #include <libdm/dm.h>
 #include <libdm/dm_table.h>
 #include <libdm/dm_target.h>
+#include <selinux/android.h>
+
+#include <dirent.h>
+#include <fcntl.h>
 #include <linux/f2fs.h>
 #include <linux/loop.h>
-#include <selinux/android.h>
 #include <stdlib.h>
 #include <sys/inotify.h>
 #include <sys/ioctl.h>
@@ -47,7 +63,7 @@
 #include <sys/sysinfo.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <utils/Trace.h>
+#include <algorithm>
 
 #include <algorithm>
 #include <array>
@@ -69,23 +85,6 @@
 #include <unordered_map>
 #include <unordered_set>
 
-#include "VerityUtils.h"
-#include "apex_constants.h"
-#include "apex_database.h"
-#include "apex_file.h"
-#include "apex_file_repository.h"
-#include "apex_manifest.h"
-#include "apex_shim.h"
-#include "apexd_checkpoint.h"
-#include "apexd_lifecycle.h"
-#include "apexd_loop.h"
-#include "apexd_private.h"
-#include "apexd_rollback_utils.h"
-#include "apexd_session.h"
-#include "apexd_utils.h"
-#include "apexd_verity.h"
-#include "com_android_apex.h"
-
 using android::base::boot_clock;
 using android::base::ConsumePrefix;
 using android::base::ErrnoError;
@@ -93,10 +92,10 @@
 using android::base::GetProperty;
 using android::base::Join;
 using android::base::ParseUint;
+using android::base::ReadFully;
 using android::base::RemoveFileIfExists;
 using android::base::Result;
 using android::base::SetProperty;
-using android::base::StartsWith;
 using android::base::StringPrintf;
 using android::base::unique_fd;
 using android::dm::DeviceMapper;
@@ -128,15 +127,6 @@
 bool gSupportsFsCheckpoints = false;
 bool gInFsCheckpointMode = false;
 
-// APEXEs for which a different version was activated than in the previous boot.
-// This can happen in the following scenarios:
-//  1. This APEX is part of the staged session that was applied during this
-//    boot.
-//  2. This is a compressed APEX that was decompressed during this boot.
-//  3. We failed to activate APEX from /data/apex/active and fallback to the
-//  pre-installed APEX.
-std::set<std::string> gChangedActiveApexes;
-
 static constexpr size_t kLoopDeviceSetupAttempts = 3u;
 
 // Please DO NOT add new modules to this list without contacting mainline-modularization@ first.
@@ -314,9 +304,22 @@
   bool cleared_;
 };
 
-Result<DmVerityDevice> CreateVerityDevice(
-    DeviceMapper& dm, const std::string& name, const DmTable& table,
-    const std::chrono::milliseconds& timeout) {
+Result<DmVerityDevice> CreateVerityDevice(const std::string& name,
+                                          const DmTable& table) {
+  DeviceMapper& dm = DeviceMapper::Instance();
+
+  if (dm.GetState(name) != DmDeviceState::INVALID) {
+    // Delete dangling dm-device. This can happen if apexd fails to delete it
+    // while unmounting an apex.
+    LOG(WARNING) << "Deleting existing dm device " << name;
+    auto result = DeleteVerityDevice(name, /* deferred= */ false);
+    if (!result.ok()) {
+      return result.error();
+    }
+  }
+
+  auto timeout = std::chrono::milliseconds(
+      android::sysprop::ApexProperties::dm_create_timeout().value_or(1000));
   std::string dev_path;
   if (!dm.CreateDevice(name, table, &dev_path, timeout)) {
     return Errorf("Couldn't create verity device.");
@@ -324,52 +327,6 @@
   return DmVerityDevice(name, dev_path);
 }
 
-Result<DmVerityDevice> CreateVerityDevice(const std::string& name,
-                                          const DmTable& table,
-                                          bool reuse_device) {
-  ATRACE_NAME("CreateVerityDevice");
-  LOG(VERBOSE) << "Creating verity device " << name;
-  auto timeout = std::chrono::milliseconds(
-      android::sysprop::ApexProperties::dm_create_timeout().value_or(1000));
-
-  DeviceMapper& dm = DeviceMapper::Instance();
-
-  auto state = dm.GetState(name);
-  if (state == DmDeviceState::INVALID) {
-    return CreateVerityDevice(dm, name, table, timeout);
-  }
-
-  if (reuse_device) {
-    if (state == DmDeviceState::ACTIVE) {
-      LOG(WARNING) << "Deleting existing active dm device " << name;
-      if (auto r = DeleteVerityDevice(name, /* deferred= */ false); !r.ok()) {
-        return r.error();
-      }
-      return CreateVerityDevice(dm, name, table, timeout);
-    }
-    if (!dm.LoadTableAndActivate(name, table)) {
-      dm.DeleteDevice(name);
-      return Error() << "Failed to activate dm device " << name;
-    }
-    std::string path;
-    if (!dm.WaitForDevice(name, timeout, &path)) {
-      dm.DeleteDevice(name);
-      return Error() << "Failed waiting for dm device " << name;
-    }
-    return DmVerityDevice(name, path);
-  } else {
-    if (state != DmDeviceState::INVALID) {
-      // Delete dangling dm-device. This can happen if apexd fails to delete it
-      // while unmounting an apex.
-      LOG(WARNING) << "Deleting existing dm device " << name;
-      if (auto r = DeleteVerityDevice(name, /* deferred= */ false); !r.ok()) {
-        return r.error();
-      }
-    }
-    return CreateVerityDevice(dm, name, table, timeout);
-  }
-}
-
 /**
  * When we create hardlink for a new apex package in kActiveApexPackagesDataDir,
  * there might be an older version of the same package already present in there.
@@ -467,10 +424,8 @@
                                          const std::string& mount_point,
                                          const std::string& device_name,
                                          const std::string& hashtree_file,
-                                         bool verify_image, bool reuse_device,
+                                         bool verify_image,
                                          bool temp_mount = false) {
-  auto tag = "MountPackageImpl: " + apex.GetManifest().name();
-  ATRACE_NAME(tag.c_str());
   if (apex.IsCompressed()) {
     return Error() << "Cannot directly mount compressed APEX "
                    << apex.GetPath();
@@ -510,10 +465,8 @@
   }
   loop::LoopbackDeviceUniqueFd loopback_device;
   for (size_t attempts = 1;; ++attempts) {
-    Result<loop::LoopbackDeviceUniqueFd> ret =
-        loop::CreateAndConfigureLoopDevice(full_path,
-                                           apex.GetImageOffset().value(),
-                                           apex.GetImageSize().value());
+    Result<loop::LoopbackDeviceUniqueFd> ret = loop::CreateLoopDevice(
+        full_path, apex.GetImageOffset().value(), apex.GetImageSize().value());
     if (ret.ok()) {
       loopback_device = std::move(*ret);
       break;
@@ -537,18 +490,6 @@
     return Error() << "Failed to verify Apex Verity data for " << full_path
                    << ": " << verity_data.error();
   }
-  if (instance.IsBlockApex(apex)) {
-    auto root_digest =
-        instance.GetBlockApexRootDigest(apex.GetManifest().name());
-    if (root_digest.has_value() &&
-        root_digest.value() != verity_data->root_digest) {
-      return Error() << "Failed to verify Apex Verity data for " << full_path
-                     << ": root digest (" << verity_data->root_digest
-                     << ") mismatches with the one (" << root_digest.value()
-                     << ") specified in config";
-    }
-  }
-
   std::string block_device = loopback_device.name;
   MountedApexData apex_data(loopback_device.name, apex.GetPath(), mount_point,
                             /* device_name = */ "",
@@ -559,11 +500,8 @@
   // dm-verity because they are already in the dm-verity protected partition;
   // system. However, note that we don't skip verification to ensure that APEXes
   // are correctly signed.
-  const bool mount_on_verity = !instance.IsPreInstalledApex(apex) ||
-                               // decompressed apexes are on /data
-                               instance.IsDecompressedApex(apex) ||
-                               // block apexes are from host
-                               instance.IsBlockApex(apex);
+  const bool mount_on_verity =
+      !instance.IsPreInstalledApex(apex) || instance.IsDecompressedApex(apex);
 
   DmVerityDevice verity_dev;
   loop::LoopbackDeviceUniqueFd loop_for_hash;
@@ -574,10 +512,7 @@
           !st.ok()) {
         return st.error();
       }
-      auto create_loop_status =
-          loop::CreateAndConfigureLoopDevice(hashtree_file,
-                                             /* image_offset= */ 0,
-                                             /* image_size= */ 0);
+      auto create_loop_status = loop::CreateLoopDevice(hashtree_file, 0, 0);
       if (!create_loop_status.ok()) {
         return create_loop_status.error();
       }
@@ -589,7 +524,7 @@
         CreateVerityTable(*verity_data, loopback_device.name, hash_device,
                           /* restart_on_corruption = */ !verify_image);
     Result<DmVerityDevice> verity_dev_res =
-        CreateVerityDevice(device_name, *verity_table, reuse_device);
+        CreateVerityDevice(device_name, *verity_table);
     if (!verity_dev_res.ok()) {
       return Error() << "Failed to create Apex Verity device " << full_path
                      << ": " << verity_dev_res.error();
@@ -668,8 +603,7 @@
   }
   auto ret =
       MountPackageImpl(apex, mount_point, temp_device_name, hashtree_file,
-                       /* verify_image = */ true, /* reuse_device= */ false,
-                       /* temp_mount = */ true);
+                       /* verify_image = */ true, /* temp_mount = */ true);
   if (!ret.ok()) {
     LOG(DEBUG) << "Cleaning up " << hashtree_file;
     if (TEMP_FAILURE_RETRY(unlink(hashtree_file.c_str())) != 0) {
@@ -728,95 +662,6 @@
 
 namespace {
 
-// TODO(b/218672709): get the ro.build.version.sdk version of the device.
-const auto kSepolicyLevel = std::to_string(__ANDROID_API_T__);
-const auto kVersionedSepolicyZip = "SEPolicy-" + kSepolicyLevel + ".zip";
-const auto kVersionedSepolicySig = "SEPolicy-" + kSepolicyLevel + ".zip.sig";
-const auto kVersionedSepolicyFsv =
-    "SEPolicy-" + kSepolicyLevel + ".zip.fsv_sig";
-
-const auto kSepolicyZip = "SEPolicy.zip";
-const auto kSepolicySig = "SEPolicy.zip.sig";
-const auto kSepolicyFsv = "SEPolicy.zip.fsv_sig";
-
-Result<void> CopySepolicyToMetadata(const std::string& mount_point) {
-  LOG(DEBUG) << "Copying SEPolicy files to /metadata/sepolicy/staged.";
-  const auto policy_dir = mount_point + "/etc";
-
-  // Find SEPolicy zip and signature files.
-  std::optional<std::string> sepolicy_zip;
-  std::optional<std::string> sepolicy_sig;
-  std::optional<std::string> sepolicy_fsv;
-  auto status =
-      WalkDir(policy_dir, [&sepolicy_zip, &sepolicy_sig, &sepolicy_fsv](
-                              const std::filesystem::directory_entry& entry) {
-        if (!entry.is_regular_file()) {
-          return;
-        }
-        const auto& path = entry.path().string();
-        if (base::EndsWith(path, kVersionedSepolicyZip)) {
-          sepolicy_zip = path;
-        } else if (base::EndsWith(path, kVersionedSepolicySig)) {
-          sepolicy_sig = path;
-        } else if (base::EndsWith(path, kVersionedSepolicyFsv)) {
-          sepolicy_fsv = path;
-        }
-      });
-  if (!status.ok()) {
-    return status.error();
-  }
-  if (sepolicy_zip->empty() || sepolicy_sig->empty() || sepolicy_fsv->empty()) {
-    return Error() << "SEPolicy files not found.";
-  }
-  LOG(INFO) << "SEPolicy files found.";
-
-  // Set up staging directory.
-  std::error_code ec;
-  const auto staged_dir =
-      std::string(gConfig->metadata_sepolicy_staged_dir) + "/";
-  status = CreateDirIfNeeded(staged_dir, 0755);
-  if (!status.ok()) {
-    return status.error();
-  }
-
-  // Clean up after myself.
-  auto scope_guard = android::base::make_scope_guard([&staged_dir]() {
-    std::error_code ec;
-    std::filesystem::remove_all(staged_dir, ec);
-    if (ec) {
-      LOG(WARNING) << "Failed to clear " << staged_dir << ": " << ec.message();
-    }
-  });
-
-  // Copy files to staged folder.
-  const auto stagedSepolicyZip = staged_dir + kSepolicyZip;
-  const auto stagedSepolicyFsv = staged_dir + kSepolicyFsv;
-  std::map<std::string, std::string> from_to = {
-      {*sepolicy_zip, stagedSepolicyZip},
-      {*sepolicy_sig, staged_dir + kSepolicySig},
-      {*sepolicy_fsv, stagedSepolicyFsv}};
-  for (const auto& [from, to] : from_to) {
-    std::filesystem::copy_file(
-        from, to, std::filesystem::copy_options::update_existing, ec);
-    if (ec) {
-      return Error() << "Failed to copy " << from << " to " << to << ": "
-                     << ec.message();
-    }
-  }
-
-  status = enableFsVerity(stagedSepolicyZip, stagedSepolicyFsv);
-  if (!status.ok()) {
-    // TODO(b/218672709): once we have a release certificate available, return
-    // an error and make the ApexdMountTest#CopySepolicyToMetadata test pass.
-    LOG(ERROR) << status.error().message();
-  } else {
-    LOG(INFO) << "fs-verity enabled on " << stagedSepolicyZip;
-  }
-
-  scope_guard.Disable();
-  return {};
-}
-
 template <typename VerifyFn>
 Result<void> RunVerifyFnInsideTempMount(const ApexFile& apex,
                                         const VerifyFn& verify_fn,
@@ -855,6 +700,65 @@
   return {};
 }
 
+template <typename HookFn, typename HookCall>
+Result<void> PrePostinstallPackages(const std::vector<ApexFile>& apexes,
+                                    HookFn fn, HookCall call) {
+  auto scope_guard = android::base::make_scope_guard([&]() {
+    for (const ApexFile& apex_file : apexes) {
+      apexd_private::UnmountTempMount(apex_file);
+    }
+  });
+  if (apexes.empty()) {
+    return Errorf("Empty set of inputs");
+  }
+
+  // 1) Check whether the APEXes have hooks.
+  bool has_hooks = false;
+  for (const ApexFile& apex_file : apexes) {
+    if (!(apex_file.GetManifest().*fn)().empty()) {
+      has_hooks = true;
+      break;
+    }
+  }
+
+  // 2) If we found hooks, temp mount if required, and run the pre/post-install.
+  if (has_hooks) {
+    std::vector<std::string> mount_points;
+    for (const ApexFile& apex : apexes) {
+      // Retrieve the mount data if the apex is already temp mounted, temp
+      // mount it otherwise.
+      std::string mount_point =
+          apexd_private::GetPackageTempMountPoint(apex.GetManifest());
+      Result<MountedApexData> mount_data =
+          apexd_private::GetTempMountedApexData(apex.GetManifest().name());
+      if (!mount_data.ok()) {
+        mount_data = VerifyAndTempMountPackage(apex, mount_point);
+        if (!mount_data.ok()) {
+          return mount_data.error();
+        }
+      }
+      mount_points.push_back(mount_point);
+    }
+
+    Result<void> install_status = (*call)(apexes, mount_points);
+    if (!install_status.ok()) {
+      return install_status;
+    }
+  }
+
+  return {};
+}
+
+Result<void> PreinstallPackages(const std::vector<ApexFile>& apexes) {
+  return PrePostinstallPackages(apexes, &ApexManifest::preinstallhook,
+                                &StagePreInstall);
+}
+
+Result<void> PostinstallPackages(const std::vector<ApexFile>& apexes) {
+  return PrePostinstallPackages(apexes, &ApexManifest::postinstallhook,
+                                &StagePostInstall);
+}
+
 // Converts a list of apex file paths into a list of ApexFile objects
 //
 // Returns error when trying to open empty set of inputs.
@@ -914,8 +818,6 @@
   return {};
 }
 
-static constexpr auto kSepolicyApexName = "com.android.sepolicy.apex";
-
 // A version of apex verification that happens on SubmitStagedSession.
 // This function contains checks that might be expensive to perform, e.g. temp
 // mounting a package and reading entire dm-verity device, and shouldn't be run
@@ -926,13 +828,10 @@
     return verify_package_boot_status;
   }
 
-  const auto validate_fn = [&apex_file](const std::string& mount_point) {
-    if (apex_file.GetManifest().name() == kSepolicyApexName) {
-      return CopySepolicyToMetadata(mount_point);
-    }
+  constexpr const auto kSuccessFn = [](const std::string& /*mount_point*/) {
     return Result<void>{};
   };
-  return RunVerifyFnInsideTempMount(apex_file, validate_fn, false);
+  return RunVerifyFnInsideTempMount(apex_file, kSuccessFn, false);
 }
 
 template <typename VerifyApexFn>
@@ -954,9 +853,9 @@
   return std::move(*apex_files);
 }
 
-Result<ApexFile> VerifySessionDir(int session_id) {
-  std::string session_dir_path =
-      StringPrintf("%s/session_%d", gConfig->staged_session_dir, session_id);
+Result<ApexFile> VerifySessionDir(const int session_id) {
+  std::string session_dir_path = std::string(kStagedSessionsDir) + "/session_" +
+                                 std::to_string(session_id);
   LOG(INFO) << "Scanning " << session_dir_path
             << " looking for packages to be validated";
   Result<std::vector<std::string>> scan =
@@ -1143,12 +1042,10 @@
 void SetConfig(const ApexdConfig& config) { gConfig = config; }
 
 Result<void> MountPackage(const ApexFile& apex, const std::string& mount_point,
-                          const std::string& device_name, bool reuse_device,
-                          bool temp_mount) {
-  auto ret =
-      MountPackageImpl(apex, mount_point, device_name,
-                       GetHashTreeFileName(apex, /* is_new= */ false),
-                       /* verify_image = */ false, reuse_device, temp_mount);
+                          const std::string& device_name) {
+  auto ret = MountPackageImpl(apex, mount_point, device_name,
+                              GetHashTreeFileName(apex, /* is_new= */ false),
+                              /* verify_image = */ false);
   if (!ret.ok()) {
     return ret.error();
   }
@@ -1337,9 +1234,7 @@
 }
 
 Result<void> ActivatePackageImpl(const ApexFile& apex_file,
-                                 const std::string& device_name,
-                                 bool reuse_device) {
-  ATRACE_NAME("ActivatePackageImpl");
+                                 const std::string& device_name) {
   const ApexManifest& manifest = apex_file.GetManifest();
 
   if (!IsValidPackageName(manifest.name())) {
@@ -1398,8 +1293,7 @@
       apexd_private::GetPackageMountPoint(manifest);
 
   if (!version_found_mounted) {
-    auto mount_status = MountPackage(apex_file, mount_point, device_name,
-                                     reuse_device, /*temp_mount=*/false);
+    auto mount_status = MountPackage(apex_file, mount_point, device_name);
     if (!mount_status.ok()) {
       return mount_status;
     }
@@ -1453,8 +1347,8 @@
   if (!apex_file.ok()) {
     return apex_file.error();
   }
-  return ActivatePackageImpl(*apex_file, GetPackageId(apex_file->GetManifest()),
-                             /* reuse_device= */ false);
+  return ActivatePackageImpl(*apex_file,
+                             GetPackageId(apex_file->GetManifest()));
 }
 
 Result<void> DeactivatePackage(const std::string& full_path) {
@@ -1469,74 +1363,6 @@
                         /* deferred= */ false);
 }
 
-Result<std::vector<ApexFile>> GetStagedApexFiles(
-    int session_id, const std::vector<int>& child_session_ids) {
-  auto session = ApexSession::GetSession(session_id);
-  if (!session.ok()) {
-    return session.error();
-  }
-  // We should only accept sessions in SessionState::STAGED state
-  auto session_state = (*session).GetState();
-  if (session_state != SessionState::STAGED) {
-    return Error() << "Session " << session_id << " is not in state STAGED";
-  }
-
-  std::vector<int> ids_to_scan;
-  if (!child_session_ids.empty()) {
-    ids_to_scan = child_session_ids;
-  } else {
-    ids_to_scan = {session_id};
-  }
-
-  // Find apex files in the staging directory
-  std::vector<std::string> apex_file_paths;
-  for (int id_to_scan : ids_to_scan) {
-    std::string session_dir_path = std::string(gConfig->staged_session_dir) +
-                                   "/session_" + std::to_string(id_to_scan);
-    Result<std::vector<std::string>> scan =
-        FindFilesBySuffix(session_dir_path, {kApexPackageSuffix});
-    if (!scan.ok()) {
-      return scan.error();
-    }
-    if (scan->size() != 1) {
-      return Error() << "Expected exactly one APEX file in directory "
-                     << session_dir_path << ". Found: " << scan->size();
-    }
-    std::string& apex_file_path = (*scan)[0];
-    apex_file_paths.push_back(std::move(apex_file_path));
-  }
-
-  return OpenApexFiles(apex_file_paths);
-}
-
-Result<ClassPath> MountAndDeriveClassPath(
-    const std::vector<ApexFile>& apex_files) {
-  auto guard = android::base::make_scope_guard([&]() {
-    for (const auto& apex : apex_files) {
-      apexd_private::UnmountTempMount(apex);
-    }
-  });
-
-  // Mount the staged apex files
-  std::vector<std::string> temp_mounted_apex_paths;
-  for (const auto& apex : apex_files) {
-    const std::string& temp_mount_point =
-        apexd_private::GetPackageTempMountPoint(apex.GetManifest());
-    const std::string& package_id = GetPackageId(apex.GetManifest());
-    const std::string& temp_device_name = package_id + ".tmp";
-    auto mount_status =
-        MountPackage(apex, temp_mount_point, temp_device_name,
-                     /*reuse_device=*/false, /*temp_mount=*/true);
-    if (!mount_status.ok()) {
-      return mount_status.error();
-    }
-    temp_mounted_apex_paths.push_back(temp_mount_point);
-  }
-
-  // Calculate classpaths of temp mounted staged apexs
-  return ClassPath::DeriveClassPath(temp_mounted_apex_paths);
-}
-
 std::vector<ApexFile> GetActivePackages() {
   std::vector<ApexFile> ret;
   gMountedApexes.ForallMountedApexes(
@@ -1686,20 +1512,6 @@
   return ErrnoError() << "Cannot find matching package for: " << packageName;
 }
 
-Result<void> DeleteStagedSepolicy() {
-  const auto staged_dir =
-      std::string(gConfig->metadata_sepolicy_staged_dir) + "/";
-  LOG(DEBUG) << "Deleting " << staged_dir;
-  std::error_code ec;
-  auto removed = std::filesystem::remove_all(staged_dir, ec);
-  if (removed == 0) {
-    LOG(INFO) << staged_dir << " already deleted.";
-  } else if (ec) {
-    return Error() << "Failed to clear " << staged_dir << ": " << ec.message();
-  }
-  return {};
-}
-
 /**
  * Abort individual staged session.
  *
@@ -1710,16 +1522,6 @@
   if (!session.ok()) {
     return Error() << "No session found with id " << session_id;
   }
-
-  const auto& apex_names = session->GetApexNames();
-  if (std::find(std::begin(apex_names), std::end(apex_names),
-                kSepolicyApexName) != std::end(apex_names)) {
-    const auto result = DeleteStagedSepolicy();
-    if (!result.ok()) {
-      return result.error();
-    }
-  }
-
   switch (session->GetState()) {
     case SessionState::VERIFIED:
       [[clang::fallthrough]];
@@ -1732,12 +1534,40 @@
 
 namespace {
 
-enum ActivationMode { kBootstrapMode = 0, kBootMode, kOtaChrootMode, kVmMode };
+// TODO(b/179497746): Avoid scanning apex directly here
+// Only used in OnBootstrap. Should we remove this function?
+Result<std::vector<ApexFile>> ScanApexFiles(const char* apex_package_dir,
+                                            bool include_compressed = false) {
+  LOG(INFO) << "Scanning " << apex_package_dir << " looking for APEX packages.";
+  if (access(apex_package_dir, F_OK) != 0 && errno == ENOENT) {
+    LOG(INFO) << "... does not exist. Skipping";
+    return {};
+  }
+  std::vector<std::string> suffix_list = {kApexPackageSuffix};
+  if (include_compressed) {
+    suffix_list.push_back(kCompressedApexPackageSuffix);
+  }
+  Result<std::vector<std::string>> scan =
+      FindFilesBySuffix(apex_package_dir, suffix_list);
+  if (!scan.ok()) {
+    return Error() << "Failed to scan " << apex_package_dir << " : "
+                   << scan.error();
+  }
+  std::vector<ApexFile> ret;
+  for (const auto& name : *scan) {
+    Result<ApexFile> apex_file = ApexFile::Open(name);
+    if (!apex_file.ok()) {
+      LOG(ERROR) << "Failed to scan " << name << " : " << apex_file.error();
+    } else {
+      ret.emplace_back(std::move(*apex_file));
+    }
+  }
+  return ret;
+}
 
 std::vector<Result<void>> ActivateApexWorker(
-    ActivationMode mode, std::queue<const ApexFile*>& apex_queue,
+    bool is_ota_chroot, std::queue<const ApexFile*>& apex_queue,
     std::mutex& mutex) {
-  ATRACE_NAME("ActivateApexWorker");
   std::vector<Result<void>> ret;
 
   while (true) {
@@ -1749,20 +1579,13 @@
       apex_queue.pop();
     }
 
-    std::string device_name;
-    if (mode == ActivationMode::kBootMode) {
-      device_name = apex->GetManifest().name();
-    } else {
-      device_name = GetPackageId(apex->GetManifest());
-    }
-    if (mode == ActivationMode::kOtaChrootMode) {
+    std::string device_name = GetPackageId(apex->GetManifest());
+    if (is_ota_chroot) {
       device_name += ".chroot";
     }
-    bool reuse_device = mode == ActivationMode::kBootMode;
-    auto res = ActivatePackageImpl(*apex, device_name, reuse_device);
-    if (!res.ok()) {
-      ret.push_back(Error() << "Failed to activate " << apex->GetPath() << "("
-                            << device_name << "): " << res.error());
+    if (auto res = ActivatePackageImpl(*apex, device_name); !res.ok()) {
+      ret.push_back(Error() << "Failed to activate " << apex->GetPath() << " : "
+                            << res.error());
     } else {
       ret.push_back({});
     }
@@ -1772,8 +1595,7 @@
 }
 
 Result<void> ActivateApexPackages(const std::vector<ApexFileRef>& apexes,
-                                  ActivationMode mode) {
-  ATRACE_NAME("ActivateApexPackages");
+                                  bool is_ota_chroot) {
   std::queue<const ApexFile*> apex_queue;
   std::mutex apex_queue_mutex;
 
@@ -1798,7 +1620,7 @@
   futures.reserve(worker_num);
   for (size_t i = 0; i < worker_num; i++) {
     futures.push_back(std::async(std::launch::async, ActivateApexWorker,
-                                 std::ref(mode), std::ref(apex_queue),
+                                 std::ref(is_ota_chroot), std::ref(apex_queue),
                                  std::ref(apex_queue_mutex)));
   }
 
@@ -1831,7 +1653,7 @@
 // such apexes that were coming from /data partition we will attempt to activate
 // their corresponding pre-installed copies.
 Result<void> ActivateMissingApexes(const std::vector<ApexFileRef>& apexes,
-                                   ActivationMode mode) {
+                                   bool is_ota_chroot) {
   LOG(INFO) << "Trying to activate pre-installed versions of missing apexes";
   const auto& file_repository = ApexFileRepository::GetInstance();
   const auto& activated_apexes = GetActivePackagesMap();
@@ -1866,22 +1688,13 @@
   }
   std::vector<ApexFile> decompressed_apex;
   if (!compressed_apex.empty()) {
-    decompressed_apex = ProcessCompressedApex(
-        compressed_apex,
-        /* is_ota_chroot= */ mode == ActivationMode::kOtaChrootMode);
+    decompressed_apex =
+        ProcessCompressedApex(compressed_apex, /* is_ota_chroot= */ false);
     for (const ApexFile& apex_file : decompressed_apex) {
       fallback_apexes.emplace_back(std::cref(apex_file));
     }
   }
-  if (mode == kBootMode) {
-    // Treat fallback to pre-installed APEXes as a change of the acitve APEX,
-    // since we are already in a pretty dire situation, so it's better if we
-    // drop all the caches.
-    for (const auto& apex : fallback_apexes) {
-      gChangedActiveApexes.insert(apex.get().GetManifest().name());
-    }
-  }
-  return ActivateApexPackages(fallback_apexes, mode);
+  return ActivateApexPackages(fallback_apexes, is_ota_chroot);
 }
 
 }  // namespace
@@ -2128,6 +1941,7 @@
 
 void OnBootCompleted() {
   ApexdLifecycle::GetInstance().MarkBootCompleted();
+  BootCompletedCleanup();
 }
 
 // Returns true if any session gets staged
@@ -2231,7 +2045,17 @@
       continue;
     }
 
-    std::vector<std::string> staged_apex_names;
+    // Run postinstall, if necessary.
+    Result<void> postinstall_status = PostinstallPackages(apexes);
+    if (!postinstall_status.ok()) {
+      std::string error_message =
+          StringPrintf("Postinstall failed for session %d %s", session_id,
+                       postinstall_status.error().message().c_str());
+      LOG(ERROR) << error_message;
+      session.SetErrorMessage(error_message);
+      continue;
+    }
+
     for (const auto& apex : apexes) {
       // TODO(b/158470836): Avoid opening ApexFile repeatedly.
       Result<ApexFile> apex_file = ApexFile::Open(apex);
@@ -2239,7 +2063,7 @@
         LOG(ERROR) << "Cannot open apex file during staging: " << apex;
         continue;
       }
-      staged_apex_names.push_back(apex_file->GetManifest().name());
+      session.AddApexName(apex_file->GetManifest().name());
     }
 
     const Result<void> result = StagePackages(apexes);
@@ -2255,10 +2079,6 @@
     // Session was OK, release scopeguard.
     scope_guard.Disable();
 
-    for (const std::string& apex : staged_apex_names) {
-      gChangedActiveApexes.insert(apex);
-    }
-
     auto st = session.UpdateStateAndCommit(SessionState::ACTIVATED);
     if (!st.ok()) {
       LOG(ERROR) << "Failed to mark " << session
@@ -2267,6 +2087,24 @@
   }
 }
 
+Result<void> PreinstallPackages(const std::vector<std::string>& paths) {
+  Result<std::vector<ApexFile>> apex_files = OpenApexFiles(paths);
+  if (!apex_files.ok()) {
+    return apex_files.error();
+  }
+  LOG(DEBUG) << "PreinstallPackages() for " << Join(paths, ',');
+  return PreinstallPackages(*apex_files);
+}
+
+Result<void> PostinstallPackages(const std::vector<std::string>& paths) {
+  Result<std::vector<ApexFile>> apex_files = OpenApexFiles(paths);
+  if (!apex_files.ok()) {
+    return apex_files.error();
+  }
+  LOG(DEBUG) << "PostinstallPackages() for " << Join(paths, ',');
+  return PostinstallPackages(*apex_files);
+}
+
 namespace {
 std::string StageDestPath(const ApexFile& apex_file) {
   return StringPrintf("%s/%s%s", gConfig->active_apex_data_dir,
@@ -2511,7 +2349,6 @@
 }
 
 int OnBootstrap() {
-  ATRACE_NAME("OnBootstrap");
   auto time_started = boot_clock::now();
   Result<void> pre_allocate = PreAllocateLoopDevices();
   if (!pre_allocate.ok()) {
@@ -2520,41 +2357,14 @@
   }
 
   ApexFileRepository& instance = ApexFileRepository::GetInstance();
-  Result<void> status =
-      instance.AddPreInstalledApex(gConfig->apex_built_in_dirs);
+  static const std::vector<std::string> kBootstrapApexDirs{
+      kApexPackageSystemDir, kApexPackageSystemExtDir, kApexPackageVendorDir};
+  Result<void> status = instance.AddPreInstalledApex(kBootstrapApexDirs);
   if (!status.ok()) {
     LOG(ERROR) << "Failed to collect APEX keys : " << status.error();
     return 1;
   }
 
-  // TODO(b/209491448) Remove this.
-  auto block_count = AddBlockApex(instance);
-  if (!block_count.ok()) {
-    LOG(ERROR) << status.error();
-    return 1;
-  }
-  pre_allocate = loop::PreAllocateLoopDevices(*block_count);
-  if (!pre_allocate.ok()) {
-    LOG(ERROR) << "Failed to pre-allocate loop devices for block apexes : "
-               << pre_allocate.error();
-  }
-
-  DeviceMapper& dm = DeviceMapper::Instance();
-  // Create empty dm device for each found APEX.
-  // This is a boot time optimization that makes use of the fact that user space
-  // paths will be created by ueventd before apexd is started, and hence
-  // reducing the time to activate APEXEs on /data.
-  // Note: since at this point we don't know which APEXes are updated, we are
-  // optimistically creating a verity device for all of them. Once boot
-  // finishes, apexd will clean up unused devices.
-  // TODO(b/192241176): move to apexd_verity.{h,cpp}
-  for (const auto& apex : instance.GetPreInstalledApexFiles()) {
-    const std::string& name = apex.get().GetManifest().name();
-    if (!dm.CreateEmptyDevice(name)) {
-      LOG(ERROR) << "Failed to create empty device " << name;
-    }
-  }
-
   // Create directories for APEX shared libraries.
   auto sharedlibs_apex_dir = CreateSharedLibsApexDir();
   if (!sharedlibs_apex_dir.ok()) {
@@ -2563,16 +2373,26 @@
   }
 
   // Find all bootstrap apexes
-  std::vector<ApexFileRef> bootstrap_apexes;
-  for (const auto& apex : instance.GetPreInstalledApexFiles()) {
-    if (IsBootstrapApex(apex.get())) {
-      bootstrap_apexes.push_back(apex);
+  std::vector<ApexFile> bootstrap_apexes;
+  for (const auto& dir : kBootstrapApexDirs) {
+    auto scan = ScanApexFiles(dir.c_str());
+    if (!scan.ok()) {
+      LOG(ERROR) << "Failed to scan APEX files in " << dir << " : "
+                 << scan.error();
+      return 1;
     }
+    std::copy_if(std::make_move_iterator(scan->begin()),
+                 std::make_move_iterator(scan->end()),
+                 std::back_inserter(bootstrap_apexes), IsBootstrapApex);
   }
 
   // Now activate bootstrap apexes.
-  auto ret =
-      ActivateApexPackages(bootstrap_apexes, ActivationMode::kBootstrapMode);
+  std::vector<ApexFileRef> bootstrap_apexes_ref;
+  std::transform(bootstrap_apexes.begin(), bootstrap_apexes.end(),
+                 std::back_inserter(bootstrap_apexes_ref),
+                 [](const auto& x) { return std::cref(x); });
+  auto ret = ActivateApexPackages(bootstrap_apexes_ref,
+                                  /* is_ota_chroot= */ false);
   if (!ret.ok()) {
     LOG(ERROR) << "Failed to activate bootstrap apex files : " << ret.error();
     return 1;
@@ -2624,13 +2444,6 @@
                << status.error();
     return;
   }
-
-  // TODO(b/209491448) Remove this.
-  if (auto block_status = AddBlockApex(instance); !block_status.ok()) {
-    LOG(ERROR) << status.error();
-    return;
-  }
-
   gMountedApexes.PopulateFromMounts(gConfig->active_apex_data_dir,
                                     gConfig->decompression_dir,
                                     gConfig->apex_hash_tree_dir);
@@ -2766,13 +2579,6 @@
   if (!result.ok()) {
     return result.error();
   }
-  auto ctx = GetfileconPath(apex_path);
-  if (!ctx.ok()) {
-    return ctx.error();
-  }
-  if (!StartsWith(*ctx, gConfig->active_apex_selinux_ctx)) {
-    return Error() << apex_path << " has wrong SELinux context " << *ctx;
-  }
   return std::move(*apex);
 }
 
@@ -2883,7 +2689,6 @@
     return Error() << "Failed to decompress CAPEX: " << return_apex.error();
   }
 
-  gChangedActiveApexes.insert(return_apex->GetManifest().name());
   /// Release compressed blocks in case decompression_dest is on f2fs-compressed
   // filesystem.
   ReleaseF2fsCompressedBlocks(decompression_dest);
@@ -2947,7 +2752,6 @@
 }
 
 void OnStart() {
-  ATRACE_NAME("OnStart");
   LOG(INFO) << "Marking APEXd as starting";
   auto time_started = boot_clock::now();
   if (!SetProperty(gConfig->apex_status_sysprop, kApexStatusStarting)) {
@@ -2996,7 +2800,6 @@
   const auto& all_apex = instance.AllApexFilesByName();
   // There can be multiple APEX packages with package name X. Determine which
   // one to activate.
-  // TODO(b/218672709): skip activation of sepolicy APEX during boot.
   auto activation_list = SelectApexForActivation(all_apex, instance);
 
   // Process compressed APEX, if any
@@ -3032,7 +2835,7 @@
 
   // TODO(b/179248390): activate parallelly if possible
   auto activate_status =
-      ActivateApexPackages(activation_list, ActivationMode::kBootMode);
+      ActivateApexPackages(activation_list, /* is_ota_chroot= */ false);
   if (!activate_status.ok()) {
     std::string error_message =
         StringPrintf("Failed to activate packages: %s",
@@ -3043,8 +2846,8 @@
     if (!revert_status.ok()) {
       LOG(ERROR) << "Failed to revert : " << revert_status.error();
     }
-    auto retry_status =
-        ActivateMissingApexes(activation_list, ActivationMode::kBootMode);
+    auto retry_status = ActivateMissingApexes(activation_list,
+                                              /* is_ota_chroot= */ false);
     if (!retry_status.ok()) {
       LOG(ERROR) << retry_status.error();
     }
@@ -3119,7 +2922,7 @@
   }
 
   std::vector<ApexFile> ret;
-  auto guard = android::base::make_scope_guard([&]() {
+  auto guard = android::base::make_scope_guard([&ret]() {
     for (const auto& apex : ret) {
       apexd_private::UnmountTempMount(apex);
     }
@@ -3129,10 +2932,15 @@
     if (!verified.ok()) {
       return verified.error();
     }
-    LOG(DEBUG) << verified->GetPath() << " is verified";
     ret.push_back(std::move(*verified));
   }
 
+  // Run preinstall, if necessary.
+  Result<void> preinstall_status = PreinstallPackages(ret);
+  if (!preinstall_status.ok()) {
+    return preinstall_status.error();
+  }
+
   if (has_rollback_enabled && is_rollback) {
     return Error() << "Cannot set session " << session_id << " as both a"
                    << " rollback and enabled for rollback.";
@@ -3148,9 +2956,6 @@
   session->SetHasRollbackEnabled(has_rollback_enabled);
   session->SetIsRollback(is_rollback);
   session->SetRollbackId(rollback_id);
-  for (const auto& apex_file : ret) {
-    session->AddApexName(apex_file.GetManifest().name());
-  }
   Result<void> commit_status =
       (*session).UpdateStateAndCommit(SessionState::VERIFIED);
   if (!commit_status.ok()) {
@@ -3162,14 +2967,6 @@
     ReleaseF2fsCompressedBlocks(apex.GetPath());
   }
 
-  // The scope guard above uses lambda that captures ret by reference.
-  // Unfortunately, for the capture by-reference, lifetime of the captured
-  // reference ends together with the lifetime of the closure object. This means
-  // that we need to manually call UnmountTempMount here.
-  for (const auto& apex : ret) {
-    apexd_private::UnmountTempMount(apex);
-  }
-
   return ret;
 }
 
@@ -3250,40 +3047,9 @@
   }
 }
 
-bool IsApexDevice(const std::string& dev_name) {
-  auto& repo = ApexFileRepository::GetInstance();
-  for (const auto& apex : repo.GetPreInstalledApexFiles()) {
-    if (StartsWith(dev_name, apex.get().GetManifest().name())) {
-      return true;
-    }
-  }
-  return false;
-}
-
-// TODO(b/192241176): move to apexd_verity.{h,cpp}.
-void DeleteUnusedVerityDevices() {
-  DeviceMapper& dm = DeviceMapper::Instance();
-  std::vector<DeviceMapper::DmBlockDevice> all_devices;
-  if (!dm.GetAvailableDevices(&all_devices)) {
-    LOG(WARNING) << "Failed to fetch dm devices";
-    return;
-  }
-  for (const auto& dev : all_devices) {
-    auto state = dm.GetState(dev.name());
-    if (state == DmDeviceState::SUSPENDED && IsApexDevice(dev.name())) {
-      LOG(INFO) << "Deleting unused dm device " << dev.name();
-      auto res = DeleteVerityDevice(dev.name(), /* deferred= */ false);
-      if (!res.ok()) {
-        LOG(WARNING) << res.error();
-      }
-    }
-  }
-}
-
 void BootCompletedCleanup() {
   RemoveInactiveDataApex();
   ApexSession::DeleteFinalizedSessions();
-  DeleteUnusedVerityDevices();
 }
 
 int UnmountAll() {
@@ -3353,9 +3119,9 @@
 }
 
 // Given a single new APEX incoming via OTA, should we allocate space for it?
-bool ShouldAllocateSpaceForDecompression(const std::string& new_apex_name,
-                                         const int64_t new_apex_version,
-                                         const ApexFileRepository& instance) {
+Result<bool> ShouldAllocateSpaceForDecompression(
+    const std::string& new_apex_name, const int64_t new_apex_version,
+    const ApexFileRepository& instance) {
   // An apex at most will have two versions on device: pre-installed and data.
 
   // Check if there is a pre-installed version for the new apex.
@@ -3394,24 +3160,6 @@
   return new_apex_version > data_version;
 }
 
-int64_t CalculateSizeForCompressedApex(
-    const std::vector<std::tuple<std::string, int64_t, int64_t>>&
-        compressed_apexes,
-    const ApexFileRepository& instance) {
-  int64_t result = 0;
-  for (const auto& compressed_apex : compressed_apexes) {
-    std::string module_name;
-    int64_t version_code;
-    int64_t decompressed_size;
-    std::tie(module_name, version_code, decompressed_size) = compressed_apex;
-    if (ShouldAllocateSpaceForDecompression(module_name, version_code,
-                                            instance)) {
-      result += decompressed_size;
-    }
-  }
-  return result;
-}
-
 void CollectApexInfoList(std::ostream& os,
                          const std::vector<ApexFile>& active_apexs,
                          const std::vector<ApexFile>& inactive_apexs) {
@@ -3428,22 +3176,18 @@
       preinstalled_module_path = *preinstalled_path;
     }
 
-    std::optional<int64_t> mtime =
-        instance.GetBlockApexLastUpdateSeconds(apex.GetManifest().name());
-    if (!mtime.has_value()) {
-      struct stat stat_buf;
-      if (stat(apex.GetPath().c_str(), &stat_buf) == 0) {
-        mtime.emplace(stat_buf.st_mtime);
-      } else {
-        PLOG(WARNING) << "Failed to stat " << apex.GetPath();
-      }
+    std::optional<int64_t> mtime;
+    struct stat stat_buf;
+    if (stat(apex.GetPath().c_str(), &stat_buf) == 0) {
+      mtime.emplace(stat_buf.st_mtime);
+    } else {
+      PLOG(WARNING) << "Failed to stat " << apex.GetPath();
     }
     com::android::apex::ApexInfo apex_info(
         apex.GetManifest().name(), apex.GetPath(), preinstalled_module_path,
         apex.GetManifest().version(), apex.GetManifest().versionname(),
-        instance.IsPreInstalledApex(apex), is_active, mtime,
-        apex.GetManifest().providesharedapexlibs());
-    apex_infos.emplace_back(std::move(apex_info));
+        instance.IsPreInstalledApex(apex), is_active, mtime);
+    apex_infos.emplace_back(apex_info);
   };
   for (const auto& apex : active_apexs) {
     convert_to_autogen(apex, /* is_active= */ true);
@@ -3503,73 +3247,6 @@
   return {};
 }
 
-// Adds block apexes if system property is set.
-Result<int> AddBlockApex(ApexFileRepository& instance) {
-  auto prop = GetProperty(gConfig->vm_payload_metadata_partition_prop, "");
-  if (prop != "") {
-    auto block_count = instance.AddBlockApex(prop);
-    if (!block_count.ok()) {
-      return Error() << "Failed to scan block APEX files: "
-                     << block_count.error();
-    }
-    return block_count;
-  } else {
-    LOG(INFO) << "No block apex metadata partition found, not adding block "
-              << "apexes";
-  }
-  return 0;
-}
-
-// When running in the VM mode, we follow the minimal start-up operations.
-// - CreateSharedLibsApexDir
-// - AddPreInstalledApex: note that CAPEXes are not supported in the VM mode
-// - AddBlockApex
-// - ActivateApexPackages
-// - setprop apexd.status: activated/ready
-int OnStartInVmMode() {
-  // waits for /dev/loop-control
-  loop::PreAllocateLoopDevices(0);
-
-  // Create directories for APEX shared libraries.
-  if (auto status = CreateSharedLibsApexDir(); !status.ok()) {
-    LOG(ERROR) << "Failed to create /apex/sharedlibs : " << status.ok();
-    return 1;
-  }
-
-  auto& instance = ApexFileRepository::GetInstance();
-
-  // Scan pre-installed apexes
-  if (auto status = instance.AddPreInstalledApex(gConfig->apex_built_in_dirs);
-      !status.ok()) {
-    LOG(ERROR) << "Failed to scan pre-installed APEX files: " << status.error();
-    return 1;
-  }
-
-  if (auto status = AddBlockApex(instance); !status.ok()) {
-    LOG(ERROR) << status.error();
-    return 1;
-  }
-
-  if (auto status = ActivateApexPackages(instance.GetPreInstalledApexFiles(),
-                                         ActivationMode::kVmMode);
-      !status.ok()) {
-    LOG(ERROR) << "Failed to activate apex packages : " << status.error();
-    return 1;
-  }
-  if (auto status = ActivateApexPackages(instance.GetDataApexFiles(),
-                                         ActivationMode::kVmMode);
-      !status.ok()) {
-    LOG(ERROR) << "Failed to activate apex packages : " << status.error();
-    return 1;
-  }
-
-  OnAllPackagesActivated(false);
-  // In VM mode, we don't run a separate --snapshotde mode.
-  // Instead, we mark apexd.status "ready" right now.
-  OnAllPackagesReady();
-  return 0;
-}
-
 int OnOtaChrootBootstrap() {
   auto& instance = ApexFileRepository::GetInstance();
   if (auto status = instance.AddPreInstalledApex(gConfig->apex_built_in_dirs);
@@ -3621,13 +3298,13 @@
     }
   }
 
-  auto activate_status =
-      ActivateApexPackages(activation_list, ActivationMode::kOtaChrootMode);
+  auto activate_status = ActivateApexPackages(activation_list,
+                                              /* is_ota_chroot= */ true);
   if (!activate_status.ok()) {
     LOG(ERROR) << "Failed to activate apex packages : "
                << activate_status.error();
-    auto retry_status =
-        ActivateMissingApexes(activation_list, ActivationMode::kOtaChrootMode);
+    auto retry_status = ActivateMissingApexes(activation_list,
+                                              /* is_ota_chroot= */ true);
     if (!retry_status.ok()) {
       LOG(ERROR) << retry_status.error();
     }
@@ -3673,8 +3350,8 @@
   return 0;
 }
 
-int ActivateFlattenedApex() {
-  LOG(INFO) << "ActivateFlattenedApex";
+int OnOtaChrootBootstrapFlattenedApex() {
+  LOG(INFO) << "OnOtaChrootBootstrapFlattenedApex";
 
   std::vector<com::android::apex::ApexInfo> apex_infos;
 
@@ -3728,8 +3405,7 @@
                               /* versionCode= */ manifest->version(),
                               /* versionName= */ manifest->versionname(),
                               /* isFactory= */ true, /* isActive= */ true,
-                              /* lastUpdateMillis= */ 0,
-                              /* provideSharedApexLibs= */ false);
+                              /* lastUpdateMillis= */ 0);
     }
   }
 
@@ -3988,9 +3664,7 @@
     // previously active APEX is still around. We need to create a new one.
     std::string old_new_id = GetPackageId(temp_apex->GetManifest()) + "_" +
                              std::to_string(*new_id_minor + 1);
-    auto res = ActivatePackageImpl(*cur_apex, old_new_id,
-                                   /* reuse_device= */ false);
-    if (!res.ok()) {
+    if (auto res = ActivatePackageImpl(*cur_apex, old_new_id); !res.ok()) {
       // At this point not much we can do... :(
       LOG(ERROR) << res.error();
     }
@@ -4010,10 +3684,8 @@
   }
 
   // 4. And activate new one.
-  auto activate_status = ActivatePackageImpl(*new_apex, new_id,
-                                             /* reuse_device= */ false);
-  if (!activate_status.ok()) {
-    return activate_status.error();
+  if (auto res = ActivatePackageImpl(*new_apex, new_id); !res.ok()) {
+    return res.error();
   }
 
   // Accept the install.
@@ -4037,14 +3709,5 @@
   return new_apex;
 }
 
-bool IsActiveApexChanged(const ApexFile& apex) {
-  return gChangedActiveApexes.find(apex.GetManifest().name()) !=
-         gChangedActiveApexes.end();
-}
-
-std::set<std::string>& GetChangedActiveApexesForTesting() {
-  return gChangedActiveApexes;
-}
-
 }  // namespace apex
 }  // namespace android
diff --git a/apexd/apexd.h b/apexd/apexd.h
index c30df4c..2465bde 100644
--- a/apexd/apexd.h
+++ b/apexd/apexd.h
@@ -17,14 +17,13 @@
 #ifndef ANDROID_APEXD_APEXD_H_
 #define ANDROID_APEXD_APEXD_H_
 
-#include <android-base/macros.h>
-#include <android-base/result.h>
-
 #include <ostream>
 #include <string>
 #include <vector>
 
-#include "apex_classpath.h"
+#include <android-base/macros.h>
+#include <android-base/result.h>
+
 #include "apex_constants.h"
 #include "apex_database.h"
 #include "apex_file.h"
@@ -48,27 +47,12 @@
   const char* ota_reserved_dir;
   const char* apex_hash_tree_dir;
   const char* staged_session_dir;
-  const char* metadata_sepolicy_staged_dir;
-  // Overrides the path to the "metadata" partition which is by default
-  // /dev/block/by-name/payload-metadata It should be a path pointing the first
-  // partition of the VM payload disk. So, realpath() of this path is checked if
-  // it has the suffix "1". For example, /test-dir/test-metadata-1 can be valid
-  // and the subsequent numbers should point APEX files.
-  const char* vm_payload_metadata_partition_prop;
-  const char* active_apex_selinux_ctx;
 };
 
 static const ApexdConfig kDefaultConfig = {
-    kApexStatusSysprop,
-    kApexPackageBuiltinDirs,
-    kActiveApexPackagesDataDir,
-    kApexDecompressedDir,
-    kOtaReservedDir,
-    kApexHashTreeDir,
+    kApexStatusSysprop,   kApexPackageBuiltinDirs, kActiveApexPackagesDataDir,
+    kApexDecompressedDir, kOtaReservedDir,         kApexHashTreeDir,
     kStagedSessionsDir,
-    kMetadataSepolicyStagedDir,
-    kVmPayloadMetadataPartitionProp,
-    "u:object_r:staging_data_file",
 };
 
 class CheckpointInterface;
@@ -83,6 +67,8 @@
 
 android::base::Result<void> PreinstallPackages(
     const std::vector<std::string>& paths) WARN_UNUSED;
+android::base::Result<void> PostinstallPackages(
+    const std::vector<std::string>& paths) WARN_UNUSED;
 
 android::base::Result<void> StagePackages(
     const std::vector<std::string>& tmpPaths) WARN_UNUSED;
@@ -93,11 +79,6 @@
     const int session_id, const std::vector<int>& child_session_ids,
     const bool has_rollback_enabled, const bool is_rollback,
     const int rollback_id) WARN_UNUSED;
-android::base::Result<std::vector<ApexFile>> GetStagedApexFiles(
-    const int session_id,
-    const std::vector<int>& child_session_ids) WARN_UNUSED;
-android::base::Result<ClassPath> MountAndDeriveClassPath(
-    const std::vector<ApexFile>&) WARN_UNUSED;
 android::base::Result<void> MarkStagedSessionReady(const int session_id)
     WARN_UNUSED;
 android::base::Result<void> MarkStagedSessionSuccessful(const int session_id)
@@ -191,13 +172,8 @@
 android::base::Result<void> RemountPackages();
 
 // Exposed for unit tests
-bool ShouldAllocateSpaceForDecompression(const std::string& new_apex_name,
-                                         int64_t new_apex_version,
-                                         const ApexFileRepository& instance);
-
-int64_t CalculateSizeForCompressedApex(
-    const std::vector<std::tuple<std::string, int64_t, int64_t>>&
-        compressed_apexes,
+android::base::Result<bool> ShouldAllocateSpaceForDecompression(
+    const std::string& new_apex_name, int64_t new_apex_version,
     const ApexFileRepository& instance);
 
 void CollectApexInfoList(std::ostream& os,
@@ -208,15 +184,12 @@
 android::base::Result<void> ReserveSpaceForCompressedApex(
     int64_t size, const std::string& dest_dir);
 
-// Entry point when running in the VM mode (with --vm arg)
-int OnStartInVmMode();
-
 // Activates apexes in otapreot_chroot environment.
 // TODO(b/172911822): support compressed apexes.
 int OnOtaChrootBootstrap();
 
-// Activates flattened apexes
-int ActivateFlattenedApex();
+// Activates flattened apexes in otapreopt_chroot environment.
+int OnOtaChrootBootstrapFlattenedApex();
 
 android::apex::MountedApexDatabase& GetApexDatabaseForTesting();
 
@@ -224,14 +197,6 @@
 // TODO(ioffe): add more documentation.
 android::base::Result<ApexFile> InstallPackage(const std::string& package_path);
 
-// Exposed for testing.
-android::base::Result<int> AddBlockApex(ApexFileRepository& instance);
-
-bool IsActiveApexChanged(const ApexFile& apex);
-
-// Shouldn't be used outside of apexd_test.cpp
-std::set<std::string>& GetChangedActiveApexesForTesting();
-
 }  // namespace apex
 }  // namespace android
 
diff --git a/apexd/apexd_checkpoint_vold.h b/apexd/apexd_checkpoint_vold.h
index 3e8ce7d..f547532 100644
--- a/apexd/apexd_checkpoint_vold.h
+++ b/apexd/apexd_checkpoint_vold.h
@@ -51,7 +51,7 @@
   VoldCheckpointInterface(VoldCheckpointInterface&& other) noexcept;
 
  private:
-  explicit VoldCheckpointInterface(sp<os::IVold>&& vold_service);
+  VoldCheckpointInterface(sp<os::IVold>&& vold_service);
 
   sp<os::IVold> vold_service_;
   bool supports_fs_checkpoints_;
diff --git a/apexd/apexd_lifecycle.cpp b/apexd/apexd_lifecycle.cpp
index b3fa1d0..41c1abe 100644
--- a/apexd/apexd_lifecycle.cpp
+++ b/apexd/apexd_lifecycle.cpp
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#include <chrono>
-#include <thread>
+#define LOG_TAG "apexd"
 
 #include "apexd_lifecycle.h"
 
@@ -24,8 +23,6 @@
 
 #include "apexd_utils.h"
 
-#define LOG_TAG "apexd"
-
 using android::base::GetProperty;
 using android::base::Result;
 using android::base::WaitForProperty;
@@ -43,35 +40,32 @@
   while (!boot_completed_) {
     // Check for change in either crashing property or sys.boot_completed
     // Wait for updatable_crashing property change for most of the time
-    // (arbitrary 10s), briefly check if boot has completed successfully,
+    // (arbitrary 30s), briefly check if boot has completed successfully,
     // if not continue waiting for updatable_crashing.
     // We use this strategy so that we can quickly detect if an updatable
     // process is crashing.
     if (WaitForProperty("sys.init.updatable_crashing", "1",
-                        std::chrono::seconds(10))) {
+                        std::chrono::seconds(30))) {
       auto name = GetProperty("sys.init.updatable_crashing_process_name", "");
       LOG(ERROR) << "Native process '" << (name.empty() ? "[unknown]" : name)
                  << "' is crashing. Attempting a revert";
       auto result = revert_fn(name, "");
       if (!result.ok()) {
         LOG(ERROR) << "Revert failed : " << result.error();
-        return WaitForBootStatus();
+        break;
       } else {
-        // This should never be reached, since revert_fn should've rebooted
-        // the device.
-        LOG(FATAL) << "Active sessions were reverted, but reboot wasn't "
-                      "triggered.";
+        // This should never be reached, since revert_fn should've rebooted a
+        // device. But if for some reason we end up here, let's reboot it
+        // manually.
+        LOG(ERROR) << "Active sessions were reverted, but reboot wasn't "
+                      "triggered. Rebooting manually";
+        Reboot();
+        return;
       }
     }
   }
 }
 
-void ApexdLifecycle::WaitForBootStatus() {
-  while (!boot_completed_) {
-    std::this_thread::sleep_for(std::chrono::seconds(1));
-  }
-}
-
 void ApexdLifecycle::MarkBootCompleted() { boot_completed_ = true; }
 
 }  // namespace apex
diff --git a/apexd/apexd_lifecycle.h b/apexd/apexd_lifecycle.h
index be99834..ecdef96 100644
--- a/apexd/apexd_lifecycle.h
+++ b/apexd/apexd_lifecycle.h
@@ -32,8 +32,6 @@
   ApexdLifecycle& operator=(const ApexdLifecycle&) = delete;
   ApexdLifecycle& operator=(ApexdLifecycle&&) = delete;
 
-  void WaitForBootStatus();
-
  public:
   static ApexdLifecycle& GetInstance() {
     static ApexdLifecycle instance;
diff --git a/apexd/apexd_loop.cpp b/apexd/apexd_loop.cpp
index 36521b0..08805ea 100644
--- a/apexd/apexd_loop.cpp
+++ b/apexd/apexd_loop.cpp
@@ -15,24 +15,18 @@
  */
 
 #define LOG_TAG "apexd"
-#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
 
 #include "apexd_loop.h"
 
-#include <array>
-#include <filesystem>
 #include <mutex>
-#include <string_view>
 
 #include <dirent.h>
 #include <fcntl.h>
-#include <libdm/dm.h>
 #include <linux/fs.h>
 #include <linux/loop.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/statfs.h>
-#include <sys/sysmacros.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -42,7 +36,6 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
-#include <utils/Trace.h>
 
 #include "apexd_utils.h"
 #include "string_log.h"
@@ -52,12 +45,21 @@
 using android::base::Error;
 using android::base::GetBoolProperty;
 using android::base::ParseUint;
-using android::base::ReadFileToString;
 using android::base::Result;
 using android::base::StartsWith;
 using android::base::StringPrintf;
 using android::base::unique_fd;
-using android::dm::DeviceMapper;
+
+#ifndef LOOP_CONFIGURE
+// These can be removed whenever we pull in the Linux v5.8 UAPI headers
+struct loop_config {
+  __u32 fd;
+  __u32 block_size;
+  struct loop_info64 info;
+  __u64 __reserved[8];
+};
+#define LOOP_CONFIGURE 0x4C0A
+#endif
 
 namespace android {
 namespace apex {
@@ -84,168 +86,6 @@
   }
 }
 
-Result<void> ConfigureScheduler(const std::string& device_path) {
-  if (!StartsWith(device_path, "/dev/")) {
-    return Error() << "Invalid argument " << device_path;
-  }
-
-  const std::string device_name = Basename(device_path);
-
-  const std::string sysfs_path =
-      StringPrintf("/sys/block/%s/queue/scheduler", device_name.c_str());
-  unique_fd sysfs_fd(open(sysfs_path.c_str(), O_RDWR | O_CLOEXEC));
-  if (sysfs_fd.get() == -1) {
-    return ErrnoError() << "Failed to open " << sysfs_path;
-  }
-
-  // Kernels before v4.1 only support 'noop'. Kernels [v4.1, v5.0) support
-  // 'noop' and 'none'. Kernels v5.0 and later only support 'none'.
-  static constexpr const std::array<std::string_view, 2> kNoScheduler = {
-      "none", "noop"};
-
-  int ret = 0;
-
-  for (const std::string_view& scheduler : kNoScheduler) {
-    ret = write(sysfs_fd.get(), scheduler.data(), scheduler.size());
-    if (ret > 0) {
-      break;
-    }
-  }
-
-  if (ret <= 0) {
-    return ErrnoError() << "Failed to write to " << sysfs_path;
-  }
-
-  return {};
-}
-
-// Return the parent device of a partition. Converts e.g. "sda26" into "sda".
-static Result<std::string> PartitionParent(const std::string& blockdev) {
-  if (blockdev.find('/') != std::string::npos) {
-    return Error() << "Invalid argument " << blockdev;
-  }
-  std::error_code ec;
-  for (const auto& entry :
-       std::filesystem::directory_iterator("/sys/class/block", ec)) {
-    const std::string path = entry.path().string();
-    if (std::filesystem::exists(
-            StringPrintf("%s/%s", path.c_str(), blockdev.c_str()))) {
-      return Basename(path);
-    }
-  }
-  return blockdev;
-}
-
-// Convert a major:minor pair into a block device name.
-static std::string BlockdevName(dev_t dev) {
-  std::error_code ec;
-  for (const auto& entry :
-       std::filesystem::directory_iterator("/dev/block", ec)) {
-    struct stat statbuf;
-    if (stat(entry.path().string().c_str(), &statbuf) < 0) {
-      continue;
-    }
-    if (dev == statbuf.st_rdev) {
-      return Basename(entry.path().string());
-    }
-  }
-  return {};
-}
-
-// For file `file_path`, retrieve the block device backing the filesystem on
-// which the file exists and return the queue depth of the block device. The
-// loop in this function may e.g. traverse the following hierarchy:
-// /dev/block/dm-9 (system-verity; dm-verity)
-// -> /dev/block/dm-1 (system_b; dm-linear)
-// -> /dev/sda26
-static Result<uint32_t> BlockDeviceQueueDepth(const std::string& file_path) {
-  struct stat statbuf;
-  int res = stat(file_path.c_str(), &statbuf);
-  if (res < 0) {
-    return ErrnoErrorf("stat({})", file_path.c_str());
-  }
-  std::string blockdev = "/dev/block/" + BlockdevName(statbuf.st_dev);
-  LOG(VERBOSE) << file_path << " -> " << blockdev;
-  if (blockdev.empty()) {
-    return Errorf("Failed to convert {}:{} (path {})", major(statbuf.st_dev),
-                  minor(statbuf.st_dev), file_path.c_str());
-  }
-  auto& dm = DeviceMapper::Instance();
-  for (;;) {
-    std::optional<std::string> child = dm.GetParentBlockDeviceByPath(blockdev);
-    if (!child) {
-      break;
-    }
-    LOG(VERBOSE) << blockdev << " -> " << *child;
-    blockdev = *child;
-  }
-  std::optional<std::string> maybe_blockdev =
-      android::dm::ExtractBlockDeviceName(blockdev);
-  if (!maybe_blockdev) {
-    return Error() << "Failed to remove /dev/block/ prefix from " << blockdev;
-  }
-  Result<std::string> maybe_parent = PartitionParent(*maybe_blockdev);
-  if (!maybe_parent.ok()) {
-    return Error() << "Failed to determine parent of " << *maybe_blockdev;
-  }
-  blockdev = *maybe_parent;
-  LOG(VERBOSE) << "Partition parent: " << blockdev;
-  const std::string nr_tags_path =
-      StringPrintf("/sys/class/block/%s/mq/0/nr_tags", blockdev.c_str());
-  std::string nr_tags;
-  if (!ReadFileToString(nr_tags_path, &nr_tags)) {
-    return Error() << "Failed to read " << nr_tags_path;
-  }
-  nr_tags = android::base::Trim(nr_tags);
-  LOG(VERBOSE) << file_path << " is backed by /dev/" << blockdev
-               << " and that block device supports queue depth " << nr_tags;
-  return strtol(nr_tags.c_str(), NULL, 0);
-}
-
-// Set 'nr_requests' of `loop_device_path` equal to the queue depth of
-// the block device backing `file_path`.
-Result<void> ConfigureQueueDepth(const std::string& loop_device_path,
-                                 const std::string& file_path) {
-  if (!StartsWith(loop_device_path, "/dev/")) {
-    return Error() << "Invalid argument " << loop_device_path;
-  }
-
-  const std::string loop_device_name = Basename(loop_device_path);
-
-  const std::string sysfs_path =
-      StringPrintf("/sys/block/%s/queue/nr_requests", loop_device_name.c_str());
-  std::string cur_nr_requests_str;
-  if (!ReadFileToString(sysfs_path, &cur_nr_requests_str)) {
-    return Error() << "Failed to read " << sysfs_path;
-  }
-  cur_nr_requests_str = android::base::Trim(cur_nr_requests_str);
-  uint32_t cur_nr_requests = 0;
-  if (!ParseUint(cur_nr_requests_str.c_str(), &cur_nr_requests)) {
-    return Error() << "Failed to parse " << cur_nr_requests_str;
-  }
-
-  unique_fd sysfs_fd(open(sysfs_path.c_str(), O_RDWR | O_CLOEXEC));
-  if (sysfs_fd.get() == -1) {
-    return ErrnoErrorf("Failed to open {}", sysfs_path);
-  }
-
-  const auto qd = BlockDeviceQueueDepth(file_path);
-  if (!qd.ok()) {
-    return qd.error();
-  }
-  if (*qd == cur_nr_requests) {
-    return {};
-  }
-  // Only report write failures if reducing the queue depth. Attempts to
-  // increase the queue depth are rejected by the kernel if no I/O scheduler
-  // is associated with the request queue.
-  if (!WriteStringToFd(StringPrintf("%u", *qd), sysfs_fd) &&
-      *qd < cur_nr_requests) {
-    return ErrnoErrorf("Failed to write {} to {}", *qd, sysfs_path);
-  }
-  return {};
-}
-
 Result<void> ConfigureReadAhead(const std::string& device_path) {
   CHECK(StartsWith(device_path, "/dev/"));
   std::string device_name = Basename(device_path);
@@ -319,7 +159,7 @@
 }
 
 Result<void> ConfigureLoopDevice(const int device_fd, const std::string& target,
-                                 const uint32_t image_offset,
+                                 const int32_t image_offset,
                                  const size_t image_size) {
   static bool use_loop_configure;
   static std::once_flag once_flag;
@@ -347,7 +187,6 @@
    * kernel driver will automatically enable Direct I/O when it sees that
    * condition is now met.
    */
-  bool use_buffered_io = false;
   unique_fd target_fd(open(target.c_str(), O_RDONLY | O_CLOEXEC | O_DIRECT));
   if (target_fd.get() == -1) {
     struct statfs stbuf;
@@ -360,7 +199,6 @@
       return Error(saved_errno) << "Failed to open " << target;
     }
     LOG(WARNING) << "Fallback to buffered I/O for " << target;
-    use_buffered_io = true;
     target_fd.reset(open(target.c_str(), O_RDONLY | O_CLOEXEC));
     if (target_fd.get() == -1) {
       return ErrnoError() << "Failed to open " << target;
@@ -378,12 +216,10 @@
   if (use_loop_configure) {
     struct loop_config config;
     memset(&config, 0, sizeof(config));
+    li.lo_flags |= LO_FLAGS_DIRECT_IO;
     config.fd = target_fd.get();
     config.info = li;
     config.block_size = 4096;
-    if (!use_buffered_io) {
-        li.lo_flags |= LO_FLAGS_DIRECT_IO;
-    }
 
     if (ioctl(device_fd, LOOP_CONFIGURE, &config) == -1) {
       return ErrnoError() << "Failed to LOOP_CONFIGURE";
@@ -442,13 +278,14 @@
   // a loop device for it. To work around this we keep polling for loop device
   // to be created until ueventd's cold boot sequence is done.
   // See comment on kLoopDeviceRetryAttempts.
+  unique_fd sysfs_fd;
   bool cold_boot_done = GetBoolProperty("ro.cold_boot_done", false);
   for (size_t i = 0; i != kLoopDeviceRetryAttempts; ++i) {
     if (!cold_boot_done) {
       cold_boot_done = GetBoolProperty("ro.cold_boot_done", false);
     }
     for (const auto& device : candidate_devices) {
-      unique_fd sysfs_fd(open(device.c_str(), O_RDWR | O_CLOEXEC));
+      sysfs_fd.reset(open(device.c_str(), O_RDWR | O_CLOEXEC));
       if (sysfs_fd.get() != -1) {
         return LoopbackDeviceUniqueFd(std::move(sysfs_fd), device);
       }
@@ -465,17 +302,15 @@
 }
 
 Result<LoopbackDeviceUniqueFd> CreateLoopDevice(const std::string& target,
-                                                uint32_t image_offset,
-                                                size_t image_size) {
-  ATRACE_NAME("CreateLoopDevice");
-
+                                                const int32_t image_offset,
+                                                const size_t image_size) {
   unique_fd ctl_fd(open("/dev/loop-control", O_RDWR | O_CLOEXEC));
   if (ctl_fd.get() == -1) {
     return ErrnoError() << "Failed to open loop-control";
   }
 
-  static std::mutex mtx;
-  std::lock_guard lock(mtx);
+  static std::mutex mlock;
+  std::lock_guard lock(mlock);
   int num = ioctl(ctl_fd.get(), LOOP_CTL_GET_FREE);
   if (num == -1) {
     return ErrnoError() << "Failed LOOP_CTL_GET_FREE";
@@ -487,39 +322,10 @@
   }
   CHECK_NE(loop_device->device_fd.get(), -1);
 
-  Result<void> configure_status = ConfigureLoopDevice(
+  Result<void> configureStatus = ConfigureLoopDevice(
       loop_device->device_fd.get(), target, image_offset, image_size);
-  if (!configure_status.ok()) {
-    return configure_status.error();
-  }
-
-  return loop_device;
-}
-
-Result<LoopbackDeviceUniqueFd> CreateAndConfigureLoopDevice(
-    const std::string& target, uint32_t image_offset, size_t image_size) {
-  ATRACE_NAME("CreateAndConfigureLoopDevice");
-  // Do minimal amount of work while holding a mutex. We need it because
-  // acquiring + configuring a loop device is not atomic. Ideally we should
-  // pre-acquire all the loop devices in advance, so that when we run APEX
-  // activation in-parallel, we can do it without holding any lock.
-  // Unfortunately, this will require some refactoring of how we manage loop
-  // devices, and probably some new loop-control ioctls, so for the time being
-  // we just limit the scope that requires locking.
-  auto loop_device = CreateLoopDevice(target, image_offset, image_size);
-  if (!loop_device.ok()) {
-    return loop_device.error();
-  }
-
-  Result<void> sched_status = ConfigureScheduler(loop_device->name);
-  if (!sched_status.ok()) {
-    LOG(WARNING) << "Configuring I/O scheduler failed: "
-                 << sched_status.error();
-  }
-
-  Result<void> qd_status = ConfigureQueueDepth(loop_device->name, target);
-  if (!qd_status.ok()) {
-    LOG(WARNING) << qd_status.error();
+  if (!configureStatus.ok()) {
+    return configureStatus.error();
   }
 
   Result<void> read_ahead_status = ConfigureReadAhead(loop_device->name);
diff --git a/apexd/apexd_loop.h b/apexd/apexd_loop.h
index 3c356d9..c727944 100644
--- a/apexd/apexd_loop.h
+++ b/apexd/apexd_loop.h
@@ -55,17 +55,13 @@
   int Get() { return device_fd.get(); }
 };
 
-android::base::Result<LoopbackDeviceUniqueFd> WaitForDevice(int num);
-
-android::base::Result<void> ConfigureQueueDepth(
-    const std::string& loop_device_path, const std::string& file_path);
-
 android::base::Result<void> ConfigureReadAhead(const std::string& device_path);
 
 android::base::Result<void> PreAllocateLoopDevices(size_t num);
 
-android::base::Result<LoopbackDeviceUniqueFd> CreateAndConfigureLoopDevice(
-    const std::string& target, uint32_t image_offset, size_t image_size);
+android::base::Result<LoopbackDeviceUniqueFd> CreateLoopDevice(
+    const std::string& target, const int32_t image_offset,
+    const size_t image_size);
 
 using DestroyLoopFn =
     std::function<void(const std::string&, const std::string&)>;
diff --git a/apexd/apexd_main.cpp b/apexd/apexd_main.cpp
index fb6b488..26d5732 100644
--- a/apexd/apexd_main.cpp
+++ b/apexd/apexd_main.cpp
@@ -25,6 +25,7 @@
 #include "apexd.h"
 #include "apexd_checkpoint_vold.h"
 #include "apexd_lifecycle.h"
+#include "apexd_prepostinstall.h"
 #include "apexservice.h"
 
 #include <android-base/properties.h>
@@ -32,6 +33,16 @@
 namespace {
 
 int HandleSubcommand(char** argv) {
+  if (strcmp("--pre-install", argv[1]) == 0) {
+    LOG(INFO) << "Preinstall subcommand detected";
+    return android::apex::RunPreInstall(argv);
+  }
+
+  if (strcmp("--post-install", argv[1]) == 0) {
+    LOG(INFO) << "Postinstall subcommand detected";
+    return android::apex::RunPostInstall(argv);
+  }
+
   if (strcmp("--bootstrap", argv[1]) == 0) {
     LOG(INFO) << "Bootstrap subcommand detected";
     return android::apex::OnBootstrap();
@@ -71,11 +82,6 @@
     return result;
   }
 
-  if (strcmp("--vm", argv[1]) == 0) {
-    LOG(INFO) << "VM subcommand detected";
-    return android::apex::OnStartInVmMode();
-  }
-
   LOG(ERROR) << "Unknown subcommand: " << argv[1];
   return 1;
 }
@@ -131,11 +137,7 @@
       // mark apexd as ready
       android::apex::OnAllPackagesReady();
     } else if (strcmp("--otachroot-bootstrap", argv[1]) == 0) {
-      LOG(INFO) << "OTA chroot bootstrap subcommand detected";
-      return android::apex::ActivateFlattenedApex();
-    } else if (strcmp("--bootstrap", argv[1]) == 0) {
-      LOG(INFO) << "Bootstrap subcommand detected";
-      return android::apex::ActivateFlattenedApex();
+      return android::apex::OnOtaChrootBootstrapFlattenedApex();
     }
     return 0;
   }
@@ -183,9 +185,6 @@
     lifecycle.WaitForBootStatus(android::apex::RevertActiveSessionsAndReboot);
   }
 
-  // Run cleanup routine before AllowServiceShutdown(), to prevent
-  // service_manager killing apexd in the middle of the cleanup.
-  android::apex::BootCompletedCleanup();
   android::apex::binder::AllowServiceShutdown();
 
   android::apex::binder::JoinThreadPool();
diff --git a/apexd/apexd_prepostinstall.cpp b/apexd/apexd_prepostinstall.cpp
new file mode 100644
index 0000000..51b60b4
--- /dev/null
+++ b/apexd/apexd_prepostinstall.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "apexd"
+
+#include "apexd_prepostinstall.h"
+
+#include <algorithm>
+#include <vector>
+
+#include <fcntl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android-base/scopeguard.h>
+#include <android-base/strings.h>
+
+#include "apex_database.h"
+#include "apex_file.h"
+#include "apex_manifest.h"
+#include "apexd.h"
+#include "apexd_private.h"
+#include "apexd_utils.h"
+#include "string_log.h"
+
+using android::base::Error;
+using android::base::Result;
+using ::apex::proto::ApexManifest;
+
+namespace android {
+namespace apex {
+
+namespace {
+
+using MountedApexData = MountedApexDatabase::MountedApexData;
+
+void CloseSTDDescriptors() {
+  // exec()d process will reopen STD* file descriptors as
+  // /dev/null
+  close(STDIN_FILENO);
+  close(STDOUT_FILENO);
+  close(STDERR_FILENO);
+}
+
+template <typename Fn>
+Result<void> StageFnInstall(const std::vector<ApexFile>& apexes,
+                            const std::vector<std::string>& mount_points, Fn fn,
+                            const char* arg, const char* name) {
+  // TODO(b/158470023): consider supporting a session with more than one
+  //   pre-install hook.
+  int hook_idx = -1;
+  for (size_t i = 0; i < apexes.size(); i++) {
+    if (!(apexes[i].GetManifest().*fn)().empty()) {
+      if (hook_idx != -1) {
+        return Error() << "Missing support for multiple " << name << " hooks";
+      }
+      hook_idx = i;
+    }
+  }
+  CHECK(hook_idx != -1);
+  LOG(VERBOSE) << name << " for " << apexes[hook_idx].GetPath();
+
+  // Create invocation args.
+  std::vector<std::string> args{
+      "/system/bin/apexd", arg,
+      mount_points[hook_idx]  // Make the APEX with hook first.
+  };
+  for (size_t i = 0; i < mount_points.size(); i++) {
+    if ((int)i != hook_idx) {
+      args.push_back(mount_points[i]);
+    }
+  }
+
+  return ForkAndRun(args);
+}
+
+template <typename Fn>
+int RunFnInstall(char** in_argv, Fn fn, const char* name) {
+  std::vector<std::string> activation_dirs;
+  auto preinstall_guard = android::base::make_scope_guard([&]() {
+    for (const std::string& active_point : activation_dirs) {
+      if (0 != rmdir(active_point.c_str())) {
+        PLOG(ERROR) << "Could not delete temporary active point "
+                    << active_point;
+      }
+    }
+  });
+
+  // 1) Unshare.
+  if (unshare(CLONE_NEWNS) != 0) {
+    PLOG(ERROR) << "Failed to unshare() for apex " << name;
+    _exit(200);
+  }
+
+  // 2) Make everything private, so that our (and hook's) changes do not
+  //    propagate.
+  if (mount(nullptr, "/", nullptr, MS_PRIVATE | MS_REC, nullptr) == -1) {
+    PLOG(ERROR) << "Failed to mount private.";
+    _exit(201);
+  }
+
+  std::string hook_path;
+  {
+    auto bind_fn = [&fn, name,
+                    activation_dirs](const std::string& mount_point) mutable {
+      std::string hook;
+      std::string active_point;
+      {
+        Result<ApexManifest> manifest_or =
+            ReadManifest(mount_point + "/" + kManifestFilenamePb);
+        if (!manifest_or.ok()) {
+          LOG(ERROR) << "Could not read manifest from  " << mount_point << "/"
+                     << kManifestFilenamePb << " for " << name << ": "
+                     << manifest_or.error();
+          // Fallback to Json manifest if present.
+          LOG(ERROR) << "Trying to find a JSON manifest";
+          manifest_or = ReadManifest(mount_point + "/" + kManifestFilenameJson);
+          if (!manifest_or.ok()) {
+            LOG(ERROR) << "Could not read manifest from  " << mount_point << "/"
+                       << kManifestFilenameJson << " for " << name << ": "
+                       << manifest_or.error();
+            _exit(202);
+          }
+        }
+        const auto& manifest = *manifest_or;
+        hook = (manifest.*fn)();
+        active_point = apexd_private::GetActiveMountPoint(manifest);
+        // Ensure there is an activation point. If not, create one and delete
+        // later.
+        if (0 == mkdir(active_point.c_str(), kMkdirMode)) {
+          activation_dirs.push_back(active_point);
+        } else if (errno != EEXIST) {
+          PLOG(ERROR) << "Unable to create mount point " << active_point;
+          _exit(205);
+        }
+      }
+
+      // 3) Activate the new apex.
+      Result<void> bind_status =
+          apexd_private::BindMount(active_point, mount_point);
+      if (!bind_status.ok()) {
+        LOG(ERROR) << "Failed to bind-mount " << mount_point << " to "
+                   << active_point << ": " << bind_status.error();
+        _exit(203);
+      }
+
+      return std::make_pair(active_point, hook);
+    };
+
+    // First/main APEX.
+    auto [active_point, hook] = bind_fn(in_argv[2]);
+    hook_path = active_point + "/" + hook;
+
+    for (size_t i = 3;; ++i) {
+      if (in_argv[i] == nullptr) {
+        break;
+      }
+      bind_fn(in_argv[i]);  // Ignore result, hook will be empty.
+    }
+  }
+
+  // 4) Run the hook.
+
+  // For now, just run sh. But this probably needs to run the new linker.
+  std::vector<std::string> args{
+      hook_path,
+  };
+  std::vector<const char*> argv;
+  argv.resize(args.size() + 1, nullptr);
+  std::transform(args.begin(), args.end(), argv.begin(),
+                 [](const std::string& in) { return in.c_str(); });
+
+  LOG(ERROR) << "execv of " << android::base::Join(args, " ");
+
+  // Close all file descriptors. They are coming from the caller, we do not
+  // want to pass them on across our fork/exec into a different domain.
+  CloseSTDDescriptors();
+
+  execv(argv[0], const_cast<char**>(argv.data()));
+  PLOG(ERROR) << "execv of " << android::base::Join(args, " ") << " failed";
+  _exit(204);
+}
+
+}  // namespace
+
+Result<void> StagePreInstall(const std::vector<ApexFile>& apexes,
+                             const std::vector<std::string>& mount_points) {
+  return StageFnInstall(apexes, mount_points, &ApexManifest::preinstallhook,
+                        "--pre-install", "pre-install");
+}
+
+int RunPreInstall(char** in_argv) {
+  return RunFnInstall(in_argv, &ApexManifest::preinstallhook, "pre-install");
+}
+
+Result<void> StagePostInstall(const std::vector<ApexFile>& apexes,
+                              const std::vector<std::string>& mount_points) {
+  return StageFnInstall(apexes, mount_points, &ApexManifest::postinstallhook,
+                        "--post-install", "post-install");
+}
+
+int RunPostInstall(char** in_argv) {
+  return RunFnInstall(in_argv, &ApexManifest::postinstallhook, "post-install");
+}
+
+}  // namespace apex
+}  // namespace android
diff --git a/apexd/apexd_prepostinstall.h b/apexd/apexd_prepostinstall.h
new file mode 100644
index 0000000..65125ba
--- /dev/null
+++ b/apexd/apexd_prepostinstall.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef ANDROID_APEXD_APEXD_PREPOSTINSTALL_H_
+#define ANDROID_APEXD_APEXD_PREPOSTINSTALL_H_
+
+#include <string>
+#include <vector>
+
+#include <android-base/result.h>
+
+namespace android {
+namespace apex {
+
+class ApexFile;
+
+// Forks into: apexd --pre-install <mount-point-of-apex-with-hook>
+// [<other-mount-points>] The caller must pass the temp mount point for each
+// apex file.
+android::base::Result<void> StagePreInstall(
+    const std::vector<ApexFile>& apexes,
+    const std::vector<std::string>& mount_points);
+int RunPreInstall(char** argv);
+
+// Forks into: apexd --post-install <mount-point-of-apex-with-hook>
+// [<other-mount-points>] The caller must pass the temp mount point for each
+// apex file.
+android::base::Result<void> StagePostInstall(
+    const std::vector<ApexFile>& apexes,
+    const std::vector<std::string>& mount_points);
+int RunPostInstall(char** argv);
+
+}  // namespace apex
+}  // namespace android
+
+#endif  // ANDROID_APEXD_APEXD_PREPOSTINSTALL_H_
diff --git a/apexd/apexd_rollback_utils.h b/apexd/apexd_rollback_utils.h
index b4dffd2..c7fa05e 100644
--- a/apexd/apexd_rollback_utils.h
+++ b/apexd/apexd_rollback_utils.h
@@ -41,7 +41,7 @@
       kCpPath,
       "-F", /* delete any existing destination file first
                       (--remove-destination) */
-      "--preserve=mode,ownership,timestamps,xattr", /* preserve properties */
+      "-p", /* preserve timestamps, ownership, and permissions */
       "-R", /* recurse into subdirectories (DEST must be a directory) */
       "-P", /* Do not follow symlinks [default] */
       "-d", /* don't dereference symlinks */
diff --git a/apexd/apexd_session_test.cpp b/apexd/apexd_session_test.cpp
index 7ee1eb1..50d0f85 100644
--- a/apexd/apexd_session_test.cpp
+++ b/apexd/apexd_session_test.cpp
@@ -39,7 +39,6 @@
 using android::apex::testing::IsOk;
 using android::base::Join;
 using android::base::make_scope_guard;
-using ::apex::proto::SessionState;
 
 // TODO(b/170329726): add unit tests for apexd_sessions.h
 
diff --git a/apexd/apexd_test.cpp b/apexd/apexd_test.cpp
index cc6d072..a3ebd03 100644
--- a/apexd/apexd_test.cpp
+++ b/apexd/apexd_test.cpp
@@ -14,36 +14,25 @@
  * limitations under the License.
  */
 
-#include "apexd.h"
+#include <string>
+#include <vector>
 
 #include <android-base/file.h>
 #include <android-base/properties.h>
-#include <android-base/result-gmock.h>
 #include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-#include <libdm/dm.h>
-#include <microdroid/metadata.h>
-#include <selinux/selinux.h>
-#include <sys/stat.h>
-
-#include <functional>
-#include <optional>
-#include <string>
-#include <tuple>
-#include <unordered_set>
-#include <vector>
 
 #include "apex_database.h"
-#include "apex_file.h"
 #include "apex_file_repository.h"
-#include "apex_manifest.pb.h"
+#include "apexd.h"
 #include "apexd_checkpoint.h"
-#include "apexd_loop.h"
 #include "apexd_session.h"
 #include "apexd_test_utils.h"
 #include "apexd_utils.h"
+
+#include "apex_manifest.pb.h"
 #include "com_android_apex.h"
 #include "gmock/gmock-matchers.h"
 
@@ -54,30 +43,19 @@
 
 using MountedApexData = MountedApexDatabase::MountedApexData;
 using android::apex::testing::ApexFileEq;
+using android::apex::testing::IsOk;
 using android::base::GetExecutableDirectory;
 using android::base::GetProperty;
-using android::base::Join;
 using android::base::make_scope_guard;
-using android::base::ReadFileToString;
-using android::base::ReadFully;
 using android::base::RemoveFileIfExists;
 using android::base::Result;
-using android::base::Split;
 using android::base::StringPrintf;
 using android::base::unique_fd;
 using android::base::WriteStringToFile;
-using android::base::testing::HasError;
-using android::base::testing::HasValue;
-using android::base::testing::Ok;
-using android::base::testing::WithMessage;
-using android::dm::DeviceMapper;
-using ::apex::proto::SessionState;
 using com::android::apex::testing::ApexInfoXmlEq;
 using ::testing::ByRef;
-using ::testing::Contains;
 using ::testing::HasSubstr;
 using ::testing::IsEmpty;
-using ::testing::Not;
 using ::testing::StartsWith;
 using ::testing::UnorderedElementsAre;
 using ::testing::UnorderedElementsAreArray;
@@ -124,11 +102,6 @@
 };
 
 static constexpr const char* kTestApexdStatusSysprop = "apexd.status.test";
-static constexpr const char* kTestVmPayloadMetadataPartitionProp =
-    "apexd.vm.payload_metadata_partition.test";
-
-static constexpr const char* kTestActiveApexSelinuxCtx =
-    "u:object_r:shell_data_file:s0";
 
 // A test fixture that provides frequently required temp directories for tests
 class ApexdUnitTest : public ::testing::Test {
@@ -140,21 +113,10 @@
     ota_reserved_dir_ = StringPrintf("%s/ota-reserved", td_.path);
     hash_tree_dir_ = StringPrintf("%s/apex-hash-tree", td_.path);
     staged_session_dir_ = StringPrintf("%s/staged-session-dir", td_.path);
-    metadata_sepolicy_staged_dir_ =
-        StringPrintf("%s/metadata-sepolicy-staged-dir", td_.path);
-
-    vm_payload_disk_ = StringPrintf("%s/vm-payload", td_.path);
-
-    config_ = {kTestApexdStatusSysprop,
-               {built_in_dir_},
-               data_dir_.c_str(),
-               decompression_dir_.c_str(),
-               ota_reserved_dir_.c_str(),
-               hash_tree_dir_.c_str(),
-               staged_session_dir_.c_str(),
-               metadata_sepolicy_staged_dir_.c_str(),
-               kTestVmPayloadMetadataPartitionProp,
-               kTestActiveApexSelinuxCtx};
+    config_ = {kTestApexdStatusSysprop,    {built_in_dir_},
+               data_dir_.c_str(),          decompression_dir_.c_str(),
+               ota_reserved_dir_.c_str(),  hash_tree_dir_.c_str(),
+               staged_session_dir_.c_str()};
   }
 
   const std::string& GetBuiltInDir() { return built_in_dir_; }
@@ -166,9 +128,6 @@
     return StringPrintf("%s/session_%d", staged_session_dir_.c_str(),
                         session_id);
   }
-  const std::string& GetMetadataSepolicyStagedDir() {
-    return metadata_sepolicy_staged_dir_;
-  }
 
   std::string GetRootDigest(const ApexFile& apex) {
     if (apex.IsCompressed()) {
@@ -197,29 +156,6 @@
     return StringPrintf("%s/%s", data_dir_.c_str(), target_name.c_str());
   }
 
-  std::string AddDecompressedApex(const std::string& apex_name) {
-    auto apex_file = ApexFile::Open(GetTestFile(apex_name));
-    CHECK(apex_file.ok());
-    std::string target_name =
-        apex_file->GetManifest().name() + "@" +
-        std::to_string(apex_file->GetManifest().version()) +
-        std::string(kDecompressedApexPackageSuffix);
-    fs::copy(GetTestFile(apex_name), decompression_dir_ + "/" + target_name);
-    return StringPrintf("%s/%s", decompression_dir_.c_str(),
-                        target_name.c_str());
-  }
-
-  std::string AddBlockApex(const std::string& apex_name,
-                           const std::string& public_key = "",
-                           const std::string& root_digest = "") {
-    auto apex_path = vm_payload_disk_ + "2";  // second partition
-    auto apex_file = GetTestFile(apex_name);
-    WriteMetadata(apex_file, public_key, root_digest);
-    // loop_devices_ will be disposed after each test
-    loop_devices_.push_back(*WriteBlockApex(apex_file, apex_path));
-    return apex_path;
-  }
-
   // Copies the compressed apex to |built_in_dir| and decompresses it to
   // |decompressed_dir| and then hard links to |target_dir|
   std::string PrepareCompressedApex(const std::string& name,
@@ -247,12 +183,6 @@
     return result;
   }
 
-  void SetBlockApexEnabled(bool enabled) {
-    // The first partition(1) is "metadata" partition
-    base::SetProperty(kTestVmPayloadMetadataPartitionProp,
-                      enabled ? (vm_payload_disk_ + "1") : "");
-  }
-
  protected:
   void SetUp() override {
     SetConfig(config_);
@@ -263,35 +193,11 @@
     ASSERT_EQ(mkdir(ota_reserved_dir_.c_str(), 0755), 0);
     ASSERT_EQ(mkdir(hash_tree_dir_.c_str(), 0755), 0);
     ASSERT_EQ(mkdir(staged_session_dir_.c_str(), 0755), 0);
-    ASSERT_EQ(mkdir(metadata_sepolicy_staged_dir_.c_str(), 0755), 0);
 
     DeleteDirContent(ApexSession::GetSessionsDir());
   }
-  void WriteMetadata(const std::string& apex_file,
-                     const std::string& public_key,
-                     const std::string& root_digest) {
-    android::microdroid::Metadata metadata;
 
-    auto apex = metadata.add_apexes();
-    apex->set_name("apex");
-    apex->set_public_key(public_key);
-    apex->set_root_digest(root_digest);
-    // In this test, block apeses are assumed as "factory".
-    // ApexFileRepositoryTestAddBlockApex tests non-factory cases.
-    apex->set_is_factory(true);
-
-    // The first partition is metadata partition
-    auto metadata_partition = vm_payload_disk_ + "1";
-    LOG(INFO) << "Writing metadata to " << metadata_partition;
-    std::ofstream out(metadata_partition);
-
-    android::microdroid::WriteMetadata(metadata, out);
-  }
-
-  void TearDown() override {
-    DeleteDirContent(ApexSession::GetSessionsDir());
-    SetBlockApexEnabled(false);
-  }
+  void TearDown() override { DeleteDirContent(ApexSession::GetSessionsDir()); }
 
  private:
   TemporaryDir td_;
@@ -300,12 +206,8 @@
   std::string decompression_dir_;
   std::string ota_reserved_dir_;
   std::string hash_tree_dir_;
-  std::string vm_payload_disk_;
-  std::string vm_payload_metadata_path_;
   std::string staged_session_dir_;
-  std::string metadata_sepolicy_staged_dir_;
   ApexdConfig config_;
-  std::vector<loop::LoopbackDeviceUniqueFd> loop_devices_;  // to be cleaned up
 };
 
 // Apex that does not have pre-installed version, does not get selected
@@ -316,7 +218,7 @@
       "com.android.apex.test.sharedlibs_generated.v1.libvX.apex"));
   auto& instance = ApexFileRepository::GetInstance();
   // Pre-installed data needs to be present so that we can add data apex
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({GetBuiltInDir()})));
 
   auto apexd_test_file = ApexFile::Open(AddDataApex("apex.apexd_test.apex"));
   auto shim_v1 = ApexFile::Open(AddDataApex("com.android.apex.cts.shim.apex"));
@@ -324,7 +226,7 @@
   // libs apex, but if they are the same version only the data apex will be.
   auto shared_lib_2 = ApexFile::Open(
       AddDataApex("com.android.apex.test.sharedlibs_generated.v1.libvX.apex"));
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
+  ASSERT_TRUE(IsOk(instance.AddDataApex(GetDataDir())));
 
   const auto all_apex = instance.AllApexFilesByName();
   // Pass a blank instance so that the data apex files are not considered
@@ -346,13 +248,13 @@
       ApexFile::Open(AddPreInstalledApex("apex.apexd_test_v2.apex"));
   AddPreInstalledApex("com.android.apex.cts.shim.apex");
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({GetBuiltInDir()})));
 
   TemporaryDir data_dir;
   AddDataApex("apex.apexd_test.apex");
   auto shim_v2 =
       ApexFile::Open(AddDataApex("com.android.apex.cts.shim.v2.apex"));
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
+  ASSERT_TRUE(IsOk(instance.AddDataApex(GetDataDir())));
 
   auto all_apex = instance.AllApexFilesByName();
   auto result = SelectApexForActivation(all_apex, instance);
@@ -369,12 +271,12 @@
   AddPreInstalledApex("com.android.apex.cts.shim.apex");
   // Initialize pre-installed APEX information
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({GetBuiltInDir()})));
 
   auto apexd_test_file = ApexFile::Open(AddDataApex("apex.apexd_test.apex"));
   auto shim_v1 = ApexFile::Open(AddDataApex("com.android.apex.cts.shim.apex"));
   // Initialize ApexFile repo
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
+  ASSERT_TRUE(IsOk(instance.AddDataApex(GetDataDir())));
 
   auto all_apex = instance.AllApexFilesByName();
   auto result = SelectApexForActivation(all_apex, instance);
@@ -391,12 +293,12 @@
       "com.android.apex.test.sharedlibs_generated.v1.libvX.apex"));
   // Initialize pre-installed APEX information
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({GetBuiltInDir()})));
 
   auto shared_lib_v2 = ApexFile::Open(
       AddDataApex("com.android.apex.test.sharedlibs_generated.v2.libvY.apex"));
   // Initialize data APEX information
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
+  ASSERT_TRUE(IsOk(instance.AddDataApex(GetDataDir())));
 
   auto all_apex = instance.AllApexFilesByName();
   auto result = SelectApexForActivation(all_apex, instance);
@@ -413,12 +315,12 @@
       "com.android.apex.test.sharedlibs_generated.v2.libvY.apex"));
   // Initialize pre-installed APEX information
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({GetBuiltInDir()})));
 
   auto shared_lib_v1 = ApexFile::Open(
       AddDataApex("com.android.apex.test.sharedlibs_generated.v1.libvX.apex"));
   // Initialize data APEX information
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
+  ASSERT_TRUE(IsOk(instance.AddDataApex(GetDataDir())));
 
   auto all_apex = instance.AllApexFilesByName();
   auto result = SelectApexForActivation(all_apex, instance);
@@ -427,7 +329,7 @@
   ASSERT_THAT(result, UnorderedElementsAre(ApexFileEq(ByRef(*shared_lib_v2))));
 }
 
-TEST_F(ApexdUnitTest, DISABLED_ProcessCompressedApex) {
+TEST_F(ApexdUnitTest, ProcessCompressedApex) {
   auto compressed_apex = ApexFile::Open(
       AddPreInstalledApex("com.android.apex.compressed.v1.capex"));
 
@@ -441,14 +343,16 @@
       kDecompressedApexPackageSuffix);
   // Assert output path is not empty
   auto exists = PathExists(decompressed_file_path);
-  ASSERT_THAT(exists, HasValue(true));
+  ASSERT_TRUE(IsOk(exists));
+  ASSERT_TRUE(*exists) << decompressed_file_path << " does not exist";
 
   // Assert that decompressed apex is same as original apex
   const std::string original_apex_file_path =
       GetTestFile("com.android.apex.compressed.v1_original.apex");
   auto comparison_result =
       CompareFiles(original_apex_file_path, decompressed_file_path);
-  ASSERT_THAT(comparison_result, HasValue(true));
+  ASSERT_TRUE(IsOk(comparison_result));
+  ASSERT_TRUE(*comparison_result);
 
   // Assert that return value contains decompressed APEX
   auto decompressed_apex = ApexFile::Open(decompressed_file_path);
@@ -479,35 +383,37 @@
 
   auto result =
       ValidateDecompressedApex(std::cref(*capex), std::cref(*decompressed_v1));
-  ASSERT_THAT(result, Ok());
+  ASSERT_TRUE(IsOk(result));
 
   // Validation checks version
   auto decompressed_v2 = ApexFile::Open(
       AddDataApex("com.android.apex.compressed.v2_original.apex"));
   result =
       ValidateDecompressedApex(std::cref(*capex), std::cref(*decompressed_v2));
+  ASSERT_FALSE(IsOk(result));
   ASSERT_THAT(
-      result,
-      HasError(WithMessage(HasSubstr(
-          "Compressed APEX has different version than decompressed APEX"))));
+      result.error().message(),
+      HasSubstr(
+          "Compressed APEX has different version than decompressed APEX"));
 
   // Validation check root digest
   auto decompressed_v1_different_digest = ApexFile::Open(AddDataApex(
       "com.android.apex.compressed.v1_different_digest_original.apex"));
   result = ValidateDecompressedApex(
       std::cref(*capex), std::cref(*decompressed_v1_different_digest));
-  ASSERT_THAT(result, HasError(WithMessage(HasSubstr(
-                          "does not match with expected root digest"))));
+  ASSERT_FALSE(IsOk(result));
+  ASSERT_THAT(result.error().message(),
+              HasSubstr("does not match with expected root digest"));
 
   // Validation checks key
   auto capex_different_key = ApexFile::Open(
       AddDataApex("com.android.apex.compressed_different_key.capex"));
   result = ValidateDecompressedApex(std::cref(*capex_different_key),
                                     std::cref(*decompressed_v1));
+  ASSERT_FALSE(IsOk(result));
   ASSERT_THAT(
-      result,
-      HasError(WithMessage(HasSubstr(
-          "Public key of compressed APEX is different than original"))));
+      result.error().message(),
+      HasSubstr("Public key of compressed APEX is different than original"));
 }
 
 TEST_F(ApexdUnitTest, ProcessCompressedApexCanBeCalledMultipleTimes) {
@@ -542,7 +448,7 @@
 }
 
 // Test behavior of ProcessCompressedApex when is_ota_chroot is true
-TEST_F(ApexdUnitTest, DISABLED_ProcessCompressedApexOnOtaChroot) {
+TEST_F(ApexdUnitTest, ProcessCompressedApexOnOtaChroot) {
   auto compressed_apex = ApexFile::Open(
       AddPreInstalledApex("com.android.apex.compressed.v1.capex"));
 
@@ -558,15 +464,16 @@
                    GetDecompressionDir().c_str(), kOtaApexPackageSuffix);
   // Assert output path is not empty
   auto exists = PathExists(decompressed_file_path);
-  ASSERT_THAT(exists, HasValue(true))
-      << decompressed_file_path << " does not exist";
+  ASSERT_TRUE(IsOk(exists));
+  ASSERT_TRUE(*exists) << decompressed_file_path << " does not exist";
 
   // Assert that decompressed apex is same as original apex
   const std::string original_apex_file_path =
       GetTestFile("com.android.apex.compressed.v1_original.apex");
   auto comparison_result =
       CompareFiles(original_apex_file_path, decompressed_file_path);
-  ASSERT_THAT(comparison_result, HasValue(true));
+  ASSERT_TRUE(IsOk(comparison_result));
+  ASSERT_TRUE(*comparison_result);
 
   // Assert that return value contains the decompressed APEX
   auto apex_file = ApexFile::Open(decompressed_file_path);
@@ -603,7 +510,7 @@
   ASSERT_EQ(return_value.size(), 1u);
 
   // Ota Apex should be cleaned up
-  ASSERT_THAT(PathExists(ota_apex_path), HasValue(false));
+  ASSERT_FALSE(*PathExists(ota_apex_path));
   ASSERT_EQ(return_value[0].GetPath(),
             StringPrintf("%s/com.android.apex.compressed@1%s",
                          GetDecompressionDir().c_str(),
@@ -612,12 +519,13 @@
 
 TEST_F(ApexdUnitTest, ShouldAllocateSpaceForDecompressionNewApex) {
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({GetBuiltInDir()})));
 
   // A brand new compressed APEX is being introduced: selected
-  bool result =
+  auto result =
       ShouldAllocateSpaceForDecompression("com.android.brand.new", 1, instance);
-  ASSERT_TRUE(result);
+  ASSERT_TRUE(IsOk(result));
+  ASSERT_TRUE(*result);
 }
 
 TEST_F(ApexdUnitTest,
@@ -625,30 +533,33 @@
   // Prepare fake pre-installed apex
   AddPreInstalledApex("apex.apexd_test.apex");
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({GetBuiltInDir()})));
 
   // An existing pre-installed APEX is now compressed in the OTA: selected
   {
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.test_package", 1, instance);
-    ASSERT_TRUE(result);
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_TRUE(*result);
   }
 
   // Even if there is a data apex (lower version)
   // Include data apex within calculation now
   AddDataApex("apex.apexd_test_v2.apex");
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
+  ASSERT_TRUE(IsOk(instance.AddDataApex(GetDataDir())));
   {
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.test_package", 3, instance);
-    ASSERT_TRUE(result);
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_TRUE(*result);
   }
 
   // But not if data apex has equal or higher version
   {
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.test_package", 2, instance);
-    ASSERT_FALSE(result);
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_FALSE(*result);
   }
 }
 
@@ -656,15 +567,16 @@
   // Prepare fake pre-installed apex
   PrepareCompressedApex("com.android.apex.compressed.v1.capex");
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
+  ASSERT_TRUE(IsOk(instance.AddPreInstalledApex({GetBuiltInDir()})));
+  ASSERT_TRUE(IsOk(instance.AddDataApex(GetDataDir())));
 
   {
     // New Compressed apex has higher version than decompressed data apex:
     // selected
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.compressed", 2, instance);
-    ASSERT_TRUE(result)
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_TRUE(*result)
         << "Higher version test with decompressed data returned false";
   }
 
@@ -672,79 +584,63 @@
   {
     // New Compressed apex has same version as decompressed data apex: not
     // selected
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.compressed", 1, instance);
-    ASSERT_FALSE(result)
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_FALSE(*result)
         << "Same version test with decompressed data returned true";
   }
 
   {
     // New Compressed apex has lower version than decompressed data apex:
     // selected
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.compressed", 0, instance);
-    ASSERT_TRUE(result)
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_TRUE(*result)
         << "lower version test with decompressed data returned false";
   }
 
   // Replace decompressed data apex with a higher version
   ApexFileRepository instance_new(GetDecompressionDir());
-  ASSERT_THAT(instance_new.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_TRUE(IsOk(instance_new.AddPreInstalledApex({GetBuiltInDir()})));
   TemporaryDir data_dir_new;
   fs::copy(GetTestFile("com.android.apex.compressed.v2_original.apex"),
            data_dir_new.path);
-  ASSERT_THAT(instance_new.AddDataApex(data_dir_new.path), Ok());
+  ASSERT_TRUE(IsOk(instance_new.AddDataApex(data_dir_new.path)));
 
   {
     // New Compressed apex has higher version as data apex: selected
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.compressed", 3, instance_new);
-    ASSERT_TRUE(result) << "Higher version test with new data returned false";
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_TRUE(*result) << "Higher version test with new data returned false";
   }
 
   {
     // New Compressed apex has same version as data apex: not selected
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.compressed", 2, instance_new);
-    ASSERT_FALSE(result) << "Same version test with new data returned true";
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_FALSE(*result) << "Same version test with new data returned true";
   }
 
   {
     // New Compressed apex has lower version than data apex: not selected
-    bool result = ShouldAllocateSpaceForDecompression(
+    auto result = ShouldAllocateSpaceForDecompression(
         "com.android.apex.compressed", 1, instance_new);
-    ASSERT_FALSE(result) << "lower version test with new data returned true";
+    ASSERT_TRUE(IsOk(result));
+    ASSERT_FALSE(*result) << "lower version test with new data returned true";
   }
 }
 
-TEST_F(ApexdUnitTest, CalculateSizeForCompressedApexEmptyList) {
-  ApexFileRepository instance;
-  int64_t result = CalculateSizeForCompressedApex({}, instance);
-  ASSERT_EQ(0LL, result);
-}
-
-TEST_F(ApexdUnitTest, CalculateSizeForCompressedApex) {
-  ApexFileRepository instance;
-  AddPreInstalledApex("com.android.apex.compressed.v1.capex");
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-
-  std::vector<std::tuple<std::string, int64_t, int64_t>> input = {
-      std::make_tuple("new_apex", 1, 1),
-      std::make_tuple("new_apex_2", 1, 2),
-      std::make_tuple("com.android.apex.compressed", 1, 4),  // will be ignored
-      std::make_tuple("com.android.apex.compressed", 2, 8),
-  };
-  int64_t result = CalculateSizeForCompressedApex(input, instance);
-  ASSERT_EQ(1 + 2 + 8LL, result);
-}
-
 TEST_F(ApexdUnitTest, ReserveSpaceForCompressedApexCreatesSingleFile) {
   TemporaryDir dest_dir;
   // Reserving space should create a single file in dest_dir with exact size
 
-  ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(100, dest_dir.path)));
   auto files = ReadDir(dest_dir.path, [](auto _) { return true; });
-  ASSERT_THAT(files, Ok());
+  ASSERT_TRUE(IsOk(files));
   ASSERT_EQ(files->size(), 1u);
   EXPECT_EQ(fs::file_size((*files)[0]), 100u);
 }
@@ -753,10 +649,10 @@
   TemporaryDir dest_dir;
   // Calling ReserveSpaceForCompressedApex multiple times should still create
   // a single file
-  ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
-  ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(100, dest_dir.path)));
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(100, dest_dir.path)));
   auto files = ReadDir(dest_dir.path, [](auto _) { return true; });
-  ASSERT_THAT(files, Ok());
+  ASSERT_TRUE(IsOk(files));
   ASSERT_EQ(files->size(), 1u);
   EXPECT_EQ(fs::file_size((*files)[0]), 100u);
 }
@@ -765,19 +661,18 @@
   TemporaryDir dest_dir;
 
   // Create a 100 byte file
-  ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(100, dest_dir.path)));
 
   // Should be able to shrink and grow the reserved space
-  ASSERT_THAT(ReserveSpaceForCompressedApex(1000, dest_dir.path), Ok());
-
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(1000, dest_dir.path)));
   auto files = ReadDir(dest_dir.path, [](auto _) { return true; });
-  ASSERT_THAT(files, Ok());
+  ASSERT_TRUE(IsOk(files));
   ASSERT_EQ(files->size(), 1u);
   EXPECT_EQ(fs::file_size((*files)[0]), 1000u);
 
-  ASSERT_THAT(ReserveSpaceForCompressedApex(10, dest_dir.path), Ok());
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(10, dest_dir.path)));
   files = ReadDir(dest_dir.path, [](auto _) { return true; });
-  ASSERT_THAT(files, Ok());
+  ASSERT_TRUE(IsOk(files));
   ASSERT_EQ(files->size(), 1u);
   EXPECT_EQ(fs::file_size((*files)[0]), 10u);
 }
@@ -786,15 +681,15 @@
   TemporaryDir dest_dir;
 
   // Create a file first
-  ASSERT_THAT(ReserveSpaceForCompressedApex(100, dest_dir.path), Ok());
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(100, dest_dir.path)));
   auto files = ReadDir(dest_dir.path, [](auto _) { return true; });
-  ASSERT_THAT(files, Ok());
+  ASSERT_TRUE(IsOk(files));
   ASSERT_EQ(files->size(), 1u);
 
   // Should delete the reserved file if size passed is 0
-  ASSERT_THAT(ReserveSpaceForCompressedApex(0, dest_dir.path), Ok());
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(0, dest_dir.path)));
   files = ReadDir(dest_dir.path, [](auto _) { return true; });
-  ASSERT_THAT(files, Ok());
+  ASSERT_TRUE(IsOk(files));
   ASSERT_EQ(files->size(), 0u);
 }
 
@@ -807,109 +702,38 @@
     // Create an ota_apex first
     fs::copy(GetTestFile("com.android.apex.compressed.v1_original.apex"),
              ota_apex_path);
-    ASSERT_THAT(PathExists(ota_apex_path), HasValue(true));
+    auto path_exists = PathExists(ota_apex_path);
+    ASSERT_TRUE(*path_exists);
   };
   create_ota_apex();
 
   // Should not delete the reserved file if size passed is negative
-  ASSERT_THAT(ReserveSpaceForCompressedApex(-1, dest_dir.path), Not(Ok()));
-  ASSERT_THAT(PathExists(ota_apex_path), HasValue(true));
+  ASSERT_FALSE(IsOk(ReserveSpaceForCompressedApex(-1, dest_dir.path)));
+  auto path_exists = PathExists(ota_apex_path);
+  ASSERT_TRUE(*path_exists);
 
   // Should delete the reserved file if size passed is 0
-  ASSERT_THAT(ReserveSpaceForCompressedApex(0, dest_dir.path), Ok());
-  ASSERT_THAT(PathExists(ota_apex_path), HasValue(false));
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(0, dest_dir.path)));
+  path_exists = PathExists(ota_apex_path);
+  ASSERT_FALSE(*path_exists);
 
   create_ota_apex();
   // Should delete the reserved file if size passed is positive
-  ASSERT_THAT(ReserveSpaceForCompressedApex(10, dest_dir.path), Ok());
-  ASSERT_THAT(PathExists(ota_apex_path), HasValue(false));
+  ASSERT_TRUE(IsOk(ReserveSpaceForCompressedApex(10, dest_dir.path)));
+  path_exists = PathExists(ota_apex_path);
+  ASSERT_FALSE(*path_exists);
 }
 
 TEST_F(ApexdUnitTest, ReserveSpaceForCompressedApexErrorForNegativeValue) {
   TemporaryDir dest_dir;
   // Should return error if negative value is passed
-  ASSERT_THAT(ReserveSpaceForCompressedApex(-1, dest_dir.path), Not(Ok()));
-}
-
-TEST_F(ApexdUnitTest, GetStagedApexFilesNoChild) {
-  // Create staged session
-  auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
-  apex_session->UpdateStateAndCommit(SessionState::STAGED);
-
-  // Query for its file
-  auto result = GetStagedApexFiles(123, {});
-
-  auto apex_file = ApexFile::Open(
-      StringPrintf("%s/apex.apexd_test.apex", GetStagedDir(123).c_str()));
-  ASSERT_THAT(result,
-              HasValue(UnorderedElementsAre(ApexFileEq(ByRef(*apex_file)))));
-}
-
-TEST_F(ApexdUnitTest, GetStagedApexFilesOnlyStaged) {
-  // Create staged session
-  auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
-  apex_session->UpdateStateAndCommit(SessionState::VERIFIED);
-
-  // Query for its file
-  auto result = GetStagedApexFiles(123, {});
-
-  ASSERT_THAT(
-      result,
-      HasError(WithMessage(HasSubstr("Session 123 is not in state STAGED"))));
-}
-
-TEST_F(ApexdUnitTest, GetStagedApexFilesChecksNumberOfApexFiles) {
-  // Create staged session
-  auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
-  apex_session->UpdateStateAndCommit(SessionState::STAGED);
-  auto staged_dir = GetStagedDir(123);
-
-  {
-    // Delete the staged apex file
-    DeleteDirContent(staged_dir);
-
-    // Query for its file
-    auto result = GetStagedApexFiles(123, {});
-    ASSERT_THAT(result, HasError(WithMessage(HasSubstr(
-                            "Expected exactly one APEX file in directory"))));
-    ASSERT_THAT(result, HasError(WithMessage(HasSubstr("Found: 0"))));
-  }
-  {
-    // Copy multiple files to staged dir
-    fs::copy(GetTestFile("apex.apexd_test.apex"), staged_dir);
-    fs::copy(GetTestFile("apex.apexd_test_v2.apex"), staged_dir);
-
-    // Query for its file
-    auto result = GetStagedApexFiles(123, {});
-    ASSERT_THAT(result, HasError(WithMessage(HasSubstr(
-                            "Expected exactly one APEX file in directory"))));
-    ASSERT_THAT(result, HasError(WithMessage(HasSubstr("Found: 2"))));
-  }
-}
-
-TEST_F(ApexdUnitTest, GetStagedApexFilesWithChildren) {
-  // Create staged session
-  auto parent_apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
-  parent_apex_session->UpdateStateAndCommit(SessionState::STAGED);
-  auto child_session_1 = CreateStagedSession("apex.apexd_test.apex", 124);
-  auto child_session_2 = CreateStagedSession("apex.apexd_test.apex", 125);
-
-  // Query for its file
-  auto result = GetStagedApexFiles(123, {124, 125});
-
-  ASSERT_THAT(result, Ok());
-  auto child_apex_file_1 = ApexFile::Open(
-      StringPrintf("%s/apex.apexd_test.apex", GetStagedDir(124).c_str()));
-  auto child_apex_file_2 = ApexFile::Open(
-      StringPrintf("%s/apex.apexd_test.apex", GetStagedDir(125).c_str()));
-  ASSERT_THAT(*result,
-              UnorderedElementsAre(ApexFileEq(ByRef(*child_apex_file_1)),
-                                   ApexFileEq(ByRef(*child_apex_file_2))));
+  ASSERT_FALSE(IsOk(ReserveSpaceForCompressedApex(-1, dest_dir.path)));
 }
 
 // A test fixture to use for tests that mount/unmount apexes.
 class ApexdMountTest : public ApexdUnitTest {
  public:
+
   void UnmountOnTearDown(const std::string& apex_file) {
     to_unmount_.push_back(apex_file);
   }
@@ -918,8 +742,7 @@
   void SetUp() final {
     ApexdUnitTest::SetUp();
     GetApexDatabaseForTesting().Reset();
-    GetChangedActiveApexesForTesting().clear();
-    ASSERT_THAT(SetUpApexTestEnvironment(), Ok());
+    ASSERT_TRUE(IsOk(SetUpApexTestEnvironment()));
   }
 
   void TearDown() final {
@@ -941,34 +764,35 @@
   std::string file_path = AddPreInstalledApex("apex.apexd_test.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret = InstallPackage(GetTestFile("apex.apexd_test.apex"));
-  ASSERT_THAT(
-      ret,
-      HasError(WithMessage(HasSubstr("does not support non-staged update"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(),
+              HasSubstr("does not support non-staged update"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsNoPreInstalledApex) {
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v1.apex"));
+  ASSERT_FALSE(IsOk(ret));
   ASSERT_THAT(
-      ret, HasError(WithMessage(HasSubstr(
-               "No active version found for package test.apex.rebootless"))));
+      ret.error().message(),
+      HasSubstr("No active version found for package test.apex.rebootless"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsNoHashtree) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret =
       InstallPackage(GetTestFile("test.rebootless_apex_v2_no_hashtree.apex"));
-  ASSERT_THAT(
-      ret,
-      HasError(WithMessage(HasSubstr(" does not have an embedded hash tree"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(),
+              HasSubstr(" does not have an embedded hash tree"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsNoActiveApex) {
@@ -976,158 +800,166 @@
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"));
+  ASSERT_FALSE(IsOk(ret));
   ASSERT_THAT(
-      ret, HasError(WithMessage(HasSubstr(
-               "No active version found for package test.apex.rebootless"))));
+      ret.error().message(),
+      HasSubstr("No active version found for package test.apex.rebootless"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsManifestMismatch) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret = InstallPackage(
       GetTestFile("test.rebootless_apex_manifest_mismatch.apex"));
+  ASSERT_FALSE(IsOk(ret));
   ASSERT_THAT(
-      ret,
-      HasError(WithMessage(HasSubstr(
-          "Manifest inside filesystem does not match manifest outside it"))));
+      ret.error().message(),
+      HasSubstr(
+          "Manifest inside filesystem does not match manifest outside it"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsCorrupted) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_corrupted.apex"));
-  ASSERT_THAT(ret,
-              HasError(WithMessage(HasSubstr("Can't verify /dev/block/dm-"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(), HasSubstr("Can't verify /dev/block/dm-"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsProvidesSharedLibs) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret = InstallPackage(
       GetTestFile("test.rebootless_apex_provides_sharedlibs.apex"));
-  ASSERT_THAT(ret, HasError(WithMessage(HasSubstr(" is a shared libs APEX"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(), HasSubstr(" is a shared libs APEX"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsProvidesNativeLibs) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret = InstallPackage(
       GetTestFile("test.rebootless_apex_provides_native_libs.apex"));
-  ASSERT_THAT(ret, HasError(WithMessage(HasSubstr(" provides native libs"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(), HasSubstr(" provides native libs"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsRequiresSharedApexLibs) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret = InstallPackage(
       GetTestFile("test.rebootless_apex_requires_shared_apex_libs.apex"));
-  ASSERT_THAT(ret,
-              HasError(WithMessage(HasSubstr(" requires shared apex libs"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(), HasSubstr(" requires shared apex libs"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsJniLibs) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_jni_libs.apex"));
-  ASSERT_THAT(ret, HasError(WithMessage(HasSubstr(" requires JNI libs"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(), HasSubstr(" requires JNI libs"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsAddRequiredNativeLib) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret =
       InstallPackage(GetTestFile("test.rebootless_apex_add_native_lib.apex"));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(),
+              HasSubstr("Set of native libs required by"));
   ASSERT_THAT(
-      ret, HasError(WithMessage(HasSubstr("Set of native libs required by"))));
-  ASSERT_THAT(ret,
-              HasError(WithMessage(HasSubstr(
-                  "differs from the one required by the currently active"))));
+      ret.error().message(),
+      HasSubstr("differs from the one required by the currently active"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsRemovesRequiredNativeLib) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret = InstallPackage(
       GetTestFile("test.rebootless_apex_remove_native_lib.apex"));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(),
+              HasSubstr("Set of native libs required by"));
   ASSERT_THAT(
-      ret, HasError(WithMessage(HasSubstr("Set of native libs required by"))));
-  ASSERT_THAT(ret,
-              HasError(WithMessage(HasSubstr(
-                  "differs from the one required by the currently active"))));
+      ret.error().message(),
+      HasSubstr("differs from the one required by the currently active"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsAppInApex) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret =
       InstallPackage(GetTestFile("test.rebootless_apex_app_in_apex.apex"));
-  ASSERT_THAT(ret, HasError(WithMessage(HasSubstr("contains app inside"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(), HasSubstr("contains app inside"));
 }
 
 TEST_F(ApexdMountTest, InstallPackageRejectsPrivAppInApex) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto ret =
       InstallPackage(GetTestFile("test.rebootless_apex_priv_app_in_apex.apex"));
-  ASSERT_THAT(ret,
-              HasError(WithMessage(HasSubstr("contains priv-app inside"))));
+  ASSERT_FALSE(IsOk(ret));
+  ASSERT_THAT(ret.error().message(), HasSubstr("contains priv-app inside"));
 }
 
 TEST_F(ApexdMountTest, InstallPackagePreInstallVersionActive) {
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   {
     auto active_apex = GetActivePackage("test.apex.rebootless");
-    ASSERT_THAT(active_apex, Ok());
+    ASSERT_TRUE(IsOk(active_apex));
     ASSERT_EQ(active_apex->GetPath(), file_path);
   }
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"));
-  ASSERT_THAT(ret, Ok());
+  ASSERT_TRUE(IsOk(ret));
   UnmountOnTearDown(ret->GetPath());
 
   auto apex_mounts = GetApexMounts();
@@ -1138,12 +970,12 @@
   // Check that /apex/test.apex.rebootless is a bind mount of
   // /apex/test.apex.rebootless@2.
   auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
-  ASSERT_THAT(manifest, Ok());
+  ASSERT_TRUE(IsOk(manifest));
   ASSERT_EQ(2u, manifest->version());
 
   // Check that GetActivePackage correctly reports upgraded version.
   auto active_apex = GetActivePackage("test.apex.rebootless");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
 
   // Check that pre-installed APEX is still around
@@ -1164,17 +996,17 @@
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   {
     auto active_apex = GetActivePackage("test.apex.rebootless");
-    ASSERT_THAT(active_apex, Ok());
+    ASSERT_TRUE(IsOk(active_apex));
     ASSERT_EQ(active_apex->GetPath(), file_path);
   }
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v1.apex"));
-  ASSERT_THAT(ret, Ok());
+  ASSERT_TRUE(IsOk(ret));
   UnmountOnTearDown(ret->GetPath());
 
   auto apex_mounts = GetApexMounts();
@@ -1184,7 +1016,7 @@
 
   // Check that GetActivePackage correctly reports upgraded version.
   auto active_apex = GetActivePackage("test.apex.rebootless");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
 
   // Check that pre-installed APEX is still around
@@ -1206,17 +1038,17 @@
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
   std::string file_path = AddDataApex("test.rebootless_apex_v1.apex");
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   {
     auto active_apex = GetActivePackage("test.apex.rebootless");
-    ASSERT_THAT(active_apex, Ok());
+    ASSERT_TRUE(IsOk(active_apex));
     ASSERT_EQ(active_apex->GetPath(), file_path);
   }
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"));
-  ASSERT_THAT(ret, Ok());
+  ASSERT_TRUE(IsOk(ret));
   UnmountOnTearDown(ret->GetPath());
 
   auto apex_mounts = GetApexMounts();
@@ -1227,12 +1059,12 @@
   // Check that /apex/test.apex.rebootless is a bind mount of
   // /apex/test.apex.rebootless@2.
   auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
-  ASSERT_THAT(manifest, Ok());
+  ASSERT_TRUE(IsOk(manifest));
   ASSERT_EQ(2u, manifest->version());
 
   // Check that GetActivePackage correctly reports upgraded version.
   auto active_apex = GetActivePackage("test.apex.rebootless");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
 
   // Check that previously active APEX was deleted.
@@ -1255,17 +1087,17 @@
 
   std::string file_path = AddDataApex("test.rebootless_apex_v1.apex",
                                       "test.apex.rebootless@1_1.apex");
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   {
     auto active_apex = GetActivePackage("test.apex.rebootless");
-    ASSERT_THAT(active_apex, Ok());
+    ASSERT_TRUE(IsOk(active_apex));
     ASSERT_EQ(active_apex->GetPath(), file_path);
   }
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v1.apex"));
-  ASSERT_THAT(ret, Ok());
+  ASSERT_TRUE(IsOk(ret));
   UnmountOnTearDown(ret->GetPath());
 
   auto apex_mounts = GetApexMounts();
@@ -1276,12 +1108,12 @@
   // Check that /apex/test.apex.rebootless is a bind mount of
   // /apex/test.apex.rebootless@2.
   auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
-  ASSERT_THAT(manifest, Ok());
+  ASSERT_TRUE(IsOk(manifest));
   ASSERT_EQ(1u, manifest->version());
 
   // Check that GetActivePackage correctly reports upgraded version.
   auto active_apex = GetActivePackage("test.apex.rebootless");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
 
   // Check that we correctly resolved active apex path collision.
@@ -1307,17 +1139,17 @@
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
   std::string file_path = AddDataApex("test.rebootless_apex_v2.apex");
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   {
     auto active_apex = GetActivePackage("test.apex.rebootless");
-    ASSERT_THAT(active_apex, Ok());
+    ASSERT_TRUE(IsOk(active_apex));
     ASSERT_EQ(active_apex->GetPath(), file_path);
   }
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"));
-  ASSERT_THAT(ret, Ok());
+  ASSERT_TRUE(IsOk(ret));
   UnmountOnTearDown(ret->GetPath());
 
   auto apex_mounts = GetApexMounts();
@@ -1328,12 +1160,12 @@
   // Check that /apex/test.apex.rebootless is a bind mount of
   // /apex/test.apex.rebootless@2.
   auto manifest = ReadManifest("/apex/test.apex.rebootless/apex_manifest.pb");
-  ASSERT_THAT(manifest, Ok());
+  ASSERT_TRUE(IsOk(manifest));
   ASSERT_EQ(2u, manifest->version());
 
   // Check that GetActivePackage correctly reports upgraded version.
   auto active_apex = GetActivePackage("test.apex.rebootless");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), ret->GetPath());
 
   // Check that previously active APEX was deleted.
@@ -1354,12 +1186,12 @@
   std::string file_path = AddPreInstalledApex("test.rebootless_apex_v1.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   {
     auto active_apex = GetActivePackage("test.apex.rebootless");
-    ASSERT_THAT(active_apex, Ok());
+    ASSERT_TRUE(IsOk(active_apex));
     ASSERT_EQ(active_apex->GetPath(), file_path);
   }
 
@@ -1368,7 +1200,7 @@
   ASSERT_NE(-1, fd.get());
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"));
-  ASSERT_THAT(ret, Not(Ok()));
+  ASSERT_FALSE(IsOk(ret));
 
   auto apex_mounts = GetApexMounts();
   ASSERT_THAT(apex_mounts,
@@ -1377,7 +1209,7 @@
 
   // Check that GetActivePackage correctly reports upgraded version.
   auto active_apex = GetActivePackage("test.apex.rebootless");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), file_path);
 
   // Check that old APEX is still around
@@ -1399,12 +1231,12 @@
 
   std::string file_path = AddDataApex("test.rebootless_apex_v1.apex");
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   {
     auto active_apex = GetActivePackage("test.apex.rebootless");
-    ASSERT_THAT(active_apex, Ok());
+    ASSERT_TRUE(IsOk(active_apex));
     ASSERT_EQ(active_apex->GetPath(), file_path);
   }
 
@@ -1413,7 +1245,7 @@
   ASSERT_NE(-1, fd.get());
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"));
-  ASSERT_THAT(ret, Not(Ok()));
+  ASSERT_FALSE(IsOk(ret));
 
   auto apex_mounts = GetApexMounts();
   ASSERT_THAT(apex_mounts,
@@ -1422,7 +1254,7 @@
 
   // Check that GetActivePackage correctly reports old apex.
   auto active_apex = GetActivePackage("test.apex.rebootless");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), file_path);
 
   // Check that old APEX is still around
@@ -1445,8 +1277,8 @@
 
   UnmountOnTearDown(apex_1);
   UnmountOnTearDown(apex_2);
-  ASSERT_THAT(ActivatePackage(apex_1), Ok());
-  ASSERT_THAT(ActivatePackage(apex_2), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(apex_1)));
+  ASSERT_TRUE(IsOk(ActivatePackage(apex_2)));
 
   // Call OnAllPackagesActivated to create /apex/apex-info-list.xml.
   OnAllPackagesActivated(/* is_bootstrap= */ false);
@@ -1454,7 +1286,7 @@
   ASSERT_EQ(0, access("/apex/apex-info-list.xml", F_OK));
 
   auto ret = InstallPackage(GetTestFile("test.rebootless_apex_v2.apex"));
-  ASSERT_THAT(ret, Ok());
+  ASSERT_TRUE(IsOk(ret));
   UnmountOnTearDown(ret->GetPath());
 
   ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
@@ -1466,81 +1298,33 @@
       /* modulePath= */ apex_1,
       /* preinstalledModulePath= */ apex_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package",
       /* modulePath= */ apex_2, /* preinstalledModulePath= */ apex_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_2));
   auto apex_info_xml_3 = com::android::apex::ApexInfo(
       /* moduleName= */ "test.apex.rebootless",
       /* modulePath= */ ret->GetPath(),
       /* preinstalledModulePath= */ apex_1,
       /* versionCode= */ 2, /* versionName= */ "2",
-      /* isFactory= */ false, /* isActive= */ true, GetMTime(ret->GetPath()),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ false, /* isActive= */ true, GetMTime(ret->GetPath()));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
                                    ApexInfoXmlEq(apex_info_xml_2),
                                    ApexInfoXmlEq(apex_info_xml_3)));
 }
 
-TEST_F(ApexdMountTest, ActivatePackageBannedName) {
-  auto status = ActivatePackage(GetTestFile("sharedlibs.apex"));
-  ASSERT_THAT(status,
-              HasError(WithMessage("Package name sharedlibs is not allowed.")));
-}
-
-TEST_F(ApexdMountTest, ActivatePackageNoCode) {
-  std::string file_path = AddPreInstalledApex("apex.apexd_test_nocode.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
-  UnmountOnTearDown(file_path);
-
-  std::string mountinfo;
-  ASSERT_TRUE(ReadFileToString("/proc/self/mountinfo", &mountinfo));
-  bool found_apex_mountpoint = false;
-  for (const auto& line : Split(mountinfo, "\n")) {
-    std::vector<std::string> tokens = Split(line, " ");
-    // line format:
-    // mnt_id parent_mnt_id major:minor source target option propagation_type
-    // ex) 33 260:19 / /apex rw,nosuid,nodev -
-    if (tokens.size() >= 7 &&
-        tokens[4] == "/apex/com.android.apex.test_package@1") {
-      found_apex_mountpoint = true;
-      // Make sure that option contains noexec
-      std::vector<std::string> options = Split(tokens[5], ",");
-      EXPECT_THAT(options, Contains("noexec"));
-      break;
-    }
-  }
-  EXPECT_TRUE(found_apex_mountpoint);
-}
-
-TEST_F(ApexdMountTest, ActivatePackageManifestMissmatch) {
-  std::string file_path =
-      AddPreInstalledApex("apex.apexd_test_manifest_mismatch.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  auto status = ActivatePackage(file_path);
-  ASSERT_THAT(
-      status,
-      HasError(WithMessage(HasSubstr(
-          "Manifest inside filesystem does not match manifest outside it"))));
-}
-
 TEST_F(ApexdMountTest, ActivatePackage) {
   std::string file_path = AddPreInstalledApex("apex.apexd_test.apex");
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
   UnmountOnTearDown(file_path);
 
   auto active_apex = GetActivePackage("com.android.apex.test_package");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), file_path);
 
   auto apex_mounts = GetApexMounts();
@@ -1548,235 +1332,13 @@
               UnorderedElementsAre("/apex/com.android.apex.test_package",
                                    "/apex/com.android.apex.test_package@1"));
 
-  ASSERT_THAT(DeactivatePackage(file_path), Ok());
-  ASSERT_THAT(GetActivePackage("com.android.apex.test_package"), Not(Ok()));
+  ASSERT_TRUE(IsOk(DeactivatePackage(file_path)));
+  ASSERT_FALSE(IsOk(GetActivePackage("com.android.apex.test_package")));
 
   auto new_apex_mounts = GetApexMounts();
   ASSERT_EQ(new_apex_mounts.size(), 0u);
 }
 
-TEST_F(ApexdMountTest, ActivatePackageShowsUpInMountedApexDatabase) {
-  std::string file_path = AddPreInstalledApex("apex.apexd_test.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
-  UnmountOnTearDown(file_path);
-
-  auto active_apex = GetActivePackage("com.android.apex.test_package");
-  ASSERT_THAT(active_apex, Ok());
-  ASSERT_EQ(active_apex->GetPath(), file_path);
-
-  auto apex_mounts = GetApexMounts();
-  ASSERT_THAT(apex_mounts,
-              UnorderedElementsAre("/apex/com.android.apex.test_package",
-                                   "/apex/com.android.apex.test_package@1"));
-
-  // Check that mounted apex database contains information about our APEX.
-  auto& db = GetApexDatabaseForTesting();
-  std::optional<MountedApexData> mounted_apex;
-  db.ForallMountedApexes("com.android.apex.test_package",
-                         [&](const MountedApexData& d, bool active) {
-                           if (active) {
-                             mounted_apex.emplace(d);
-                           }
-                         });
-  ASSERT_TRUE(mounted_apex)
-      << "Haven't found com.android.apex.test_package in the database of "
-      << "mounted apexes";
-}
-
-TEST_F(ApexdMountTest, ActivatePackageNoHashtree) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  std::string file_path = AddDataApex("apex.apexd_test_no_hashtree.apex");
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
-  UnmountOnTearDown(file_path);
-
-  // Check that hashtree was generated
-  std::string hashtree_path =
-      GetHashTreeDir() + "/com.android.apex.test_package@1";
-  ASSERT_EQ(0, access(hashtree_path.c_str(), F_OK));
-
-  // Check that block device can be read.
-  auto block_device = GetBlockDeviceForApex("com.android.apex.test_package@1");
-  ASSERT_THAT(block_device, Ok());
-  ASSERT_THAT(ReadDevice(*block_device), Ok());
-}
-
-TEST_F(ApexdMountTest, ActivatePackageNoHashtreeShowsUpInMountedDatabase) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  std::string file_path = AddDataApex("apex.apexd_test_no_hashtree.apex");
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
-  UnmountOnTearDown(file_path);
-
-  // Get loop devices that were used to mount APEX.
-  auto children = ListChildLoopDevices("com.android.apex.test_package@1");
-  ASSERT_THAT(children, Ok());
-  ASSERT_EQ(2u, children->size())
-      << "Unexpected number of children: " << Join(*children, ",");
-
-  auto& db = GetApexDatabaseForTesting();
-  std::optional<MountedApexData> mounted_apex;
-  db.ForallMountedApexes("com.android.apex.test_package",
-                         [&](const MountedApexData& d, bool active) {
-                           if (active) {
-                             mounted_apex.emplace(d);
-                           }
-                         });
-  ASSERT_TRUE(mounted_apex)
-      << "Haven't found com.android.apex.test_package@1  in the database of "
-      << "mounted apexes";
-
-  ASSERT_EQ(file_path, mounted_apex->full_path);
-  ASSERT_EQ("/apex/com.android.apex.test_package@1", mounted_apex->mount_point);
-  ASSERT_EQ("com.android.apex.test_package@1", mounted_apex->device_name);
-  // For loops we only check that both loop_name and hashtree_loop_name are
-  // children of the top device mapper device.
-  ASSERT_THAT(*children, Contains(mounted_apex->loop_name));
-  ASSERT_THAT(*children, Contains(mounted_apex->hashtree_loop_name));
-  ASSERT_NE(mounted_apex->loop_name, mounted_apex->hashtree_loop_name);
-}
-
-TEST_F(ApexdMountTest, DeactivePackageFreesLoopDevices) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  std::string file_path = AddDataApex("apex.apexd_test_no_hashtree.apex");
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
-  UnmountOnTearDown(file_path);
-
-  // Get loop devices that were used to mount APEX.
-  auto children = ListChildLoopDevices("com.android.apex.test_package@1");
-  ASSERT_THAT(children, Ok());
-  ASSERT_EQ(2u, children->size())
-      << "Unexpected number of children: " << Join(*children, ",");
-
-  ASSERT_THAT(DeactivatePackage(file_path), Ok());
-  for (const auto& loop : *children) {
-    struct loop_info li;
-    unique_fd fd(TEMP_FAILURE_RETRY(open(loop.c_str(), O_RDWR | O_CLOEXEC)));
-    EXPECT_NE(-1, fd.get())
-        << "Failed to open " << loop << " : " << strerror(errno);
-    EXPECT_EQ(-1, ioctl(fd.get(), LOOP_GET_STATUS, &li))
-        << loop << " is still alive";
-    EXPECT_EQ(ENXIO, errno) << "Unexpected errno : " << strerror(errno);
-  }
-}
-
-TEST_F(ApexdMountTest, NoHashtreeApexNewSessionDoesNotImpactActivePackage) {
-  MockCheckpointInterface checkpoint_interface;
-  checkpoint_interface.SetSupportsCheckpoint(true);
-  InitializeVold(&checkpoint_interface);
-
-  AddPreInstalledApex("apex.apexd_test_no_hashtree.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  std::string file_path = AddDataApex("apex.apexd_test_no_hashtree.apex");
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
-  UnmountOnTearDown(file_path);
-
-  ASSERT_THAT(CreateStagedSession("apex.apexd_test_no_hashtree_2.apex", 239),
-              Ok());
-  auto status =
-      SubmitStagedSession(239, {}, /* has_rollback_enabled= */ false,
-                          /* is_rollback= */ false, /* rollback_id= */ -1);
-  ASSERT_THAT(status, Ok());
-
-  // Check that new hashtree file was created.
-  {
-    std::string hashtree_path =
-        GetHashTreeDir() + "/com.android.apex.test_package@1.new";
-    ASSERT_THAT(PathExists(hashtree_path), HasValue(true))
-        << hashtree_path << " does not exist";
-  }
-  // Check that active hashtree is still there.
-  {
-    std::string hashtree_path =
-        GetHashTreeDir() + "/com.android.apex.test_package@1";
-    ASSERT_THAT(PathExists(hashtree_path), HasValue(true))
-        << hashtree_path << " does not exist";
-  }
-
-  // Check that block device of active APEX can still be read.
-  auto block_device = GetBlockDeviceForApex("com.android.apex.test_package@1");
-  ASSERT_THAT(block_device, Ok());
-  ASSERT_THAT(ReadDevice(*block_device), Ok());
-}
-
-TEST_F(ApexdMountTest, NoHashtreeApexStagePackagesMovesHashtree) {
-  MockCheckpointInterface checkpoint_interface;
-  checkpoint_interface.SetSupportsCheckpoint(true);
-  InitializeVold(&checkpoint_interface);
-
-  AddPreInstalledApex("apex.apexd_test_no_hashtree.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  auto read_fn = [](const std::string& path) -> std::vector<uint8_t> {
-    static constexpr size_t kBufSize = 4096;
-    std::vector<uint8_t> buffer(kBufSize);
-    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
-    if (fd.get() == -1) {
-      PLOG(ERROR) << "Failed to open " << path;
-      ADD_FAILURE();
-      return buffer;
-    }
-    if (!ReadFully(fd.get(), buffer.data(), kBufSize)) {
-      PLOG(ERROR) << "Failed to read " << path;
-      ADD_FAILURE();
-    }
-    return buffer;
-  };
-
-  ASSERT_THAT(CreateStagedSession("apex.apexd_test_no_hashtree_2.apex", 37),
-              Ok());
-  auto status =
-      SubmitStagedSession(37, {}, /* has_rollback_enabled= */ false,
-                          /* is_rollback= */ false, /* rollback_id= */ -1);
-  ASSERT_THAT(status, Ok());
-  auto staged_apex = std::move((*status)[0]);
-
-  // Check that new hashtree file was created.
-  std::vector<uint8_t> original_hashtree_data;
-  {
-    std::string hashtree_path =
-        GetHashTreeDir() + "/com.android.apex.test_package@1.new";
-    ASSERT_THAT(PathExists(hashtree_path), HasValue(true));
-    original_hashtree_data = read_fn(hashtree_path);
-  }
-
-  ASSERT_THAT(StagePackages({staged_apex.GetPath()}), Ok());
-  // Check that hashtree file was moved.
-  {
-    std::string hashtree_path =
-        GetHashTreeDir() + "/com.android.apex.test_package@1.new";
-    ASSERT_THAT(PathExists(hashtree_path), HasValue(false));
-  }
-  {
-    std::string hashtree_path =
-        GetHashTreeDir() + "/com.android.apex.test_package@1";
-    ASSERT_THAT(PathExists(hashtree_path), HasValue(true));
-    std::vector<uint8_t> moved_hashtree_data = read_fn(hashtree_path);
-    ASSERT_EQ(moved_hashtree_data, original_hashtree_data);
-  }
-}
-
-TEST_F(ApexdMountTest, DeactivePackageTearsDownVerityDevice) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  std::string file_path = AddDataApex("apex.apexd_test_v2.apex");
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
-  UnmountOnTearDown(file_path);
-
-  ASSERT_THAT(DeactivatePackage(file_path), Ok());
-  auto& dm = DeviceMapper::Instance();
-  ASSERT_EQ(dm::DmDeviceState::INVALID,
-            dm.GetState("com.android.apex.test_package@2"));
-}
-
 TEST_F(ApexdMountTest, ActivateDeactivateSharedLibsApex) {
   ASSERT_EQ(mkdir("/apex/sharedlibs", 0755), 0);
   ASSERT_EQ(mkdir("/apex/sharedlibs/lib", 0755), 0);
@@ -1794,18 +1356,18 @@
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
 
   UnmountOnTearDown(file_path);
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(file_path)));
 
   auto active_apex = GetActivePackage("com.android.apex.test.sharedlibs");
-  ASSERT_THAT(active_apex, Ok());
+  ASSERT_TRUE(IsOk(active_apex));
   ASSERT_EQ(active_apex->GetPath(), file_path);
 
   auto apex_mounts = GetApexMounts();
   ASSERT_THAT(apex_mounts,
               UnorderedElementsAre("/apex/com.android.apex.test.sharedlibs@1"));
 
-  ASSERT_THAT(DeactivatePackage(file_path), Ok());
-  ASSERT_THAT(GetActivePackage("com.android.apex.test.sharedlibs"), Not(Ok()));
+  ASSERT_TRUE(IsOk(DeactivatePackage(file_path)));
+  ASSERT_FALSE(IsOk(GetActivePackage("com.android.apex.test.sharedlibs")));
 
   auto new_apex_mounts = GetApexMounts();
   ASSERT_EQ(new_apex_mounts.size(), 0u);
@@ -1841,8 +1403,8 @@
   ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
   UnmountOnTearDown(active_decompressed_apex);
   UnmountOnTearDown(active_data_apex);
-  ASSERT_THAT(ActivatePackage(active_decompressed_apex), Ok());
-  ASSERT_THAT(ActivatePackage(active_data_apex), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(active_decompressed_apex)));
+  ASSERT_TRUE(IsOk(ActivatePackage(active_data_apex)));
   // Clean up inactive apex packages
   RemoveInactiveDataApex();
 
@@ -1879,14 +1441,12 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_path_2));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
                                    ApexInfoXmlEq(apex_info_xml_2)));
@@ -1926,21 +1486,18 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_path_2));
   auto apex_info_xml_3 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package",
       /* modulePath= */ apex_path_3,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 2, /* versionName= */ "2",
-      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
                                    ApexInfoXmlEq(apex_info_xml_2),
@@ -1974,21 +1531,18 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_path_2));
   auto apex_info_xml_3 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package",
       /* modulePath= */ apex_path_3,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
                                    ApexInfoXmlEq(apex_info_xml_2),
@@ -2022,14 +1576,12 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 2, /* versionName= */ "2",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_path_2));
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
@@ -2063,14 +1615,12 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_path_2));
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
@@ -2087,7 +1637,7 @@
 
   {
     auto apex = ApexFile::Open(apex_path_3);
-    ASSERT_THAT(apex, Ok());
+    ASSERT_TRUE(IsOk(apex));
     ASSERT_EQ(static_cast<uint64_t>(apex->GetManifest().version()), 2ULL);
   }
 
@@ -2112,14 +1662,12 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_path_2));
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
@@ -2148,8 +1696,7 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1));
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1)));
@@ -2181,22 +1728,19 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test.sharedlibs",
       /* modulePath= */ apex_path_2,
       /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_2));
   auto apex_info_xml_3 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package",
       /* modulePath= */ apex_path_3,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 2, /* versionName= */ "2",
-      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3));
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
@@ -2265,29 +1809,25 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test.sharedlibs",
       /* modulePath= */ apex_path_2,
       /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_2));
   auto apex_info_xml_3 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package",
       /* modulePath= */ apex_path_3,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 2, /* versionName= */ "2",
-      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_3));
   auto apex_info_xml_4 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test.sharedlibs",
       /* modulePath= */ apex_path_4,
       /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 2, /* versionName= */ "2",
-      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_4),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ false, /* isActive= */ true, GetMTime(apex_path_4));
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
@@ -2362,8 +1902,7 @@
       /* modulePath= */ decompressed_apex,
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(decompressed_apex),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(decompressed_apex));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
   auto& db = GetApexDatabaseForTesting();
@@ -2442,8 +1981,7 @@
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 2, /* versionName= */ "2",
       /* isFactory= */ true, /* isActive= */ true,
-      GetMTime(decompressed_active_apex),
-      /* provideSharedApexLibs= */ false);
+      GetMTime(decompressed_active_apex));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
   auto& db = GetApexDatabaseForTesting();
@@ -2491,8 +2029,7 @@
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
       /* isFactory= */ true, /* isActive= */ true,
-      GetMTime(decompressed_active_apex),
-      /* provideSharedApexLibs= */ false);
+      GetMTime(decompressed_active_apex));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
   auto& db = GetApexDatabaseForTesting();
@@ -2540,8 +2077,7 @@
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
       /* isFactory= */ true, /* isActive= */ true,
-      GetMTime(decompressed_ota_apex),
-      /* provideSharedApexLibs= */ false);
+      GetMTime(decompressed_ota_apex));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
   auto& db = GetApexDatabaseForTesting();
@@ -2605,8 +2141,7 @@
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
       /* isFactory= */ true, /* isActive= */ true,
-      GetMTime(decompressed_active_apex),
-      /* provideSharedApexLibs= */ false);
+      GetMTime(decompressed_active_apex));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
   auto& db = GetApexDatabaseForTesting();
@@ -2649,8 +2184,7 @@
       /* modulePath= */ apex_path,
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_uncompressed)));
 }
@@ -2690,8 +2224,7 @@
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
       /* isFactory= */ true, /* isActive= */ true,
-      GetMTime(decompressed_active_apex),
-      /* provideSharedApexLibs= */ false);
+      GetMTime(decompressed_active_apex));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
 }
@@ -2722,15 +2255,13 @@
       /* modulePath= */ data_apex_path,
       /* preinstalledModulePath= */ system_apex_path,
       /* versionCode= */ 2, /* versionName= */ "2",
-      /* isFactory= */ false, /* isActive= */ true, GetMTime(data_apex_path),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ false, /* isActive= */ true, GetMTime(data_apex_path));
   auto apex_info_xml_system = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.compressed",
       /* modulePath= */ system_apex_path,
       /* preinstalledModulePath= */ system_apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(system_apex_path),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(system_apex_path));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_data),
                                    ApexInfoXmlEq(apex_info_xml_system)));
@@ -2774,8 +2305,7 @@
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 2, /* versionName= */ "2",
       /* isFactory= */ true, /* isActive= */ true,
-      GetMTime(decompressed_active_apex),
-      /* provideSharedApexLibs= */ false);
+      GetMTime(decompressed_active_apex));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml)));
   auto& db = GetApexDatabaseForTesting();
@@ -2816,15 +2346,13 @@
       /* modulePath= */ data_apex_path,
       /* preinstalledModulePath= */ system_apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ false, /* isActive= */ true, GetMTime(data_apex_path),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ false, /* isActive= */ true, GetMTime(data_apex_path));
   auto apex_info_xml_system = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.compressed",
       /* modulePath= */ system_apex_path,
       /* preinstalledModulePath= */ system_apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(system_apex_path),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(system_apex_path));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_data),
                                    ApexInfoXmlEq(apex_info_xml_system)));
@@ -2868,8 +2396,7 @@
       /* preinstalledModulePath= */ apex_path,
       /* versionCode= */ 1, /* versionName= */ "1",
       /* isFactory= */ true, /* isActive= */ true,
-      GetMTime(decompressed_active_apex),
-      /* provideSharedApexLibs= */ false);
+      GetMTime(decompressed_active_apex));
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_decompressed)));
   auto& db = GetApexDatabaseForTesting();
@@ -2970,14 +2497,12 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 137, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ false, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_path_2));
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
@@ -3012,21 +2537,19 @@
       /* modulePath= */ apex_path_1,
       /* preinstalledModulePath= */ apex_path_1,
       /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1),
-      /* provideSharedApexLibs= */ false);
+      /* isFactory= */ true, /* isActive= */ true, GetMTime(apex_path_1));
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_path_2, /* preinstalledModulePath= */ apex_path_2,
       /* versionCode= */ 1, /* versionName= */ "1", /* isFactory= */ true,
-      /* isActive= */ true, GetMTime(apex_path_2),
-      /* provideSharedApexLibs= */ false);
+      /* isActive= */ true, GetMTime(apex_path_2));
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
                                    ApexInfoXmlEq(apex_info_xml_2)));
 }
 
-TEST_F(ApexdMountTest, ActivateFlattenedApex) {
+TEST_F(ApexdMountTest, OnOtaChrootBootstrapFlattenedApex) {
   std::string apex_dir_1 = GetBuiltInDir() + "/com.android.apex.test_package";
   std::string apex_dir_2 = GetBuiltInDir() + "/com.android.apex.test_package_2";
 
@@ -3050,7 +2573,7 @@
   write_manifest_fn(apex_dir_1, "com.android.apex.test_package", 2);
   write_manifest_fn(apex_dir_2, "com.android.apex.test_package_2", 1);
 
-  ASSERT_EQ(ActivateFlattenedApex(), 0);
+  ASSERT_EQ(OnOtaChrootBootstrapFlattenedApex(), 0);
 
   auto apex_mounts = GetApexMounts();
   ASSERT_THAT(apex_mounts,
@@ -3070,16 +2593,14 @@
       /* preinstalledModulePath= */ apex_dir_1,
       /* versionCode= */ 2, /* versionName= */ "2",
       /* isFactory= */ true, /* isActive= */ true,
-      /* lastUpdateMillis= */ 0,
-      /* provideSharedApexLibs= */ false);
+      /* lastUpdateMillis= */ 0);
   auto apex_info_xml_2 = com::android::apex::ApexInfo(
       /* moduleName= */ "com.android.apex.test_package_2",
       /* modulePath= */ apex_dir_2,
       /* preinstalledModulePath= */ apex_dir_2,
       /* versionCode= */ 1, /* versionName= */ "1",
       /* isFactory= */ true, /* isActive= */ true,
-      /* lastUpdateMillis= */ 0,
-      /* provideSharedApexLibs= */ false);
+      /* lastUpdateMillis= */ 0);
 
   ASSERT_THAT(info_list->getApexInfo(),
               UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1),
@@ -3095,9 +2616,8 @@
   std::string apex_path_2 =
       AddPreInstalledApex("apex.apexd_test_different_app.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3123,9 +2643,8 @@
       AddPreInstalledApex("apex.apexd_test_different_app.apex");
   std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3149,9 +2668,8 @@
   std::string apex_path = AddPreInstalledApex("com.android.apex.cts.shim.apex");
   AddDataApex("com.android.apex.cts.shim.v2_wrong_sha.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   UnmountOnTearDown(apex_path);
   OnStart();
@@ -3173,9 +2691,8 @@
       AddPreInstalledApex("apex.apexd_test_different_app.apex");
   std::string apex_path_3 = AddDataApex("apex.apexd_test.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3209,9 +2726,8 @@
       AddPreInstalledApex("apex.apexd_test_different_app.apex");
   AddDataApex("apex.apexd_test.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3245,9 +2761,8 @@
       AddPreInstalledApex("apex.apexd_test_different_app.apex");
   AddDataApex("apex.apexd_test_manifest_mismatch.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3284,13 +2799,12 @@
 
   {
     auto apex = ApexFile::Open(apex_path_3);
-    ASSERT_THAT(apex, Ok());
+    ASSERT_TRUE(IsOk(apex));
     ASSERT_EQ(static_cast<uint64_t>(apex->GetManifest().version()), 2ULL);
   }
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3322,9 +2836,8 @@
   std::string apex_path_1 =
       AddPreInstalledApex("com.android.apex.compressed.v1.capex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3346,7 +2859,7 @@
                            ASSERT_TRUE(latest);
                            ASSERT_EQ(data.full_path, decompressed_active_apex);
                            ASSERT_EQ(data.device_name,
-                                     "com.android.apex.compressed");
+                                     "com.android.apex.compressed@1");
                          });
 }
 
@@ -3359,9 +2872,8 @@
   std::string apex_path_2 =
       AddDataApex("com.android.apex.compressed.v2_original.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3379,7 +2891,7 @@
                            ASSERT_TRUE(latest);
                            ASSERT_EQ(data.full_path, apex_path_2);
                            ASSERT_EQ(data.device_name,
-                                     "com.android.apex.compressed");
+                                     "com.android.apex.compressed@2");
                          });
 }
 
@@ -3392,9 +2904,8 @@
   std::string apex_path_2 =
       AddDataApex("com.android.apex.compressed.v1_original.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3414,7 +2925,7 @@
                            ASSERT_TRUE(latest);
                            ASSERT_EQ(data.full_path, apex_path_2);
                            ASSERT_EQ(data.device_name,
-                                     "com.android.apex.compressed");
+                                     "com.android.apex.compressed@1");
                          });
 }
 
@@ -3427,9 +2938,8 @@
       AddPreInstalledApex("com.android.apex.compressed.v2.capex");
   AddDataApex("com.android.apex.compressed.v1_original.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3452,7 +2962,7 @@
                            ASSERT_TRUE(latest);
                            ASSERT_EQ(data.full_path, decompressed_active_apex);
                            ASSERT_EQ(data.device_name,
-                                     "com.android.apex.compressed");
+                                     "com.android.apex.compressed@2");
                          });
 }
 
@@ -3464,9 +2974,8 @@
   AddPreInstalledApex("com.android.apex.compressed.v1.capex");
   AddDataApex("com.android.apex.compressed.v2_manifest_mismatch.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3489,7 +2998,7 @@
                            ASSERT_TRUE(latest);
                            ASSERT_EQ(data.full_path, decompressed_active_apex);
                            ASSERT_EQ(data.device_name,
-                                     "com.android.apex.compressed");
+                                     "com.android.apex.compressed@1");
                          });
 }
 
@@ -3503,9 +3012,8 @@
   PrepareCompressedApex("com.android.apex.compressed.v1.capex");
   AddDataApex("com.android.apex.compressed.v2_manifest_mismatch.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3527,7 +3035,7 @@
                            ASSERT_TRUE(latest);
                            ASSERT_EQ(data.full_path, decompressed_active_apex);
                            ASSERT_EQ(data.device_name,
-                                     "com.android.apex.compressed");
+                                     "com.android.apex.compressed@1");
                          });
 }
 
@@ -3544,9 +3052,8 @@
   fs::copy(GetTestFile("com.android.apex.compressed.v2_manifest_mismatch.apex"),
            GetDataDir() + "/com.android.apex.compressed@2.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3568,7 +3075,7 @@
                            ASSERT_TRUE(latest);
                            ASSERT_EQ(data.full_path, decompressed_active_apex);
                            ASSERT_EQ(data.device_name,
-                                     "com.android.apex.compressed");
+                                     "com.android.apex.compressed@2");
                          });
 }
 
@@ -3583,9 +3090,8 @@
   auto apex_path =
       AddPreInstalledApex("com.android.apex.compressed.v1_original.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3624,9 +3130,8 @@
   auto apex_path =
       AddPreInstalledApex("com.android.apex.compressed.v1_original.apex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3654,9 +3159,8 @@
                         previous_built_in_dir.path);
   auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3679,7 +3183,7 @@
                            ASSERT_TRUE(latest);
                            ASSERT_EQ(data.full_path, decompressed_active_apex);
                            ASSERT_EQ(data.device_name,
-                                     "com.android.apex.compressed");
+                                     "com.android.apex.compressed@1");
                          });
 }
 
@@ -3697,9 +3201,8 @@
   fs::copy(GetTestFile("com.android.apex.compressed.v2_original.apex"),
            ota_apex_path.c_str());
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   // When we call OnStart for the first time, it will decompress v1 capex and
   // activate it, while after second call it will decompress v2 capex and
@@ -3725,9 +3228,8 @@
   RemoveFileIfExists(old_capex);
   AddPreInstalledApex("com.android.apex.compressed.v2.capex");
   ApexFileRepository::GetInstance().Reset(GetDecompressionDir());
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
   OnStart();
   path_exists = PathExists(ota_apex_path);
   ASSERT_FALSE(*path_exists);
@@ -3757,9 +3259,8 @@
       pre_installed_apex->GetManifest().capexmetadata().originalapexdigest(),
       different_digest);
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3788,9 +3289,8 @@
   // Place a same version capex in current built_in_dir, which has different key
   auto apex_path = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
 
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
+  ASSERT_RESULT_OK(
+      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}));
 
   OnStart();
 
@@ -3831,11 +3331,11 @@
       StringPrintf("%s/apex.apexd_test_different_app.apex", td.path);
 
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_RESULT_OK(instance.AddPreInstalledApex({GetBuiltInDir()}));
 
-  ASSERT_THAT(ActivatePackage(apex_path), Ok());
-  ASSERT_THAT(ActivatePackage(decompressed_apex), Ok());
-  ASSERT_THAT(ActivatePackage(other_apex), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(apex_path)));
+  ASSERT_TRUE(IsOk(ActivatePackage(decompressed_apex)));
+  ASSERT_TRUE(IsOk(ActivatePackage(other_apex)));
 
   auto& db = GetApexDatabaseForTesting();
   // Remember mount information for |other_apex|, since it won't be available in
@@ -3905,11 +3405,11 @@
                    GetDecompressionDir().c_str());
 
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_RESULT_OK(instance.AddPreInstalledApex({GetBuiltInDir()}));
 
-  ASSERT_THAT(ActivatePackage(apex_path_2), Ok());
-  ASSERT_THAT(ActivatePackage(apex_path_3), Ok());
-  ASSERT_THAT(ActivatePackage(decompressed_apex), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(apex_path_2)));
+  ASSERT_TRUE(IsOk(ActivatePackage(apex_path_3)));
+  ASSERT_TRUE(IsOk(ActivatePackage(decompressed_apex)));
   UnmountOnTearDown(apex_path_2);
   UnmountOnTearDown(apex_path_3);
   UnmountOnTearDown(decompressed_apex);
@@ -3951,10 +3451,10 @@
       AddDataApex("com.android.apex.test.sharedlibs_generated.v2.libvY.apex");
 
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_RESULT_OK(instance.AddPreInstalledApex({GetBuiltInDir()}));
 
-  ASSERT_THAT(ActivatePackage(apex_path_1), Ok());
-  ASSERT_THAT(ActivatePackage(apex_path_2), Ok());
+  ASSERT_TRUE(IsOk(ActivatePackage(apex_path_1)));
+  ASSERT_TRUE(IsOk(ActivatePackage(apex_path_2)));
   UnmountOnTearDown(apex_path_1);
   UnmountOnTearDown(apex_path_2);
 
@@ -3973,368 +3473,6 @@
   ASSERT_EQ(new_apex_mounts.size(), 0u);
 }
 
-TEST_F(ApexdMountTest, OnStartInVmModeActivatesPreInstalled) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  auto path1 = AddPreInstalledApex("apex.apexd_test.apex");
-  auto path2 = AddPreInstalledApex("apex.apexd_test_different_app.apex");
-  // In VM mode, we don't scan /data/apex
-  AddDataApex("apex.apexd_test_v2.apex");
-
-  ASSERT_EQ(0, OnStartInVmMode());
-  UnmountOnTearDown(path1);
-  UnmountOnTearDown(path2);
-
-  auto apex_mounts = GetApexMounts();
-  ASSERT_THAT(apex_mounts,
-              UnorderedElementsAre("/apex/com.android.apex.test_package",
-                                   "/apex/com.android.apex.test_package@1",
-                                   "/apex/com.android.apex.test_package_2",
-                                   "/apex/com.android.apex.test_package_2@1",
-                                   // Emits apex-info-list as well
-                                   "/apex/apex-info-list.xml"));
-
-  ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "ready");
-}
-
-TEST_F(ApexdMountTest, OnStartInVmModeFailsWithCapex) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  AddPreInstalledApex("com.android.apex.compressed.v2.capex");
-
-  ASSERT_EQ(1, OnStartInVmMode());
-}
-
-TEST_F(ApexdMountTest, OnStartInVmModeActivatesBlockDevicesAsWell) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  auto path1 = AddBlockApex("apex.apexd_test.apex");
-
-  ASSERT_EQ(0, OnStartInVmMode());
-  UnmountOnTearDown(path1);
-
-  auto apex_mounts = GetApexMounts();
-  ASSERT_THAT(apex_mounts,
-              UnorderedElementsAre("/apex/com.android.apex.test_package",
-                                   "/apex/com.android.apex.test_package@1",
-                                   // Emits apex-info-list as well
-                                   "/apex/apex-info-list.xml"));
-
-  ASSERT_EQ(access("/apex/apex-info-list.xml", F_OK), 0);
-  auto info_list =
-      com::android::apex::readApexInfoList("/apex/apex-info-list.xml");
-  ASSERT_TRUE(info_list.has_value());
-  auto apex_info_xml_1 = com::android::apex::ApexInfo(
-      /* moduleName= */ "com.android.apex.test_package",
-      /* modulePath= */ path1,
-      /* preinstalledModulePath= */ path1,
-      /* versionCode= */ 1, /* versionName= */ "1",
-      /* isFactory= */ true, /* isActive= */ true, GetMTime(path1),
-      /* provideSharedApexLibs= */ false);
-  ASSERT_THAT(info_list->getApexInfo(),
-              UnorderedElementsAre(ApexInfoXmlEq(apex_info_xml_1)));
-}
-
-TEST_F(ApexdMountTest, OnStartInVmModeFailsWithDuplicateNames) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  AddPreInstalledApex("apex.apexd_test.apex");
-  AddBlockApex("apex.apexd_test_v2.apex");
-
-  ASSERT_EQ(1, OnStartInVmMode());
-}
-
-TEST_F(ApexdMountTest, OnStartInVmModeFailsWithWrongPubkey) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  AddBlockApex("apex.apexd_test.apex", /*public_key=*/"wrong pubkey");
-
-  ASSERT_EQ(1, OnStartInVmMode());
-}
-
-TEST_F(ApexdMountTest, GetActivePackagesReturningBlockApexesAsWell) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  auto path1 = AddBlockApex("apex.apexd_test.apex");
-
-  ASSERT_EQ(0, OnStartInVmMode());
-  UnmountOnTearDown(path1);
-
-  auto active_apexes = GetActivePackages();
-  ASSERT_EQ(1u, active_apexes.size());
-  ASSERT_EQ(path1, active_apexes[0].GetPath());
-}
-
-TEST_F(ApexdMountTest, OnStartInVmModeFailsWithWrongRootDigest) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  AddBlockApex("apex.apexd_test.apex", /*public_key=*/"",
-               /*root_digest=*/"wrong root digest");
-
-  ASSERT_EQ(1, OnStartInVmMode());
-}
-
-// Test that OnStart works with only block devices
-TEST_F(ApexdMountTest, OnStartOnlyBlockDevices) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  auto path1 = AddBlockApex("apex.apexd_test.apex");
-
-  ASSERT_THAT(android::apex::AddBlockApex(ApexFileRepository::GetInstance()),
-              Ok());
-
-  OnStart();
-  UnmountOnTearDown(path1);
-
-  ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
-  auto apex_mounts = GetApexMounts();
-
-  ASSERT_THAT(apex_mounts,
-              UnorderedElementsAre("/apex/com.android.apex.test_package",
-                                   "/apex/com.android.apex.test_package@1"));
-}
-
-// Test that we can have a mix of both block and system apexes
-TEST_F(ApexdMountTest, OnStartBlockAndSystemInstalled) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  auto path1 = AddPreInstalledApex("apex.apexd_test.apex");
-  auto path2 = AddBlockApex("apex.apexd_test_different_app.apex");
-
-  auto& instance = ApexFileRepository::GetInstance();
-
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-  ASSERT_THAT(android::apex::AddBlockApex(instance), Ok());
-
-  OnStart();
-  UnmountOnTearDown(path1);
-  UnmountOnTearDown(path2);
-
-  ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
-  auto apex_mounts = GetApexMounts();
-
-  ASSERT_THAT(apex_mounts,
-              UnorderedElementsAre("/apex/com.android.apex.test_package",
-                                   "/apex/com.android.apex.test_package@1",
-                                   "/apex/com.android.apex.test_package_2",
-                                   "/apex/com.android.apex.test_package_2@1"));
-}
-
-TEST_F(ApexdMountTest, OnStartBlockAndCompressedInstalled) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  auto path1 = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
-  auto path2 = AddBlockApex("apex.apexd_test.apex");
-
-  auto& instance = ApexFileRepository::GetInstance();
-
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-  ASSERT_THAT(android::apex::AddBlockApex(instance), Ok());
-
-  OnStart();
-  UnmountOnTearDown(path1);
-  UnmountOnTearDown(path2);
-
-  // Decompressed APEX should be mounted
-  std::string decompressed_active_apex = StringPrintf(
-      "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
-      kDecompressedApexPackageSuffix);
-  UnmountOnTearDown(decompressed_active_apex);
-
-  ASSERT_EQ(GetProperty(kTestApexdStatusSysprop, ""), "starting");
-  auto apex_mounts = GetApexMounts();
-  ASSERT_THAT(apex_mounts,
-              UnorderedElementsAre("/apex/com.android.apex.compressed",
-                                   "/apex/com.android.apex.compressed@1",
-                                   "/apex/com.android.apex.test_package",
-                                   "/apex/com.android.apex.test_package@1"));
-}
-
-// Test that data version of apex is used if newer
-TEST_F(ApexdMountTest, BlockAndNewerData) {
-  // MockCheckpointInterface checkpoint_interface;
-  //// Need to call InitializeVold before calling OnStart
-  // InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  auto& instance = ApexFileRepository::GetInstance();
-  AddBlockApex("apex.apexd_test.apex");
-  ASSERT_THAT(android::apex::AddBlockApex(instance), Ok());
-
-  TemporaryDir data_dir;
-  auto apexd_test_file_v2 =
-      ApexFile::Open(AddDataApex("apex.apexd_test_v2.apex"));
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
-
-  auto all_apex = instance.AllApexFilesByName();
-  auto result = SelectApexForActivation(all_apex, instance);
-  ASSERT_EQ(result.size(), 1u);
-
-  ASSERT_THAT(result,
-              UnorderedElementsAre(ApexFileEq(ByRef(*apexd_test_file_v2))));
-}
-
-// Test that data version of apex not is used if older
-TEST_F(ApexdMountTest, BlockApexAndOlderData) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  auto& instance = ApexFileRepository::GetInstance();
-  auto apexd_test_file_v2 =
-      ApexFile::Open(AddBlockApex("apex.apexd_test_v2.apex"));
-  ASSERT_THAT(android::apex::AddBlockApex(instance), Ok());
-
-  TemporaryDir data_dir;
-  AddDataApex("apex.apexd_test.apex");
-  ASSERT_THAT(instance.AddDataApex(GetDataDir()), Ok());
-
-  auto all_apex = instance.AllApexFilesByName();
-  auto result = SelectApexForActivation(all_apex, instance);
-  ASSERT_EQ(result.size(), 1u);
-
-  ASSERT_THAT(result,
-              UnorderedElementsAre(ApexFileEq(ByRef(*apexd_test_file_v2))));
-}
-
-// Test that AddBlockApex does nothing if system property not set.
-TEST_F(ApexdMountTest, AddBlockApexWithoutSystemProp) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  auto& instance = ApexFileRepository::GetInstance();
-  AddBlockApex("apex.apexd_test.apex");
-  ASSERT_THAT(android::apex::AddBlockApex(instance), Ok());
-  ASSERT_EQ(instance.AllApexFilesByName().size(), 0ul);
-}
-
-// Test that adding block apex fails if preinstalled version exists
-TEST_F(ApexdMountTest, AddBlockApexFailsWithDuplicate) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  AddPreInstalledApex("apex.apexd_test.apex");
-  AddBlockApex("apex.apexd_test_v2.apex");
-
-  auto& instance = ApexFileRepository::GetInstance();
-
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-  ASSERT_THAT(android::apex::AddBlockApex(instance),
-              HasError(WithMessage(HasSubstr(
-                  "duplicate of com.android.apex.test_package found"))));
-}
-
-// Test that adding block apex fails if preinstalled compressed version exists
-TEST_F(ApexdMountTest, AddBlockApexFailsWithCompressedDuplicate) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  // Set system property to enable block apexes
-  SetBlockApexEnabled(true);
-
-  auto path1 = AddPreInstalledApex("com.android.apex.compressed.v1.capex");
-  auto path2 = AddBlockApex("com.android.apex.compressed.v1_original.apex");
-
-  auto& instance = ApexFileRepository::GetInstance();
-
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-  ASSERT_THAT(android::apex::AddBlockApex(instance),
-              HasError(WithMessage(HasSubstr(
-                  "duplicate of com.android.apex.compressed found"))));
-}
-
-TEST_F(ApexdMountTest, CopySepolicyToMetadata) {
-  std::string file_path = AddPreInstalledApex("com.android.sepolicy.apex");
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
-  ASSERT_THAT(ActivatePackage(file_path), Ok());
-  UnmountOnTearDown(file_path);
-  ASSERT_THAT(CreateStagedSession("com.android.sepolicy.apex", 666), Ok());
-
-  ASSERT_THAT(
-      SubmitStagedSession(666, {}, /* has_rollback_enabled= */ false,
-                          /* is_rollback= */ false, /* rollback_id= */ -1),
-      Ok());
-
-  auto staged_dir = GetMetadataSepolicyStagedDir();
-  ASSERT_THAT(PathExists(staged_dir + "/SEPolicy.zip"), HasValue(true));
-  ASSERT_THAT(PathExists(staged_dir + "/SEPolicy.zip.sig"), HasValue(true));
-  ASSERT_THAT(PathExists(staged_dir + "/SEPolicy.zip.fsv_sig"), HasValue(true));
-}
-
-TEST_F(ApexdMountTest, AbortSepolicyApexInstall) {
-  std::string file_path = AddPreInstalledApex("com.android.sepolicy.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-  ASSERT_THAT(CreateStagedSession("com.android.sepolicy.apex", 666), Ok());
-  ASSERT_THAT(
-      SubmitStagedSession(666, {}, /* has_rollback_enabled= */ false,
-                          /* is_rollback= */ false, /* rollback_id= */ -1),
-      Ok());
-
-  auto staged_dir = GetMetadataSepolicyStagedDir();
-  ASSERT_THAT(PathExists(staged_dir), HasValue(true));
-  ASSERT_FALSE(IsEmptyDirectory(staged_dir));
-
-  ASSERT_THAT(AbortStagedSession(666), Ok());
-  ASSERT_THAT(PathExists(staged_dir), HasValue(false));
-}
-
 class ApexActivationFailureTests : public ApexdMountTest {};
 
 TEST_F(ApexActivationFailureTests, BuildFingerprintDifferent) {
@@ -4374,7 +3512,7 @@
               HasSubstr("More than one APEX package found"));
 }
 
-TEST_F(ApexActivationFailureTests, CorruptedSuperblockApexCannotBeStaged) {
+TEST_F(ApexActivationFailureTests, PostInstallFailsForApex) {
   auto apex_session =
       CreateStagedSession("apex.apexd_test_corrupt_superblock_apex.apex", 123);
   apex_session->UpdateStateAndCommit(SessionState::STAGED);
@@ -4383,7 +3521,7 @@
 
   apex_session = ApexSession::GetSession(123);
   ASSERT_THAT(apex_session->GetErrorMessage(),
-              HasSubstr("Couldn't find filesystem magic"));
+              HasSubstr("Postinstall failed for session"));
 }
 
 TEST_F(ApexActivationFailureTests, CorruptedApexCannotBeStaged) {
@@ -4400,7 +3538,7 @@
 TEST_F(ApexActivationFailureTests, ActivatePackageImplFails) {
   auto shim_path = AddPreInstalledApex("com.android.apex.cts.shim.apex");
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_RESULT_OK(instance.AddPreInstalledApex({GetBuiltInDir()}));
 
   auto apex_session =
       CreateStagedSession("com.android.apex.cts.shim.v2_wrong_sha.apex", 123);
@@ -4425,7 +3563,7 @@
 
   auto pre_installed_apex = AddPreInstalledApex("apex.apexd_test.apex");
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_RESULT_OK(instance.AddPreInstalledApex({GetBuiltInDir()}));
 
   auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
   apex_session->UpdateStateAndCommit(SessionState::STAGED);
@@ -4449,7 +3587,7 @@
 
   auto pre_installed_apex = AddPreInstalledApex("apex.apexd_test.apex");
   auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
+  ASSERT_RESULT_OK(instance.AddPreInstalledApex({GetBuiltInDir()}));
 
   auto apex_session = CreateStagedSession("apex.apexd_test.apex", 123);
   apex_session->UpdateStateAndCommit(SessionState::STAGED);
@@ -4461,403 +3599,5 @@
   ASSERT_EQ(apex_session->GetState(), SessionState::REVERTED);
 }
 
-TEST_F(ApexdMountTest, OnBootstrapCreatesEmptyDmDevices) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  AddPreInstalledApex("com.android.apex.compressed.v1.capex");
-
-  DeviceMapper& dm = DeviceMapper::Instance();
-
-  auto cleaner = make_scope_guard([&]() {
-    dm.DeleteDeviceIfExists("com.android.apex.test_package", 1s);
-    dm.DeleteDeviceIfExists("com.android.apex.compressed", 1s);
-  });
-
-  ASSERT_EQ(0, OnBootstrap());
-
-  ASSERT_EQ(dm::DmDeviceState::SUSPENDED,
-            dm.GetState("com.android.apex.test_package"));
-  ASSERT_EQ(dm::DmDeviceState::SUSPENDED,
-            dm.GetState("com.android.apex.compressed"));
-}
-
-TEST_F(ApexdUnitTest, StagePackagesFailKey) {
-  auto status =
-      StagePackages({GetTestFile("apex.apexd_test_no_inst_key.apex")});
-
-  ASSERT_THAT(
-      status,
-      HasError(WithMessage(("No preinstalled apex found for package "
-                            "com.android.apex.test_package.no_inst_key"))));
-}
-
-TEST_F(ApexdUnitTest, StagePackagesSuccess) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-
-  auto status = StagePackages({GetTestFile("apex.apexd_test.apex")});
-  ASSERT_THAT(status, Ok());
-
-  auto staged_path = StringPrintf("%s/com.android.apex.test_package@1.apex",
-                                  GetDataDir().c_str());
-  ASSERT_EQ(0, access(staged_path.c_str(), F_OK));
-}
-
-TEST_F(ApexdUnitTest, StagePackagesClearsPreviouslyActivePackage) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-
-  auto current_apex = AddDataApex("apex.apexd_test.apex");
-  ASSERT_EQ(0, access(current_apex.c_str(), F_OK));
-
-  auto status = StagePackages({GetTestFile("apex.apexd_test_v2.apex")});
-  ASSERT_THAT(status, Ok());
-
-  auto staged_path = StringPrintf("%s/com.android.apex.test_package@2.apex",
-                                  GetDataDir().c_str());
-  ASSERT_EQ(0, access(staged_path.c_str(), F_OK));
-  ASSERT_EQ(-1, access(current_apex.c_str(), F_OK));
-  ASSERT_EQ(ENOENT, errno);
-}
-
-TEST_F(ApexdUnitTest, StagePackagesClearsPreviouslyActivePackageDowngrade) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-
-  auto current_apex = AddDataApex("apex.apexd_test_v2.apex");
-  ASSERT_EQ(0, access(current_apex.c_str(), F_OK));
-
-  auto status = StagePackages({GetTestFile("apex.apexd_test.apex")});
-  ASSERT_THAT(status, Ok());
-
-  auto staged_path = StringPrintf("%s/com.android.apex.test_package@1.apex",
-                                  GetDataDir().c_str());
-  ASSERT_EQ(0, access(staged_path.c_str(), F_OK));
-  ASSERT_EQ(-1, access(current_apex.c_str(), F_OK));
-  ASSERT_EQ(ENOENT, errno);
-}
-
-TEST_F(ApexdUnitTest, StagePackagesAlreadyStagedPackage) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-
-  auto status = StagePackages({GetTestFile("apex.apexd_test.apex")});
-  ASSERT_THAT(status, Ok());
-
-  auto staged_path = StringPrintf("%s/com.android.apex.test_package@1.apex",
-                                  GetDataDir().c_str());
-  struct stat stat1;
-  ASSERT_EQ(0, stat(staged_path.c_str(), &stat1));
-  ASSERT_TRUE(S_ISREG(stat1.st_mode));
-
-  {
-    auto apex = ApexFile::Open(staged_path);
-    ASSERT_THAT(apex, Ok());
-    ASSERT_FALSE(apex->GetManifest().nocode());
-  }
-
-  auto status2 = StagePackages({GetTestFile("apex.apexd_test_nocode.apex")});
-  ASSERT_THAT(status2, Ok());
-
-  struct stat stat2;
-  ASSERT_EQ(0, stat(staged_path.c_str(), &stat2));
-  ASSERT_TRUE(S_ISREG(stat2.st_mode));
-
-  ASSERT_NE(stat1.st_ino, stat2.st_ino);
-
-  {
-    auto apex = ApexFile::Open(staged_path);
-    ASSERT_THAT(apex, Ok());
-    ASSERT_TRUE(apex->GetManifest().nocode());
-  }
-}
-
-TEST_F(ApexdUnitTest, StagePackagesMultiplePackages) {
-  AddPreInstalledApex("apex.apexd_test.apex");
-  AddPreInstalledApex("apex.apexd_test_different_app.apex");
-  auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-
-  auto status =
-      StagePackages({GetTestFile("apex.apexd_test_v2.apex"),
-                     GetTestFile("apex.apexd_test_different_app.apex")});
-  ASSERT_THAT(status, Ok());
-
-  auto staged_path1 = StringPrintf("%s/com.android.apex.test_package@2.apex",
-                                   GetDataDir().c_str());
-  auto staged_path2 = StringPrintf("%s/com.android.apex.test_package_2@1.apex",
-                                   GetDataDir().c_str());
-  ASSERT_EQ(0, access(staged_path1.c_str(), F_OK));
-  ASSERT_EQ(0, access(staged_path2.c_str(), F_OK));
-}
-
-TEST_F(ApexdUnitTest, UnstagePackages) {
-  auto file_path1 = AddDataApex("apex.apexd_test.apex");
-  auto file_path2 = AddDataApex("apex.apexd_test_different_app.apex");
-
-  ASSERT_THAT(UnstagePackages({file_path1}), Ok());
-  ASSERT_EQ(-1, access(file_path1.c_str(), F_OK));
-  ASSERT_EQ(errno, ENOENT);
-  ASSERT_EQ(0, access(file_path2.c_str(), F_OK));
-}
-
-TEST_F(ApexdUnitTest, UnstagePackagesEmptyInput) {
-  auto file_path1 = AddDataApex("apex.apexd_test.apex");
-  auto file_path2 = AddDataApex("apex.apexd_test_different_app.apex");
-
-  ASSERT_THAT(UnstagePackages({}),
-              HasError(WithMessage("Empty set of inputs")));
-  ASSERT_EQ(0, access(file_path1.c_str(), F_OK));
-  ASSERT_EQ(0, access(file_path2.c_str(), F_OK));
-}
-
-TEST_F(ApexdUnitTest, UnstagePackagesFail) {
-  auto file_path1 = AddDataApex("apex.apexd_test.apex");
-  auto bad_path = GetDataDir() + "/missing.apex";
-
-  ASSERT_THAT(UnstagePackages({file_path1, bad_path}), Not(Ok()));
-  ASSERT_EQ(0, access(file_path1.c_str(), F_OK));
-}
-
-TEST_F(ApexdUnitTest, UnstagePackagesFailPreInstalledApex) {
-  auto file_path1 = AddPreInstalledApex("apex.apexd_test.apex");
-  auto file_path2 = AddDataApex("apex.apexd_test_different_app.apex");
-
-  auto& instance = ApexFileRepository::GetInstance();
-  ASSERT_THAT(instance.AddPreInstalledApex({GetBuiltInDir()}), Ok());
-
-  ASSERT_THAT(UnstagePackages({file_path1, file_path2}),
-              HasError(WithMessage("Can't uninstall pre-installed apex " +
-                                   file_path1)));
-  ASSERT_EQ(0, access(file_path1.c_str(), F_OK));
-  ASSERT_EQ(0, access(file_path2.c_str(), F_OK));
-}
-
-TEST_F(ApexdUnitTest, RevertStoresCrashingNativeProcess) {
-  MockCheckpointInterface checkpoint_interface;
-  checkpoint_interface.SetSupportsCheckpoint(true);
-  InitializeVold(&checkpoint_interface);
-
-  auto apex_session = CreateStagedSession("apex.apexd_test.apex", 1543);
-  ASSERT_THAT(apex_session, Ok());
-  ASSERT_THAT(apex_session->UpdateStateAndCommit(SessionState::ACTIVATED),
-              Ok());
-
-  ASSERT_THAT(RevertActiveSessions("test_process", ""), Ok());
-  apex_session = ApexSession::GetSession(1543);
-  ASSERT_THAT(apex_session, Ok());
-  ASSERT_EQ(apex_session->GetCrashingNativeProcess(), "test_process");
-}
-
-TEST_F(ApexdUnitTest, MountAndDeriveClasspathNoJar) {
-  AddPreInstalledApex("apex.apexd_test_classpath.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  // Call MountAndDeriveClassPath
-  auto apex_file = ApexFile::Open(GetTestFile("apex.apexd_test.apex"));
-  auto package_name = apex_file->GetManifest().name();
-  std::vector<ApexFile> apex_files;
-  apex_files.emplace_back(std::move(*apex_file));
-  auto class_path = MountAndDeriveClassPath(apex_files);
-  ASSERT_THAT(class_path, Ok());
-  ASSERT_THAT(class_path->HasClassPathJars(package_name), false);
-}
-
-TEST_F(ApexdUnitTest, MountAndDeriveClassPathJarsPresent) {
-  AddPreInstalledApex("apex.apexd_test_classpath.apex");
-  ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()});
-
-  // Call MountAndDeriveClassPath
-  auto apex_file =
-      ApexFile::Open(GetTestFile("apex.apexd_test_classpath.apex"));
-  auto package_name = apex_file->GetManifest().name();
-  std::vector<ApexFile> apex_files;
-  apex_files.emplace_back(std::move(*apex_file));
-  auto class_path = MountAndDeriveClassPath(apex_files);
-  ASSERT_THAT(class_path, Ok());
-  ASSERT_THAT(class_path->HasClassPathJars(package_name), true);
-}
-
-TEST_F(ApexdUnitTest, ProcessCompressedApexWrongSELinuxContext) {
-  auto compressed_apex = ApexFile::Open(
-      AddPreInstalledApex("com.android.apex.compressed.v1.capex"));
-
-  std::vector<ApexFileRef> compressed_apex_list;
-  compressed_apex_list.emplace_back(std::cref(*compressed_apex));
-  auto return_value =
-      ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
-  ASSERT_EQ(return_value.size(), 1u);
-
-  auto decompressed_apex_path = StringPrintf(
-      "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
-      kDecompressedApexPackageSuffix);
-  // Verify that so far it has correct context.
-  ASSERT_EQ(kTestActiveApexSelinuxCtx,
-            GetSelinuxContext(decompressed_apex_path));
-
-  // Manually mess up the context
-  ASSERT_EQ(0, setfilecon(decompressed_apex_path.c_str(),
-                          "u:object_r:apex_data_file:s0"));
-  ASSERT_EQ("u:object_r:apex_data_file:s0",
-            GetSelinuxContext(decompressed_apex_path));
-
-  auto attempt_2 =
-      ProcessCompressedApex(compressed_apex_list, /* is_ota_chroot= */ false);
-  ASSERT_EQ(attempt_2.size(), 1u);
-  // Verify that it again has correct context.
-  ASSERT_EQ(kTestActiveApexSelinuxCtx,
-            GetSelinuxContext(decompressed_apex_path));
-}
-
-TEST_F(ApexdMountTest, OnStartNoApexUpdated) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  AddPreInstalledApex("com.android.apex.compressed.v1.capex");
-  std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
-  std::string apex_path_2 =
-      AddPreInstalledApex("apex.apexd_test_different_app.apex");
-  std::string apex_path_3 = AddDataApex("apex.apexd_test_v2.apex");
-  std::string apex_path_4 =
-      AddDecompressedApex("com.android.apex.compressed.v1_original.apex");
-
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
-
-  OnStart();
-
-  UnmountOnTearDown(apex_path_2);
-  UnmountOnTearDown(apex_path_3);
-  UnmountOnTearDown(apex_path_4);
-
-  auto updated_apexes = GetChangedActiveApexesForTesting();
-  ASSERT_EQ(updated_apexes.size(), 0u);
-  // Quick check that all apexes were mounted
-  auto apex_mounts = GetApexMounts();
-  ASSERT_EQ(apex_mounts.size(), 6u);
-}
-
-TEST_F(ApexdMountTest, OnStartDecompressingConsideredApexUpdate) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  AddPreInstalledApex("com.android.apex.compressed.v1.capex");
-  std::string apex_path_1 = AddPreInstalledApex("apex.apexd_test.apex");
-  std::string decompressed_active_apex = StringPrintf(
-      "%s/com.android.apex.compressed@1%s", GetDecompressionDir().c_str(),
-      kDecompressedApexPackageSuffix);
-  UnmountOnTearDown(decompressed_active_apex);
-
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
-
-  OnStart();
-
-  UnmountOnTearDown(apex_path_1);
-  UnmountOnTearDown(decompressed_active_apex);
-
-  auto updated_apexes = GetChangedActiveApexesForTesting();
-  ASSERT_EQ(updated_apexes.size(), 1u);
-  auto apex_file = ApexFile::Open(decompressed_active_apex);
-  ASSERT_THAT(apex_file, Ok());
-  ASSERT_TRUE(IsActiveApexChanged(*apex_file));
-}
-
-TEST_F(ApexdMountTest, ActivatesStagedSession) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  std::string preinstalled_apex = AddPreInstalledApex("apex.apexd_test.apex");
-  auto apex_session = CreateStagedSession("apex.apexd_test_v2.apex", 37);
-  apex_session->UpdateStateAndCommit(SessionState::STAGED);
-
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
-
-  std::string active_apex =
-      GetDataDir() + "/" + "com.android.apex.test_package@2.apex";
-
-  UnmountOnTearDown(preinstalled_apex);
-  UnmountOnTearDown(active_apex);
-  OnStart();
-
-  // Quick check that session was activated
-  {
-    auto session = ApexSession::GetSession(37);
-    ASSERT_THAT(session, Ok());
-    ASSERT_EQ(session->GetState(), SessionState::ACTIVATED);
-  }
-
-  auto updated_apexes = GetChangedActiveApexesForTesting();
-  ASSERT_EQ(updated_apexes.size(), 1u);
-  auto apex_file = ApexFile::Open(active_apex);
-  ASSERT_THAT(apex_file, Ok());
-  ASSERT_TRUE(IsActiveApexChanged(*apex_file));
-}
-
-TEST_F(ApexdMountTest, FailsToActivateStagedSession) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  std::string preinstalled_apex = AddPreInstalledApex("apex.apexd_test.apex");
-  auto apex_session =
-      CreateStagedSession("apex.apexd_test_manifest_mismatch.apex", 73);
-  apex_session->UpdateStateAndCommit(SessionState::STAGED);
-
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
-
-  UnmountOnTearDown(preinstalled_apex);
-  OnStart();
-
-  // Quick check that session was activated
-  {
-    auto session = ApexSession::GetSession(73);
-    ASSERT_THAT(session, Ok());
-    ASSERT_NE(session->GetState(), SessionState::ACTIVATED);
-  }
-
-  auto updated_apexes = GetChangedActiveApexesForTesting();
-  ASSERT_EQ(updated_apexes.size(), 1u);
-
-  auto apex_file = ApexFile::Open(preinstalled_apex);
-  ASSERT_THAT(apex_file, Ok());
-  ASSERT_TRUE(IsActiveApexChanged(*apex_file));
-}
-
-TEST_F(ApexdMountTest, FailsToActivateApexFallbacksToSystemOne) {
-  MockCheckpointInterface checkpoint_interface;
-  // Need to call InitializeVold before calling OnStart
-  InitializeVold(&checkpoint_interface);
-
-  std::string preinstalled_apex = AddPreInstalledApex("apex.apexd_test.apex");
-  AddDataApex("apex.apexd_test_manifest_mismatch.apex");
-
-  ASSERT_THAT(
-      ApexFileRepository::GetInstance().AddPreInstalledApex({GetBuiltInDir()}),
-      Ok());
-
-  UnmountOnTearDown(preinstalled_apex);
-  OnStart();
-
-  auto updated_apexes = GetChangedActiveApexesForTesting();
-  ASSERT_EQ(updated_apexes.size(), 1u);
-
-  auto apex_file = ApexFile::Open(preinstalled_apex);
-  ASSERT_THAT(apex_file, Ok());
-  ASSERT_TRUE(IsActiveApexChanged(*apex_file));
-}
-
 }  // namespace apex
 }  // namespace android
diff --git a/apexd/apexd_test_utils.h b/apexd/apexd_test_utils.h
index 2ba7660..5e3689d 100644
--- a/apexd/apexd_test_utils.h
+++ b/apexd/apexd_test_utils.h
@@ -17,9 +17,9 @@
 #include <filesystem>
 #include <fstream>
 
+#include <asm-generic/errno-base.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-#include <linux/loop.h>
 #include <sched.h>
 #include <sys/mount.h>
 
@@ -33,21 +33,27 @@
 #include <android/apex/ApexInfo.h>
 #include <android/apex/ApexSessionInfo.h>
 #include <binder/IServiceManager.h>
-#include <fstab/fstab.h>
-#include <libdm/dm.h>
 #include <selinux/android.h>
 
 #include "apex_file.h"
-#include "apexd_loop.h"
-#include "apexd_utils.h"
 #include "session_state.pb.h"
 
 #include "com_android_apex.h"
 
+using android::base::Error;
+using android::base::Result;
+using apex::proto::SessionState;
+
 namespace android {
 namespace apex {
 namespace testing {
 
+using ::testing::AllOf;
+using ::testing::Eq;
+using ::testing::ExplainMatchResult;
+using ::testing::Field;
+using ::testing::Property;
+
 template <typename T>
 inline ::testing::AssertionResult IsOk(const android::base::Result<T>& result) {
   if (result.ok()) {
@@ -67,10 +73,6 @@
 }
 
 MATCHER_P(SessionInfoEq, other, "") {
-  using ::testing::AllOf;
-  using ::testing::Eq;
-  using ::testing::Field;
-
   return ExplainMatchResult(
       AllOf(
           Field("sessionId", &ApexSessionInfo::sessionId, Eq(other.sessionId)),
@@ -93,10 +95,6 @@
 }
 
 MATCHER_P(ApexInfoEq, other, "") {
-  using ::testing::AllOf;
-  using ::testing::Eq;
-  using ::testing::Field;
-
   return ExplainMatchResult(
       AllOf(Field("moduleName", &ApexInfo::moduleName, Eq(other.moduleName)),
             Field("modulePath", &ApexInfo::modulePath, Eq(other.modulePath)),
@@ -109,10 +107,6 @@
 }
 
 MATCHER_P(ApexFileEq, other, "") {
-  using ::testing::AllOf;
-  using ::testing::Eq;
-  using ::testing::Property;
-
   return ExplainMatchResult(
       AllOf(Property("path", &ApexFile::GetPath, Eq(other.get().GetPath())),
             Property("image_offset", &ApexFile::GetImageOffset,
@@ -171,13 +165,13 @@
   *os << "}";
 }
 
-inline android::base::Result<bool> CompareFiles(const std::string& filename1,
-                                                const std::string& filename2) {
+inline Result<bool> CompareFiles(const std::string& filename1,
+                                 const std::string& filename2) {
   std::ifstream file1(filename1, std::ios::binary);
   std::ifstream file2(filename2, std::ios::binary);
 
   if (file1.bad() || file2.bad()) {
-    return android::base::Error() << "Could not open one of the file";
+    return Error() << "Could not open one of the file";
   }
 
   std::istreambuf_iterator<char> begin1(file1);
@@ -304,138 +298,12 @@
   // Just in case, run restorecon -R on /apex.
   if (selinux_android_restorecon("/apex", SELINUX_ANDROID_RESTORECON_RECURSE) <
       0) {
-    return ErrnoError() << "Failed to restorecon /apex";
+    return android::base::ErrnoError() << "Failed to restorecon /apex";
   }
 
   return {};
 }
 
-// Simpler version of loop::CreateLoopDevice. Uses LOOP_SET_FD/LOOP_SET_STATUS64
-// instead of LOOP_CONFIGURE.
-// TODO(b/191244059) use loop::CreateLoopDevice
-inline base::Result<loop::LoopbackDeviceUniqueFd> CreateLoopDeviceForTest(
-    const std::string& filepath) {
-  base::unique_fd ctl_fd(open("/dev/loop-control", O_RDWR | O_CLOEXEC));
-  if (ctl_fd.get() == -1) {
-    return base::ErrnoError() << "Failed to open loop-control";
-  }
-  int num = ioctl(ctl_fd.get(), LOOP_CTL_GET_FREE);
-  if (num == -1) {
-    return base::ErrnoError() << "Failed LOOP_CTL_GET_FREE";
-  }
-  auto loop_device = loop::WaitForDevice(num);
-  if (!loop_device.ok()) {
-    return loop_device.error();
-  }
-  base::unique_fd target_fd(open(filepath.c_str(), O_RDONLY | O_CLOEXEC));
-  if (target_fd.get() == -1) {
-    return base::ErrnoError() << "Failed to open " << filepath;
-  }
-  struct loop_info64 li = {};
-  strlcpy((char*)li.lo_crypt_name, filepath.c_str(), LO_NAME_SIZE);
-  li.lo_flags |= LO_FLAGS_AUTOCLEAR;
-  if (ioctl(loop_device->device_fd.get(), LOOP_SET_FD, target_fd.get()) == -1) {
-    return base::ErrnoError() << "Failed to LOOP_SET_FD";
-  }
-  if (ioctl(loop_device->device_fd.get(), LOOP_SET_STATUS64, &li) == -1) {
-    return base::ErrnoError() << "Failed to LOOP_SET_STATUS64";
-  }
-  return loop_device;
-}
-
-inline base::Result<loop::LoopbackDeviceUniqueFd> MountViaLoopDevice(
-    const std::string& filepath, const std::string& mount_point) {
-  auto loop_device = CreateLoopDeviceForTest(filepath);
-  if (loop_device.ok()) {
-    close(open(mount_point.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
-               0644));
-    if (0 != mount(loop_device->name.c_str(), mount_point.c_str(), nullptr,
-                   MS_BIND, nullptr)) {
-      return base::ErrnoError() << "can't mount.";
-    }
-  }
-  return loop_device;
-}
-
-inline base::Result<loop::LoopbackDeviceUniqueFd> WriteBlockApex(
-    const std::string& apex_file, const std::string& apex_path) {
-  std::string intermediate_path = apex_path + ".intermediate";
-  std::filesystem::copy(apex_file, intermediate_path);
-  return MountViaLoopDevice(intermediate_path, apex_path);
-}
-
-inline android::base::Result<std::string> GetBlockDeviceForApex(
-    const std::string& package_id) {
-  using android::fs_mgr::Fstab;
-  using android::fs_mgr::GetEntryForMountPoint;
-  using android::fs_mgr::ReadFstabFromFile;
-
-  std::string mount_point = std::string(kApexRoot) + "/" + package_id;
-  Fstab fstab;
-  if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
-    return android::base::Error() << "Failed to read /proc/mounts";
-  }
-  auto entry = GetEntryForMountPoint(&fstab, mount_point);
-  if (entry == nullptr) {
-    return android::base::Error()
-           << "Can't find " << mount_point << " in /proc/mounts";
-  }
-  return entry->blk_device;
-}
-
-inline android::base::Result<void> ReadDevice(const std::string& block_device) {
-  static constexpr int kBlockSize = 4096;
-  static constexpr size_t kBufSize = 1024 * kBlockSize;
-  std::vector<uint8_t> buffer(kBufSize);
-
-  android::base::unique_fd fd(
-      TEMP_FAILURE_RETRY(open(block_device.c_str(), O_RDONLY | O_CLOEXEC)));
-  if (fd.get() == -1) {
-    return android::base::ErrnoError() << "Can't open " << block_device;
-  }
-
-  while (true) {
-    int n = read(fd.get(), buffer.data(), kBufSize);
-    if (n < 0) {
-      return android::base::ErrnoError() << "Failed to read " << block_device;
-    }
-    if (n == 0) {
-      break;
-    }
-  }
-  return {};
-}
-
-inline android::base::Result<std::vector<std::string>> ListChildLoopDevices(
-    const std::string& name) {
-  using android::base::Error;
-  using android::dm::DeviceMapper;
-
-  DeviceMapper& dm = DeviceMapper::Instance();
-  std::string dm_path;
-  if (!dm.GetDmDevicePathByName(name, &dm_path)) {
-    return Error() << "Failed to get path of dm device " << name;
-  }
-  // It's a little bit sad we can't use ConsumePrefix here :(
-  constexpr std::string_view kDevPrefix = "/dev/";
-  if (!android::base::StartsWith(dm_path, kDevPrefix)) {
-    return Error() << "Illegal path " << dm_path;
-  }
-  dm_path = dm_path.substr(kDevPrefix.length());
-  std::vector<std::string> children;
-  std::string dir = "/sys/" + dm_path + "/slaves";
-  auto status = WalkDir(dir, [&](const auto& entry) {
-    std::error_code ec;
-    if (entry.is_symlink(ec)) {
-      children.push_back("/dev/block/" + entry.path().filename().string());
-    }
-  });
-  if (!status.ok()) {
-    return status.error();
-  }
-  return children;
-}
-
 }  // namespace apex
 }  // namespace android
 
@@ -444,25 +312,12 @@
 namespace apex {
 
 namespace testing {
-
-// "preinstalledModulePath" is an optional in ApexInfoList.xsd.
-// getPreinstalledModulePath() should be called when hasPreinstalledModulePath()
-// returns true. Introducing a simple wrapper which returns optional<string>.
-inline std::optional<std::string> getPreinstalledModulePath(
-    const ApexInfo& obj) {
-  if (obj.hasPreinstalledModulePath()) {
-    return obj.getPreinstalledModulePath();
-  }
-  return std::nullopt;
-}
-
 MATCHER_P(ApexInfoXmlEq, other, "") {
   using ::testing::AllOf;
   using ::testing::Eq;
   using ::testing::ExplainMatchResult;
   using ::testing::Field;
   using ::testing::Property;
-  using ::testing::ResultOf;
 
   return ExplainMatchResult(
       AllOf(
@@ -470,8 +325,9 @@
                    Eq(other.getModuleName())),
           Property("modulePath", &ApexInfo::getModulePath,
                    Eq(other.getModulePath())),
-          ResultOf(&getPreinstalledModulePath,
-                   Eq(getPreinstalledModulePath(other))),
+          Property("preinstalledModulePath",
+                   &ApexInfo::getPreinstalledModulePath,
+                   Eq(other.getPreinstalledModulePath())),
           Property("versionCode", &ApexInfo::getVersionCode,
                    Eq(other.getVersionCode())),
           Property("isFactory", &ApexInfo::getIsFactory,
@@ -489,10 +345,8 @@
   *os << "apex_info: {\n";
   *os << "  moduleName : " << apex.getModuleName() << "\n";
   *os << "  modulePath : " << apex.getModulePath() << "\n";
-  if (apex.hasPreinstalledModulePath()) {
-    *os << "  preinstalledModulePath : " << apex.getPreinstalledModulePath()
-        << "\n";
-  }
+  *os << "  preinstalledModulePath : " << apex.getPreinstalledModulePath()
+      << "\n";
   *os << "  versionCode : " << apex.getVersionCode() << "\n";
   *os << "  isFactory : " << apex.getIsFactory() << "\n";
   *os << "  isActive : " << apex.getIsActive() << "\n";
diff --git a/apexd/apexd_testdata/Android.bp b/apexd/apexd_testdata/Android.bp
index 0307690..0e7039a 100644
--- a/apexd/apexd_testdata/Android.bp
+++ b/apexd/apexd_testdata/Android.bp
@@ -105,7 +105,7 @@
   name: "gen_key_mismatch_capex",
   out: ["com.android.apex.compressed_different_key.capex"],
   srcs: [":apex.apexd_test_no_inst_key"],
-  tools: ["soong_zip", "zipalign", "conv_apex_manifest", "apex_compression_tool", "avbtool"],
+  tools: ["soong_zip", "zipalign", "conv_apex_manifest", "apex_compression_tool"],
   cmd: "unzip -q $(in) -d $(genDir) && " +
        "$(location conv_apex_manifest) setprop name com.android.apex.compressed $(genDir)/apex_manifest.pb && " +
        "$(location soong_zip) -d -C $(genDir) -D $(genDir) " +
@@ -113,9 +113,8 @@
        "-o $(genDir)/unaligned.apex && " +
        "$(location zipalign) -f 4096 $(genDir)/unaligned.apex " +
        "$(genDir)/com.android.apex.compressed_different_key.apex && " +
-       "HOST_OUT_BIN=$$(dirname $(location apex_compression_tool)) && " +
        "$(location apex_compression_tool) compress " +
-       "--apex_compression_tool_path=\"$$HOST_OUT_BIN\" " +
+       "--apex_compression_tool_path='out/soong/host/linux-x86/bin:prebuilts/sdk/tools/linux/bin' " +
        "--input=$(genDir)/com.android.apex.compressed_different_key.apex " +
        "--output=$(genDir)/com.android.apex.compressed_different_key.capex"
 }
@@ -204,17 +203,6 @@
 }
 
 apex {
-    name: "apex.apexd_test_erofs",
-    manifest: "manifest.json",
-    file_contexts: ":apex.test-file_contexts",
-    prebuilts: ["sample_prebuilt_file"],
-    key: "com.android.apex.test_package.key",
-    installable: false,
-    min_sdk_version: "current",
-    payload_fs_type: "erofs",
-}
-
-apex {
     name: "apex.apexd_test_no_hashtree",
     manifest: "manifest.json",
     file_contexts: ":apex.test-file_contexts",
@@ -281,6 +269,60 @@
 }
 
 apex_key {
+    name: "com.android.apex.test_package.preinstall.key",
+    public_key: "com.android.apex.test_package.preinstall.avbpubkey",
+    private_key: "com.android.apex.test_package.preinstall.pem",
+    installable: false,
+}
+
+apex {
+    name: "apex.apexd_test_preinstall",
+    manifest: "manifest_preinstall.json",
+    file_contexts: ":apex.test-file_contexts",
+    prebuilts: ["sample_prebuilt_file"],
+    key: "com.android.apex.test_package.preinstall.key",
+    binaries: ["apex_test_preInstallHook"],
+    installable: false,
+    updatable: false,
+}
+
+apex_key {
+    name: "com.android.apex.test_package.postinstall.key",
+    public_key: "com.android.apex.test_package.postinstall.avbpubkey",
+    private_key: "com.android.apex.test_package.postinstall.pem",
+    installable: false,
+}
+
+apex {
+    name: "apex.apexd_test_postinstall",
+    manifest: "manifest_postinstall.json",
+    file_contexts: ":apex.test-file_contexts",
+    prebuilts: ["sample_prebuilt_file"],
+    key: "com.android.apex.test_package.postinstall.key",
+    binaries: ["apex_test_postInstallHook"],
+    installable: false,
+    updatable: false,
+}
+
+apex_key {
+    name: "com.android.apex.test_package.prepostinstall.fail.key",
+    public_key: "com.android.apex.test_package.prepostinstall.fail.avbpubkey",
+    private_key: "com.android.apex.test_package.prepostinstall.fail.pem",
+    installable: false,
+}
+
+apex {
+    name: "apex.apexd_test_prepostinstall.fail",
+    manifest: "manifest_prepostinstall.fail.json",
+    file_contexts: ":apex.test-file_contexts",
+    prebuilts: ["sample_prebuilt_file"],
+    key: "com.android.apex.test_package.prepostinstall.fail.key",
+    binaries: ["apex_test_prePostInstallHookFail"],
+    installable: false,
+    updatable: false,
+}
+
+apex_key {
     name: "com.android.apex.test_package.no_inst_key.key",
     public_key: "com.android.apex.test_package.no_inst_key.avbpubkey",
     private_key: "com.android.apex.test_package.no_inst_key.pem",
@@ -308,17 +350,6 @@
     updatable: false,
 }
 
-apex {
-    name: "apex.apexd_test_erofs_no_inst_key",
-    manifest: "manifest_no_inst_key.json",
-    file_contexts: ":apex.test-file_contexts",
-    prebuilts: ["sample_prebuilt_file"],
-    key: "com.android.apex.test_package.no_inst_key.key",
-    installable: false,
-    payload_fs_type: "erofs",
-    updatable: false,
-}
-
 apex_key {
     name: "com.android.apex.test_package_2.key",
     public_key: "com.android.apex.test_package_2.avbpubkey",
@@ -336,6 +367,21 @@
     updatable: false,
 }
 
+sh_binary {
+    name: "apex_test_preInstallHook",
+    src: "preInstallHook.sh",
+}
+
+sh_binary {
+    name: "apex_test_postInstallHook",
+    src: "postInstallHook.sh",
+}
+
+sh_binary {
+    name: "apex_test_prePostInstallHookFail",
+    src: "fail.sh",
+}
+
 apex {
     name: "apex.apexd_test_nocode",
     manifest: "manifest_nocode.json",
@@ -510,57 +556,3 @@
       "test.rebootless_apex_priv_app_in_apex",
     ],
 }
-
-apex_test {
-    name: "apex.apexd_test_classpath",
-    bootclasspath_fragments: ["apex.apexd_test_bootclasspath-fragment"],
-    systemserverclasspath_fragments: ["apex.apexd_test_systemserverclasspath-fragment"],
-    manifest: "manifest.json",
-    prebuilts: ["sample_prebuilt_file"],
-    key: "com.android.apex.test_package.key",
-    file_contexts: ":apex.test-file_contexts",
-    installable: false, // Should never be installed on the systemimage
-    updatable: false,
-}
-
-bootclasspath_fragment {
-    name: "apex.apexd_test_bootclasspath-fragment",
-    contents: ["test_framework-apexd"],
-}
-
-systemserverclasspath_fragment {
-    name: "apex.apexd_test_systemserverclasspath-fragment",
-    contents: ["test_service-apexd"],
-}
-
-java_sdk_library {
-    name: "test_framework-apexd",
-    defaults: ["framework-module-defaults"],
-    srcs: ["src/com/android/apex/test/Test.java"],
-    permitted_packages: ["com.android.apex.test"],
-    min_sdk_version: "30",
-
-    // Test only SDK, don't check against released APIs.
-    unsafe_ignore_missing_latest_api: true,
-    // Output the api files to a special directory that won't trigger an API
-    // review as it is a test only API.
-    api_dir: "apis_for_tests",
-    // Testing only.
-    no_dist: true,
-}
-
-java_sdk_library {
-    name: "test_service-apexd",
-    defaults: ["framework-system-server-module-defaults"],
-    srcs: ["src/com/android/apex/test/Test.java"],
-    permitted_packages: ["com.android.apex.test"],
-    min_sdk_version: "30",
-
-    // Test only SDK, don't check against released APIs.
-    unsafe_ignore_missing_latest_api: true,
-    // Output the api files to a special directory that won't trigger an API
-    // review as it is a test only API.
-    api_dir: "apis_for_tests",
-    // Testing only.
-    no_dist: true,
-}
diff --git a/apexd/apexd_testdata/apis_for_tests/current.txt b/apexd/apexd_testdata/apis_for_tests/current.txt
deleted file mode 100644
index 7ceb448..0000000
--- a/apexd/apexd_testdata/apis_for_tests/current.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-// Signature format: 2.0
-package com.android.apex.test {
-
-  public class Test {
-    ctor public Test();
-  }
-
-}
-
diff --git a/apexd/apexd_testdata/apis_for_tests/module-lib-current.txt b/apexd/apexd_testdata/apis_for_tests/module-lib-current.txt
deleted file mode 100644
index d802177..0000000
--- a/apexd/apexd_testdata/apis_for_tests/module-lib-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apexd/apexd_testdata/apis_for_tests/module-lib-removed.txt b/apexd/apexd_testdata/apis_for_tests/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apexd/apexd_testdata/apis_for_tests/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apexd/apexd_testdata/apis_for_tests/removed.txt b/apexd/apexd_testdata/apis_for_tests/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apexd/apexd_testdata/apis_for_tests/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apexd/apexd_testdata/apis_for_tests/system-current.txt b/apexd/apexd_testdata/apis_for_tests/system-current.txt
deleted file mode 100644
index d802177..0000000
--- a/apexd/apexd_testdata/apis_for_tests/system-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apexd/apexd_testdata/apis_for_tests/system-removed.txt b/apexd/apexd_testdata/apis_for_tests/system-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apexd/apexd_testdata/apis_for_tests/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apexd/apexd_testdata/apis_for_tests/system-server-current.txt b/apexd/apexd_testdata/apis_for_tests/system-server-current.txt
deleted file mode 100644
index d802177..0000000
--- a/apexd/apexd_testdata/apis_for_tests/system-server-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apexd/apexd_testdata/apis_for_tests/system-server-removed.txt b/apexd/apexd_testdata/apis_for_tests/system-server-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/apexd/apexd_testdata/apis_for_tests/system-server-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/apexd/apexd_testdata/com.android.apex.test_package.postinstall.avbpubkey b/apexd/apexd_testdata/com.android.apex.test_package.postinstall.avbpubkey
new file mode 100644
index 0000000..97f26a2
--- /dev/null
+++ b/apexd/apexd_testdata/com.android.apex.test_package.postinstall.avbpubkey
Binary files differ
diff --git a/apexd/apexd_testdata/com.android.apex.test_package.postinstall.pem b/apexd/apexd_testdata/com.android.apex.test_package.postinstall.pem
new file mode 100644
index 0000000..af1efd9
--- /dev/null
+++ b/apexd/apexd_testdata/com.android.apex.test_package.postinstall.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKAIBAAKCAgEAqxHLv23c1mE6rgPsLORpH5iEZYR9QUxFPDXDTqNK43mUSnJ8
+XwScbQ8JXJNsTnpCshk1AlE/1vXTURMI2Fa1ns8G8QEZZaEmEhteRm1kH5QjR0YU
+Z6kJjGfVP4G7YCD0q0Pq5r3jXfHrUDDPexvt7yuprnYJB89Sniv2atTZwC7RG/PW
+iVK3ZF/lX9ZL9ko0xOUlJSIkIfN69kzF/8aeYLwPohTeYdBP6Wq/if0YKuB5h5xE
++OVBJpi0a2IymOTLq0zg91BjTJKVvn4Nx7UTdPNp7kk6Pt82SFOFIi/1H7Hlnslp
+pDXdc5nqwod4eVXE2ag7pMIjwPP+aairJ1aXcKdtwqXnOQ3bJOjAJJQHj8eHe1RX
+lG5VovGipex5ImBqRfj3jrZSZNiJzPCOIDUTHxImY6/81UAWxWGrnT3niW0jKjTa
+Sfi+izV8b+2CLrpE4oUCDQjHZ6nDp82xkSlm0lhTGDK417NuVNvsD1eNFnpsyRmr
+xpaBg8gcYTGgNvQ5uSrFXN9b6O5Z6nYnjLLUjvqbt1gTVqJH+FaKsMN6Xk4M46h6
+nqGEQHUIsPUx+dAbrb+Ard5CIJvey2m3DDpoHzriyZh8P3pNdOt0+OIzrUCAxyp2
+i9khNCE2lDOczWvKDwGczmmFlB0wj5YP4sDG906oTlcTC2IeVwtEOxjyePsCAwEA
+AQKCAgEApsnmBhE+ZEJN7QXkCez01ZplU3k2iiirxEWC07P/uwN54o/21MlxHh+v
+9/PAgE9RocVT2puPC62Hx58wW4VG9LxSvz1cHqtcrADFDRNwsB1FvCMGl/7GUX+W
++aEqKFJZWnYQm8H94UWSMRA16ojTlgHTIUbyDQxFN/QTABvg5jB/LqqxvBfKuHGK
++MK+MzYsduAXNDoyUmvKskMuNO/Y0OXqtBN2spVgpGqwrv/1xTAxLVfeI3GZ8OCn
+357RSCKitLRzDo3xEuJEX4MVOmZAvyDoYixBPrVwfln4DtoFO06+Wu9zMWhXLnOd
+4OYmPt6x26jb5gpmw6TgovGRVfxmDxa3uDr9LNfobRnSHru1qCrq9SBcHi61sj9O
+OqGNQUWXBzUKwfFRwar4KOb/kKgcgsTkkRPEStNenDSq0VHIIkrNQVIa0gkc7Bgw
+jktRX/q0zefJmxZATX3VPQQlU4bOd8dxYvRAByOVTp8AYSxMI0fHpB/+nTtMZhYm
+6CckK2RgJ4MdJ3lONCTf+fFwv0WyQmSE7vsXMv0cyjD0NoGw+M4timns7Ut8NZI2
+tji6X0HDTAtuNg31+nhCd9QHL/sqd3J7JHFjF9e6Zqe0OhRiN6CyBuZuOBjLAI86
+HdOv0QYz/+lt6cnr5keuxtqek/Eqr2jb4pcufUzjMQvN8a7sM6kCggEBANnclYiX
+Fs+chM/6oj5JQu5Ft+TiIVbfBx0RqW6ZVxnXC5ilXV/aAHCFrepma7UjYiY53/Lb
+bJtnmTyprqM8JmVAskpxV8YZJ++ZgOIHOzCXrMs7KHstbVCN750aqAdPwCOU11/V
+vKhsxyaEPQDEOO17bTHFIBkGD6u3VQ3GGgAauomNwKfzOqBAmqqiK5DSNQzk5Qs5
+UCi7ASNSK0RQRt8Q2Wr54iOn3G7c+x1L4VmrYNFg01Acwog7bVDYRLQx8lemoN/q
+uaoDvzs/GtkD3PZAY7H4vAba5mqZW9qUT6xfv11L8ijQSY/EF2K/SYc7g664xlY4
+8bm109ndgRApTXcCggEBAMkEO82lrhufs5ppSVcDCAL2qIr3UQBg7xq2nXe3fGKl
+p406vz7wB1+p0P1lJ0H654hUi9CADPsrcjZTy7zXuM4a/7iFZjmOrawat7VSrF3v
+YL6bTZpO8TOCn7V4UJM6bPjzReCa87OD9m2LwDHxsFaPQevnivptxiUNfDt06oWy
+efifjBGQtyvIfYfr5MA6zUFLnGa/pYJvD26eZ1IP2fAedP+JrH4D38Dn+LiiVaYJ
+fOFkEtZPWnQ0sGhapY5iCyIuk9ffaDoKiNXxkPclARKp1wLC8eh/fHayUmT9ZgR3
+YCu14MjjegvqQPpdjqD17cBJW6fbPXlWqfzH105TgZ0CggEALBbvEDB7hlKHsktn
+sDFFYVEssR5uXtVN7D0Zy+8uaGVTzHWS2wYUVrFHDAvkOklJ4LCPuOddKGoj4dn5
+JMHUh2M7ccNUXxvSMDQhmBychu37Izn6rEr6N3YyCtpNLQWfvdOubo+j2XYCK7JR
+YilT2APFim/5WfcXDspQZTQ1KNY/7/yHA7Y+pBXO9z9Qj8Nqxww/qjDUHxoRVeOY
+LAAPB6+yQGsHr+2Vt73y9+/WUD5Vnqn4udrIJ6fXLKhH5yvAfqqTHh2zq0uM1OGl
+fkvA2PkY8/iBnOWKAgK9SxP+t8S8xpXLESVt7bFihjJuH/cUZDSyttpZWRsKH6or
+J2kkawKCAQA1xkgpT3UwNpzZZekUud7ezBVyd47Xxxav0sJ1UESaLy6PfXPD5npS
+gR9DalgCMpjVw6hTcq4GUy0Ok4QhVKQ/nsFiH22lYCHdtJgIjcFGr871rp4n9Y5Y
+9Uy8Qx9rA2o7fvjmiQ1ArMCztXsI4VsHDPPZo+tt6wfiyaS+UxyZ/5DZjfTujgQy
+VkQepGBhfFmEajHA2uvv5L4AHagOL+dhcQRjh/T5ERg+hs/mtKas8ETUFu1jH39X
+LvEyOW2olVndHxC14zICtOa+NQ1O0DtlPsIiHvyP8erd5f5cvd0YvMahatpjY1c2
+8MfJMlYBgUjE89rtIJ1lZGW9FcjnTzeRAoIBAHV5uS9s5sscmJT4igPazfMEl3qI
+6UJUH0Lhwr6CGPc078KSebXDFeqAzDKkCgP6tmaeLFrzQDYWPcXRzKo7KcMDpLsT
+rKNAmldhTmBAzC4bC0d9WFu/hg8A04p10zwsAD458S68KJz9hy1YuXyzwMYhcH6G
+V7fqir7VbieRsXmTtaAtEDz4FqPsL4X+5mGi6cUio+ttTrYs5udYBXs3MvyZgvT9
+b6nntwV/tWpleurt3dm8dFU6aRJWvEysnXiNhQeUxO/z4aTkdFgVBidqFIfmJ3v5
+XzJf+c4/NURzKP4XFBsAIDjSEVTH00g5fs5LUeSXU3h2rQmXezMdMzMTx9U=
+-----END RSA PRIVATE KEY-----
diff --git a/apexd/apexd_testdata/com.android.apex.test_package.preinstall.avbpubkey b/apexd/apexd_testdata/com.android.apex.test_package.preinstall.avbpubkey
new file mode 100644
index 0000000..f3593c4
--- /dev/null
+++ b/apexd/apexd_testdata/com.android.apex.test_package.preinstall.avbpubkey
Binary files differ
diff --git a/apexd/apexd_testdata/com.android.apex.test_package.preinstall.pem b/apexd/apexd_testdata/com.android.apex.test_package.preinstall.pem
new file mode 100644
index 0000000..09f861b
--- /dev/null
+++ b/apexd/apexd_testdata/com.android.apex.test_package.preinstall.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKgIBAAKCAgEA43h4SU45Am/C2YlZllyBFQiOVCn2Z+ngoTewe9o/4++Z7/uS
+3sWyHahm9PJ3KDihmxI1gQxUMuoj1QH0oPzM19obw+Ubx0S5JeZLP3C86AuLwrxn
+ftkH1m/E8qbkIZ+bT7rWC121ZglXhYH+LPHGtocYAChsPIczHYltyyQXiSFBDKse
+b32NFJ1TOTcDkrIowajZzEFb587wCkDGOvwQlj51NmSAM32rL9vIxevzx4OKQHJx
+4IMy70c1dAi/zTiUfXIbEQRbr8KYAORnUPhtJ28olvVDcHgeQlVYu2CTWzftCvs/
+9RnrpKZOvohBV0Lx6pNG7At56oyNVhdmL4PyoLfhpATXGSAplxAsn8yHdYyImOcP
+ZioZmXfggQUVXabDH+8tDnTOu6no0p5kcyxqL+965RCnpLpo1XSi3fDVbq037Qq2
+F+XubJ30CGNYqR4HjpfqoniJIyrVz43JYTiGhvCaMEgcjHMi+CzHFa67Amu/kogK
+aOVnFe3t1YVe7sW5H+xz+tqH0foYdpGXKwF1y0BLWOlcvypNQqtiPO0uCJmgfu0q
+blJ+KAa/AGg3Iob5y9HqR87Ee7S+/c3J+jtQBzis0VA1m9ajSpy2WwaNe7yHuRmu
+v4iQsJFW8phOHLoKnUeuGqWj77pePIzO101sqPtTv/T3NOx7sjLpX4X9YgECAwEA
+AQKCAgAbHGmhuwv6aV2c1czyqdXMrvdfupyep/ZY4K1NJacFwLHlM2O+32sqM78J
+pLhk99LzC4mK9vA2HUfmBFSmt1qmw10ZzP2xk1RJ2xfO2N36/h1LOW9QZAeWHD4p
++ZApHb/CEe+e7S1ImwZuaB7mNm7LpHBM3ISB9k82TwHh+0w+0NLS8rYu7ZTaByI7
+KH5phohrBHfo60VL7JMZdbzqnM5RSeJoeDP7bxfvHU/hnwywE9JvefRuoNR6Rk9t
+o/lQOVUhWm81aQKQgS3itVZHBUTlNU9uJo9CIV7h4xAvTQRjE9hRvb5StSMrvZKX
+DOBUySrSHXmPepKuTNAvmZxZP220Voalt0WdHFI6xzuv1e3wO/3/jvVYLfKKhHw8
+WMRyZKhBAYzYCbeRJIKP0z+BrHbF+V+oX/cWjtEU9BDZ6KcQ401FgDLyPyGVfBbb
+GgqC0heOvIkaoK40XS/OEDb9BCIjgWlTZjGbeJzNmZFap9ZzRWw18W5QZdTC6X4x
+wfZiTf7k1DngcxN+kGF6ox42UycPnVKARVrBa9p7eS1NYugxXXJZgd0Oqq9DuEgt
+A1iXwkgMqcdCUMMOb/Fng7p3hUY0ANTVqnKnvtaxnq7h3SBXLfSHi1ySHzRZPb2Z
+nDM0+8UeF+W33q3DVV/YGh5MA4lMHoWmrxAoCs3YbVxz6Ano/QKCAQEA+kB38OFl
+IP0N1OWOEGJoOobLGi/XCz8qYjC5RC2CJ7V5yPR9gcVS1F8fQjsNnaYAigF0HcKS
+bkeeuXqr6KKQlhc2sKEFjVyaejT9cMMtObVlgVYkSv60cFQ/lKqnH9hGFspG2tTu
+6IjS5O7+AiRrpVvkMOGv9vvUE0TnU8cVM9f9euCP8HCGs8hE4+45tQmMK5iX0Tqm
+qKgXfhvKpAOdgbP3RKrboql+EtjF1ks7lYuyI6dfchLbaoQtU5oe09tqtjUG9iF5
+toUq/Pu+WTbWGyovcFHDS8QEKrdUe5IofIonodMZ76DJSCGrO8zp5nPDjrrhTiMN
+vx/3OZ9xM9gOSwKCAQEA6LILAugGENQCamyxIP+mtNBcuvtQerIr/q/quT5HKAyU
+GNqdpbwyp9w3Hm/Uy2q60Dt5J50MmQewrewvwQvp+bD1XIaWU1TOxkurxkDEVgkL
+8uTiA/SnDgJsNznCFt99/VhTG2BnW7nU1yKD/KcBXHJzQpnly2krCO8GxPEV5RY8
+Ebh++UzThYAszuXjY+jL3dzyuCLsJJHBbOW+aeNjNOfgoieGHCbqAjE9TlIv74Cv
+Zjnb39gphBThJ7HU7F1EWH1HvK+bs6+X9XM2MQ04+U7v0pbqFoDzQYc42KKdD7Z5
+4BGcxOdj0/a1wz7iGb7uBFmCoX3jPMQTfYl4teqxYwKCAQEA7GQHqJgRYlcIQMpT
+JzD+CgMYSfVU6n/Rdo1WBIwEfaQUlXo2MGaINqpgKb0EwJ11tudmm1IX5mprCgRR
+7V/aupzVAYYpa35FQhlaKrGDwBaU+ta3U8xEADPlF3cYhaFTm+WZhs9LmobcyHrl
+oHps4Pfrly0pfmIl08nrxpyxb5ahD/ien158L8mHIdP/2P5a1TfAeVkw4vJdtrdj
+9QihOUsZ0VigPohi2kTApQvODha2wK0zINulPnn7IxTb9/41UEbI+6llgr9Ke00G
+YtnE6EYyJ6RkmeZglUU2XcAT1IjgpSF3R3+XgzaivMt1S0ahPOtVNu0v6BG3BEyT
+r4hw/wKCAQEAu6Nua66LzaAYPpddEf31ANMQI5sqH3ZzMZHLlgrZODtEZPJMs2uZ
+8XALZljJYCq1b9q1bLMgiHoCB41wSJwB1V3TzQOeTp4RiydT4a8yYyoyX3AfrQ7o
+csyTVMkXcHhR0Swa//VyAy5LqhtkESTeXRzRQsB049zvXenZLJA3lp6iW6vJf+Bq
+pLlh6IjKHzOGyWY0tzU59JcwQU7Vh+9bfTsKEdgLNcJPausnw3NUwi2jwqwfWFan
+y6FGmkq1JtBin3SOl2GIDZIn2D5KUa2W5rq3erpFE1ZyUcHnnhEq05PSnVO2dbUc
+87x6f3HCwv4KUqmXRAAOcF6wVMe49gDFfwKCAQEAo00/8sbxTMU9lUz2muJ6Xzy2
+MlGRnYK01u4zXerojWxNowwjNXUhKU8tsEcV2OdQz07CxkKLps+5fSZ7MJfqXU/m
+HTRryb9rPMxuwK77Mnx4dWqeMnHtC+6bA0ScZHC7DbAXbkUVc36DVFssIjRkOQDw
+MMUU0qyIrvoVq/J5wZxWquEh2jt0MtKotLPXDIzJM2G0cc7e7yw09fmkSpc7xQmC
+ISgkR6C4+W2eoo3+Iq/lPoV1igg+07UZkdZS5b96asETDVHEL9Ba33J8WoOpOoEE
+gSgpS/5XubFhK4KMFR8HkIpS860+Scl3VbsFUwvwGAzkEmucseq9XaavUcfXbw==
+-----END RSA PRIVATE KEY-----
diff --git a/apexd/apexd_testdata/manifest_postinstall.json b/apexd/apexd_testdata/manifest_postinstall.json
new file mode 100644
index 0000000..80e2eeb
--- /dev/null
+++ b/apexd/apexd_testdata/manifest_postinstall.json
@@ -0,0 +1,5 @@
+{
+  "name": "com.android.apex.test_package.postinstall",
+  "version": 1,
+  "postInstallHook": "bin/apex_test_postInstallHook"
+}
diff --git a/apexd/apexd_testdata/manifest_preinstall.json b/apexd/apexd_testdata/manifest_preinstall.json
new file mode 100644
index 0000000..91a3f23
--- /dev/null
+++ b/apexd/apexd_testdata/manifest_preinstall.json
@@ -0,0 +1,5 @@
+{
+  "name": "com.android.apex.test_package.preinstall",
+  "version": 1,
+  "preInstallHook": "bin/apex_test_preInstallHook"
+}
diff --git a/apexd/apexd_testdata/manifest_prepostinstall.fail.json b/apexd/apexd_testdata/manifest_prepostinstall.fail.json
new file mode 100644
index 0000000..218c3f8
--- /dev/null
+++ b/apexd/apexd_testdata/manifest_prepostinstall.fail.json
@@ -0,0 +1,6 @@
+{
+  "name": "com.android.apex.test_package.prepostinstall.fail",
+  "version": 1,
+  "preInstallHook": "bin/apex_test_prePostInstallHookFail",
+  "postInstallHook": "bin/apex_test_prePostInstallHookFail"
+}
diff --git a/apexd/apexd_testdata/postInstallHook.sh b/apexd/apexd_testdata/postInstallHook.sh
new file mode 100644
index 0000000..3bee5a8
--- /dev/null
+++ b/apexd/apexd_testdata/postInstallHook.sh
@@ -0,0 +1,15 @@
+#!/system/bin/sh
+
+# Side test for b/124769206.
+if [ -z "$BOOTCLASSPATH" ] ; then
+  log -t apex_tests -p f "BOOTCLASSPATH is perceived as empty"
+  exit 1
+fi
+
+# Look for the session data, but do not fail and instead print a literal
+# otherwise. Sleep is an attempt to ensure that the message always reaches
+# logcat.
+/system/bin/logwrapper \
+  /system/bin/sh -c \
+    'ls /apex/com.android.apex.test_package/etc/sample_prebuilt_file \
+     || echo "PostInstall Test" ; sleep 5s'
diff --git a/apexd/apexd_testdata/preInstallHook.sh b/apexd/apexd_testdata/preInstallHook.sh
new file mode 100644
index 0000000..2d341a8
--- /dev/null
+++ b/apexd/apexd_testdata/preInstallHook.sh
@@ -0,0 +1,15 @@
+#!/system/bin/sh
+
+# Side test for b/124769206.
+if [ -z "$BOOTCLASSPATH" ] ; then
+  log -t apex_tests -p f "BOOTCLASSPATH is perceived as empty"
+  exit 1
+fi
+
+# Look for the session data, but do not fail and instead print a literal
+# otherwise. Sleep is an attempt to ensure that the message always reaches
+# logcat.
+/system/bin/logwrapper \
+  /system/bin/sh -c \
+    'ls /apex/com.android.apex.test_package/etc/sample_prebuilt_file \
+     || echo "PreInstall Test" ; sleep 5s'
diff --git a/apexd/apexd_testdata/src/com/android/apex/test/Test.java b/apexd/apexd_testdata/src/com/android/apex/test/Test.java
deleted file mode 100644
index b24fabf..0000000
--- a/apexd/apexd_testdata/src/com/android/apex/test/Test.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2021 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.apex.test;
-
-public class Test {
-
-    public Test() {}
-}
diff --git a/apexd/apexd_utils.h b/apexd/apexd_utils.h
index 782bd2f..23194eb 100644
--- a/apexd/apexd_utils.h
+++ b/apexd/apexd_utils.h
@@ -44,6 +44,49 @@
 namespace android {
 namespace apex {
 
+inline int WaitChild(pid_t pid) {
+  int status;
+  pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
+
+  if (got_pid != pid) {
+    PLOG(WARNING) << "waitpid failed: wanted " << pid << ", got " << got_pid;
+    return 1;
+  }
+
+  if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+    return 0;
+  } else {
+    return status;
+  }
+}
+
+inline android::base::Result<void> ForkAndRun(
+    const std::vector<std::string>& args) {
+  LOG(DEBUG) << "Forking : " << android::base::Join(args, " ");
+  std::vector<const char*> argv;
+  argv.resize(args.size() + 1, nullptr);
+  std::transform(args.begin(), args.end(), argv.begin(),
+                 [](const std::string& in) { return in.c_str(); });
+
+  pid_t pid = fork();
+  if (pid == -1) {
+    // Fork failed.
+    return android::base::ErrnoError() << "Unable to fork";
+  }
+
+  if (pid == 0) {
+    execv(argv[0], const_cast<char**>(argv.data()));
+    PLOG(ERROR) << "execv failed";
+    _exit(1);
+  }
+
+  int rc = WaitChild(pid);
+  if (rc != 0) {
+    return android::base::Error() << "Failed run: status=" << rc;
+  }
+  return {};
+}
+
 template <typename Fn>
 android::base::Result<void> WalkDir(const std::string& path, Fn fn) {
   namespace fs = std::filesystem;
@@ -159,11 +202,6 @@
   if (android_reboot(ANDROID_RB_RESTART2, 0, nullptr) != 0) {
     LOG(ERROR) << "Failed to reboot device";
   }
-  // Wait for reboot to complete as we expect this to be a terminal
-  // command. Crash apexd if reboot does not complete even after
-  // waiting an arbitrary significant amount of time.
-  std::this_thread::sleep_for(std::chrono::seconds(120));
-  LOG(FATAL) << "Device did not reboot within 120 seconds";
 }
 
 inline android::base::Result<void> WaitForFile(
@@ -334,17 +372,6 @@
   return {};
 }
 
-inline android::base::Result<std::string> GetfileconPath(
-    const std::string& path) {
-  char* ctx;
-  if (getfilecon(path.c_str(), &ctx) < 0) {
-    return android::base::ErrnoError() << "Failed to getfilecon " << path;
-  }
-  std::string ret(ctx);
-  freecon(ctx);
-  return ret;
-}
-
 }  // namespace apex
 }  // namespace android
 
diff --git a/apexd/apexd_verity.cpp b/apexd/apexd_verity.cpp
index 5db78bf..0008f6d 100644
--- a/apexd/apexd_verity.cpp
+++ b/apexd/apexd_verity.cpp
@@ -17,17 +17,14 @@
 
 #include "apexd_verity.h"
 
+#include <filesystem>
+#include <vector>
+
 #include <android-base/file.h>
 #include <android-base/result.h>
 #include <android-base/unique_fd.h>
 #include <verity/hash_tree_builder.h>
 
-#include <filesystem>
-#include <iomanip>
-#include <sstream>
-#include <string>
-#include <vector>
-
 #include "apex_constants.h"
 #include "apex_file.h"
 #include "apexd_utils.h"
@@ -202,15 +199,5 @@
   // TODO(b/120058143): on boot complete, remove unused hashtree files
 }
 
-std::string BytesToHex(const uint8_t* bytes, size_t bytes_len) {
-  std::ostringstream s;
-
-  s << std::hex << std::setfill('0');
-  for (size_t i = 0; i < bytes_len; i++) {
-    s << std::setw(2) << static_cast<int>(bytes[i]);
-  }
-  return s.str();
-}
-
 }  // namespace apex
 }  // namespace android
diff --git a/apexd/apexd_verity.h b/apexd/apexd_verity.h
index deb3ac0..e3c8427 100644
--- a/apexd/apexd_verity.h
+++ b/apexd/apexd_verity.h
@@ -23,8 +23,6 @@
 namespace android {
 namespace apex {
 
-std::string BytesToHex(const uint8_t* bytes, size_t len);
-
 enum PrepareHashTreeResult {
   kReuse = 0,
   KRegenerate = 1,
diff --git a/apexd/apexservice.cpp b/apexd/apexservice.cpp
index 801f634..4f3d2fc 100644
--- a/apexd/apexservice.cpp
+++ b/apexd/apexservice.cpp
@@ -63,16 +63,6 @@
   return BinderStatus::ok();
 }
 
-BinderStatus CheckCallerSystemOrRoot(const std::string& name) {
-  uid_t uid = IPCThreadState::self()->getCallingUid();
-  if (uid != AID_ROOT && uid != AID_SYSTEM) {
-    std::string msg = "Only root and system_server are allowed to call " + name;
-    return BinderStatus::fromExceptionCode(BinderStatus::EX_SECURITY,
-                                           String8(name.c_str()));
-  }
-  return BinderStatus::ok();
-}
-
 class ApexService : public BnApexService {
  public:
   using BinderStatus = ::android::binder::Status;
@@ -89,12 +79,16 @@
   BinderStatus getSessions(std::vector<ApexSessionInfo>* aidl_return) override;
   BinderStatus getStagedSessionInfo(
       int session_id, ApexSessionInfo* apex_session_info) override;
-  BinderStatus getStagedApexInfos(const ApexSessionParams& params,
-                                  std::vector<ApexInfo>* aidl_return) override;
+  BinderStatus activatePackage(const std::string& package_path) override;
+  BinderStatus deactivatePackage(const std::string& package_path) override;
   BinderStatus getActivePackages(std::vector<ApexInfo>* aidl_return) override;
   BinderStatus getActivePackage(const std::string& package_name,
                                 ApexInfo* aidl_return) override;
   BinderStatus getAllPackages(std::vector<ApexInfo>* aidl_return) override;
+  BinderStatus preinstallPackages(
+      const std::vector<std::string>& paths) override;
+  BinderStatus postinstallPackages(
+      const std::vector<std::string>& paths) override;
   BinderStatus abortStagedSession(int session_id) override;
   BinderStatus revertActiveSessions() override;
   BinderStatus resumeRevertIfNeeded() override;
@@ -143,9 +137,6 @@
   if (!debug_check.isOk()) {
     return debug_check;
   }
-  if (auto is_root = CheckCallerIsRoot("stagePackages"); !is_root.isOk()) {
-    return is_root;
-  }
   LOG(DEBUG) << "stagePackages() received by ApexService, paths "
              << android::base::Join(paths, ',');
 
@@ -164,10 +155,6 @@
 
 BinderStatus ApexService::unstagePackages(
     const std::vector<std::string>& paths) {
-  if (auto check = CheckCallerSystemOrRoot("unstagePackages"); !check.isOk()) {
-    return check;
-  }
-
   Result<void> res = ::android::apex::UnstagePackages(paths);
   if (res.ok()) {
     return BinderStatus::ok();
@@ -182,11 +169,6 @@
 
 BinderStatus ApexService::submitStagedSession(const ApexSessionParams& params,
                                               ApexInfoList* apex_info_list) {
-  auto check = CheckCallerSystemOrRoot("submitStagedSession");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "submitStagedSession() received by ApexService, session id "
              << params.sessionId << " child sessions: ["
              << android::base::Join(params.childSessionIds, ',') << "]";
@@ -213,11 +195,6 @@
 }
 
 BinderStatus ApexService::markStagedSessionReady(int session_id) {
-  auto check = CheckCallerSystemOrRoot("markStagedSessionReady");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "markStagedSessionReady() received by ApexService, session id "
              << session_id;
   Result<void> success = ::android::apex::MarkStagedSessionReady(session_id);
@@ -232,11 +209,6 @@
 }
 
 BinderStatus ApexService::markStagedSessionSuccessful(int session_id) {
-  auto check = CheckCallerSystemOrRoot("markStagedSessionSuccessful");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG)
       << "markStagedSessionSuccessful() received by ApexService, session id "
       << session_id;
@@ -252,11 +224,6 @@
 }
 
 BinderStatus ApexService::markBootCompleted() {
-  auto check = CheckCallerSystemOrRoot("markBootCompleted");
-  if (!check.isOk()) {
-    return check;
-  }
-
   ::android::apex::OnBootCompleted();
   return BinderStatus::ok();
 }
@@ -264,15 +231,15 @@
 BinderStatus ApexService::calculateSizeForCompressedApex(
     const CompressedApexInfoList& compressed_apex_info_list,
     int64_t* required_size) {
-  std::vector<std::tuple<std::string, int64_t, int64_t>> compressed_apexes;
-  compressed_apexes.reserve(compressed_apex_info_list.apexInfos.size());
-  for (const auto& apex_info : compressed_apex_info_list.apexInfos) {
-    compressed_apexes.emplace_back(apex_info.moduleName, apex_info.versionCode,
-                                   apex_info.decompressedSize);
-  }
+  *required_size = 0;
   const auto& instance = ApexFileRepository::GetInstance();
-  *required_size = ::android::apex::CalculateSizeForCompressedApex(
-      compressed_apexes, instance);
+  for (const auto& apex_info : compressed_apex_info_list.apexInfos) {
+    auto should_allocate_space = ShouldAllocateSpaceForDecompression(
+        apex_info.moduleName, apex_info.versionCode, instance);
+    if (!should_allocate_space.ok() || *should_allocate_space) {
+      *required_size += apex_info.decompressedSize;
+    }
+  }
   return BinderStatus::ok();
 }
 
@@ -359,19 +326,8 @@
   Result<std::string> preinstalled_path =
       instance.GetPreinstalledPath(package.GetManifest().name());
   if (preinstalled_path.ok()) {
-    // We replace the preinstalled paths for block devices to /system/apex
-    // because PackageManager will not resolve them if they aren't in one of
-    // the SYSTEM_PARTITIONS defined in PackagePartitions.java.
-    // b/195363518 for more context.
-    const std::string block_path = "/dev/block/";
-    const std::string sys_apex_path =
-        std::string(kApexPackageSystemDir) + "/" +
-        preinstalled_path->substr(block_path.length());
-    out.preinstalledModulePath = preinstalled_path->starts_with(block_path)
-                                     ? sys_apex_path
-                                     : *preinstalled_path;
+    out.preinstalledModulePath = *preinstalled_path;
   }
-  out.activeApexChanged = ::android::apex::IsActiveApexChanged(package);
   return out;
 }
 
@@ -389,11 +345,6 @@
 
 BinderStatus ApexService::getSessions(
     std::vector<ApexSessionInfo>* aidl_return) {
-  auto check = CheckCallerSystemOrRoot("getSessions");
-  if (!check.isOk()) {
-    return check;
-  }
-
   auto sessions = ApexSession::GetSessions();
   for (const auto& session : sessions) {
     ApexSessionInfo session_info;
@@ -406,11 +357,6 @@
 
 BinderStatus ApexService::getStagedSessionInfo(
     int session_id, ApexSessionInfo* apex_session_info) {
-  auto check = CheckCallerSystemOrRoot("getStagedSessionInfo");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "getStagedSessionInfo() received by ApexService, session id "
              << session_id;
   auto session = ApexSession::GetSession(session_id);
@@ -426,45 +372,50 @@
   return BinderStatus::ok();
 }
 
-BinderStatus ApexService::getStagedApexInfos(
-    const ApexSessionParams& params, std::vector<ApexInfo>* aidl_return) {
-  auto check = CheckCallerSystemOrRoot("getStagedApexInfos");
-  if (!check.isOk()) {
-    return check;
+BinderStatus ApexService::activatePackage(const std::string& package_path) {
+  BinderStatus debug_check = CheckDebuggable("activatePackage");
+  if (!debug_check.isOk()) {
+    return debug_check;
   }
 
-  LOG(DEBUG) << "getStagedApexInfos() received by ApexService, session id "
-             << params.sessionId << " child sessions: ["
-             << android::base::Join(params.childSessionIds, ',') << "]";
-  Result<std::vector<ApexFile>> files = ::android::apex::GetStagedApexFiles(
-      params.sessionId, params.childSessionIds);
-  if (!files.ok()) {
-    LOG(ERROR) << "Failed to getStagedApexInfo session id " << params.sessionId
-               << ": " << files.error();
-    return BinderStatus::fromExceptionCode(
-        BinderStatus::EX_SERVICE_SPECIFIC,
-        String8(files.error().message().c_str()));
+  LOG(DEBUG) << "activatePackage() received by ApexService, path "
+             << package_path;
+
+  Result<void> res = ::android::apex::ActivatePackage(package_path);
+
+  if (res.ok()) {
+    return BinderStatus::ok();
   }
 
-  // Retrieve classpath information
-  auto class_path = ::android::apex::MountAndDeriveClassPath(*files);
-  for (const auto& apex_file : *files) {
-    ApexInfo apex_info = GetApexInfo(apex_file);
-    auto package_name = apex_info.moduleName;
-    apex_info.hasClassPathJars = class_path->HasClassPathJars(package_name);
-    aidl_return->push_back(std::move(apex_info));
+  LOG(ERROR) << "Failed to activate " << package_path << ": " << res.error();
+  return BinderStatus::fromExceptionCode(
+      BinderStatus::EX_SERVICE_SPECIFIC,
+      String8(res.error().message().c_str()));
+}
+
+BinderStatus ApexService::deactivatePackage(const std::string& package_path) {
+  BinderStatus debug_check = CheckDebuggable("deactivatePackage");
+  if (!debug_check.isOk()) {
+    return debug_check;
   }
 
-  return BinderStatus::ok();
+  LOG(DEBUG) << "deactivatePackage() received by ApexService, path "
+             << package_path;
+
+  Result<void> res = ::android::apex::DeactivatePackage(package_path);
+
+  if (res.ok()) {
+    return BinderStatus::ok();
+  }
+
+  LOG(ERROR) << "Failed to deactivate " << package_path << ": " << res.error();
+  return BinderStatus::fromExceptionCode(
+      BinderStatus::EX_SERVICE_SPECIFIC,
+      String8(res.error().message().c_str()));
 }
 
 BinderStatus ApexService::getActivePackages(
     std::vector<ApexInfo>* aidl_return) {
-  auto check = CheckCallerSystemOrRoot("getActivePackages");
-  if (!check.isOk()) {
-    return check;
-  }
-
   auto packages = ::android::apex::GetActivePackages();
   for (const auto& package : packages) {
     ApexInfo apex_info = GetApexInfo(package);
@@ -477,11 +428,6 @@
 
 BinderStatus ApexService::getActivePackage(const std::string& package_name,
                                            ApexInfo* aidl_return) {
-  auto check = CheckCallerSystemOrRoot("getActivePackage");
-  if (!check.isOk()) {
-    return check;
-  }
-
   Result<ApexFile> apex = ::android::apex::GetActivePackage(package_name);
   if (apex.ok()) {
     *aidl_return = GetApexInfo(*apex);
@@ -491,11 +437,6 @@
 }
 
 BinderStatus ApexService::getAllPackages(std::vector<ApexInfo>* aidl_return) {
-  auto check = CheckCallerSystemOrRoot("getAllPackages");
-  if (!check.isOk()) {
-    return check;
-  }
-
   const auto& active = ::android::apex::GetActivePackages();
   const auto& factory = ::android::apex::GetFactoryPackages();
   for (const ApexFile& pkg : active) {
@@ -516,11 +457,6 @@
 
 BinderStatus ApexService::installAndActivatePackage(
     const std::string& package_path, ApexInfo* aidl_return) {
-  auto check = CheckCallerSystemOrRoot("installAndActivatePackage");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "installAndActivatePackage() received by ApexService, path: "
              << package_path;
   auto res = InstallPackage(package_path);
@@ -536,12 +472,45 @@
   return BinderStatus::ok();
 }
 
-BinderStatus ApexService::abortStagedSession(int session_id) {
-  auto check = CheckCallerSystemOrRoot("abortStagedSession");
-  if (!check.isOk()) {
-    return check;
+BinderStatus ApexService::preinstallPackages(
+    const std::vector<std::string>& paths) {
+  BinderStatus debug_check = CheckDebuggable("preinstallPackages");
+  if (!debug_check.isOk()) {
+    return debug_check;
   }
 
+  Result<void> res = ::android::apex::PreinstallPackages(paths);
+  if (res.ok()) {
+    return BinderStatus::ok();
+  }
+
+  LOG(ERROR) << "Failed to preinstall packages "
+             << android::base::Join(paths, ',') << ": " << res.error();
+  return BinderStatus::fromExceptionCode(
+      BinderStatus::EX_SERVICE_SPECIFIC,
+      String8(res.error().message().c_str()));
+}
+
+BinderStatus ApexService::postinstallPackages(
+    const std::vector<std::string>& paths) {
+  BinderStatus debug_check = CheckDebuggable("postinstallPackages");
+  if (!debug_check.isOk()) {
+    return debug_check;
+  }
+
+  Result<void> res = ::android::apex::PostinstallPackages(paths);
+  if (res.ok()) {
+    return BinderStatus::ok();
+  }
+
+  LOG(ERROR) << "Failed to postinstall packages "
+             << android::base::Join(paths, ',') << ": " << res.error();
+  return BinderStatus::fromExceptionCode(
+      BinderStatus::EX_SERVICE_SPECIFIC,
+      String8(res.error().message().c_str()));
+}
+
+BinderStatus ApexService::abortStagedSession(int session_id) {
   LOG(DEBUG) << "abortStagedSession() received by ApexService.";
   Result<void> res = ::android::apex::AbortStagedSession(session_id);
   if (!res.ok()) {
@@ -553,11 +522,6 @@
 }
 
 BinderStatus ApexService::revertActiveSessions() {
-  auto check = CheckCallerSystemOrRoot("revertActiveSessions");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "revertActiveSessions() received by ApexService.";
   Result<void> res = ::android::apex::RevertActiveSessions("", "");
   if (!res.ok()) {
@@ -574,11 +538,6 @@
     return debug_check;
   }
 
-  auto root_check = CheckCallerIsRoot("resumeRevertIfNeeded");
-  if (!root_check.isOk()) {
-    return root_check;
-  }
-
   LOG(DEBUG) << "resumeRevertIfNeeded() received by ApexService.";
   Result<void> res = ::android::apex::ResumeRevertIfNeeded();
   if (!res.ok()) {
@@ -591,11 +550,6 @@
 
 BinderStatus ApexService::snapshotCeData(int user_id, int rollback_id,
                                          const std::string& apex_name) {
-  auto check = CheckCallerSystemOrRoot("snapshotCeData");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "snapshotCeData() received by ApexService.";
   Result<void> res =
       ::android::apex::SnapshotCeData(user_id, rollback_id, apex_name);
@@ -609,11 +563,6 @@
 
 BinderStatus ApexService::restoreCeData(int user_id, int rollback_id,
                                         const std::string& apex_name) {
-  auto check = CheckCallerSystemOrRoot("restoreCeData");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "restoreCeData() received by ApexService.";
   Result<void> res =
       ::android::apex::RestoreCeData(user_id, rollback_id, apex_name);
@@ -626,11 +575,6 @@
 }
 
 BinderStatus ApexService::destroyDeSnapshots(int rollback_id) {
-  auto check = CheckCallerSystemOrRoot("destroyDeSnapshots");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "destroyDeSnapshots() received by ApexService.";
   Result<void> res = ::android::apex::DestroyDeSnapshots(rollback_id);
   if (!res.ok()) {
@@ -642,11 +586,6 @@
 }
 
 BinderStatus ApexService::destroyCeSnapshots(int user_id, int rollback_id) {
-  auto check = CheckCallerSystemOrRoot("destroyCeSnapshots");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "destroyCeSnapshots() received by ApexService.";
   Result<void> res = ::android::apex::DestroyCeSnapshots(user_id, rollback_id);
   if (!res.ok()) {
@@ -659,11 +598,6 @@
 
 BinderStatus ApexService::destroyCeSnapshotsNotSpecified(
     int user_id, const std::vector<int>& retain_rollback_ids) {
-  auto check = CheckCallerSystemOrRoot("destroyCeSnapshotsNotSpecified");
-  if (!check.isOk()) {
-    return check;
-  }
-
   LOG(DEBUG) << "destroyCeSnapshotsNotSpecified() received by ApexService.";
   Result<void> res = ::android::apex::DestroyCeSnapshotsNotSpecified(
       user_id, retain_rollback_ids);
@@ -837,6 +771,12 @@
         << "  deactivatePackage [package_path] - deactivate package from the "
            "given path"
         << std::endl
+        << "  preinstallPackages [package_path1] ([package_path2]...) - run "
+           "pre-install hooks of the given packages"
+        << std::endl
+        << "  postinstallPackages [package_path1] ([package_path2]...) - run "
+           "post-install hooks of the given packages"
+        << std::endl
         << "  getStagedSessionInfo [sessionId] - displays information about a "
            "given session previously submitted"
         << std::endl
@@ -950,13 +890,12 @@
       print_help(err, "activatePackage requires one package_path");
       return BAD_VALUE;
     }
-    std::string path = String8(args[1]).string();
-    auto status = ::android::apex::ActivatePackage(path);
-    if (status.ok()) {
+    BinderStatus status = activatePackage(String8(args[1]).string());
+    if (status.isOk()) {
       return OK;
     }
     std::string msg = StringLog() << "Failed to activate package: "
-                                  << status.error().message() << std::endl;
+                                  << status.toString8().string() << std::endl;
     dprintf(err, "%s", msg.c_str());
     return BAD_VALUE;
   }
@@ -966,13 +905,12 @@
       print_help(err, "deactivatePackage requires one package_path");
       return BAD_VALUE;
     }
-    std::string path = String8(args[1]).string();
-    auto status = ::android::apex::DeactivatePackage(path);
-    if (status.ok()) {
+    BinderStatus status = deactivatePackage(String8(args[1]).string());
+    if (status.isOk()) {
       return OK;
     }
     std::string msg = StringLog() << "Failed to deactivate package: "
-                                  << status.error().message() << std::endl;
+                                  << status.toString8().string() << std::endl;
     dprintf(err, "%s", msg.c_str());
     return BAD_VALUE;
   }
@@ -1048,6 +986,31 @@
     return BAD_VALUE;
   }
 
+  if (cmd == String16("preinstallPackages") ||
+      cmd == String16("postinstallPackages")) {
+    if (args.size() < 2) {
+      print_help(err,
+                 "preinstallPackages/postinstallPackages requires at least"
+                 " one package_path");
+      return BAD_VALUE;
+    }
+    std::vector<std::string> pkgs;
+    pkgs.reserve(args.size() - 1);
+    for (size_t i = 1; i != args.size(); ++i) {
+      pkgs.emplace_back(String8(args[i]).string());
+    }
+    BinderStatus status = cmd == String16("preinstallPackages")
+                              ? preinstallPackages(pkgs)
+                              : postinstallPackages(pkgs);
+    if (status.isOk()) {
+      return OK;
+    }
+    std::string msg = StringLog() << "Failed to pre/postinstall package(s): "
+                                  << status.toString8().string() << std::endl;
+    dprintf(err, "%s", msg.c_str());
+    return BAD_VALUE;
+  }
+
   if (cmd == String16("remountPackages")) {
     BinderStatus status = remountPackages();
     if (status.isOk()) {
diff --git a/apexd/apexservice_test.cpp b/apexd/apexservice_test.cpp
index 29cf1d7..545bb38 100644
--- a/apexd/apexservice_test.cpp
+++ b/apexd/apexservice_test.cpp
@@ -14,31 +14,6 @@
  * limitations under the License.
  */
 
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/macros.h>
-#include <android-base/properties.h>
-#include <android-base/scopeguard.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android/apex/ApexInfo.h>
-#include <android/apex/IApexService.h>
-#include <android/os/IVold.h>
-#include <binder/IServiceManager.h>
-#include <fs_mgr_overlayfs.h>
-#include <fstab/fstab.h>
-#include <gmock/gmock.h>
-#include <grp.h>
-#include <gtest/gtest.h>
-#include <libdm/dm.h>
-#include <linux/loop.h>
-#include <selinux/selinux.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/xattr.h>
-
 #include <algorithm>
 #include <filesystem>
 #include <fstream>
@@ -49,6 +24,32 @@
 #include <unordered_set>
 #include <vector>
 
+#include <grp.h>
+#include <linux/loop.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android-base/properties.h>
+#include <android-base/scopeguard.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android/os/IVold.h>
+#include <binder/IServiceManager.h>
+#include <fs_mgr_overlayfs.h>
+#include <fstab/fstab.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <libdm/dm.h>
+#include <selinux/selinux.h>
+
+#include <android/apex/ApexInfo.h>
+#include <android/apex/IApexService.h>
+
 #include "apex_constants.h"
 #include "apex_database.h"
 #include "apex_file.h"
@@ -68,21 +69,25 @@
 
 using android::sp;
 using android::String16;
+using android::apex::testing::ApexInfoEq;
 using android::apex::testing::CreateSessionInfo;
 using android::apex::testing::IsOk;
 using android::apex::testing::SessionInfoEq;
 using android::base::EndsWith;
-using android::base::Error;
+using android::base::ErrnoError;
 using android::base::Join;
-using android::base::Result;
-using android::base::SetProperty;
+using android::base::ReadFully;
 using android::base::StartsWith;
 using android::base::StringPrintf;
 using android::base::unique_fd;
 using android::dm::DeviceMapper;
+using android::fs_mgr::Fstab;
+using android::fs_mgr::GetEntryForMountPoint;
+using android::fs_mgr::ReadFstabFromFile;
 using ::apex::proto::ApexManifest;
-using ::apex::proto::SessionState;
+using ::testing::Contains;
 using ::testing::EndsWith;
+using ::testing::HasSubstr;
 using ::testing::Not;
 using ::testing::SizeIs;
 using ::testing::UnorderedElementsAre;
@@ -94,18 +99,7 @@
 
 class ApexServiceTest : public ::testing::Test {
  public:
-  ApexServiceTest() {}
-
- protected:
-  void SetUp() override {
-    // TODO(b/136647373): Move this check to environment setup
-    if (!android::base::GetBoolProperty("ro.apex.updatable", false)) {
-      GTEST_SKIP() << "Skipping test because device doesn't support APEX";
-    }
-
-    // Enable VERBOSE logging to simplifying debugging
-    SetProperty("log.tag.apexd", "VERBOSE");
-
+  ApexServiceTest() {
     using android::IBinder;
     using android::IServiceManager;
 
@@ -118,7 +112,14 @@
     if (binder != nullptr) {
       vold_service_ = android::interface_cast<android::os::IVold>(binder);
     }
+  }
 
+ protected:
+  void SetUp() override {
+    // TODO(b/136647373): Move this check to environment setup
+    if (!android::base::GetBoolProperty("ro.apex.updatable", false)) {
+      GTEST_SKIP() << "Skipping test because device doesn't support APEX";
+    }
     ASSERT_NE(nullptr, service_.get());
     ASSERT_NE(nullptr, vold_service_.get());
     android::binder::Status status =
@@ -141,6 +142,37 @@
 
   static bool IsSelinuxEnforced() { return 0 != security_getenforce(); }
 
+  Result<bool> IsActive(const std::string& name) {
+    std::vector<ApexInfo> list;
+    android::binder::Status status = service_->getActivePackages(&list);
+    if (!status.isOk()) {
+      return Error() << "Failed to check if " << name
+                     << " is active : " << status.exceptionMessage().c_str();
+    }
+    for (const ApexInfo& apex : list) {
+      if (apex.moduleName == name) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  Result<bool> IsActive(const std::string& name, int64_t version,
+                        const std::string& path) {
+    std::vector<ApexInfo> list;
+    android::binder::Status status = service_->getActivePackages(&list);
+    if (status.isOk()) {
+      for (const ApexInfo& p : list) {
+        if (p.moduleName == name && p.versionCode == version &&
+            p.modulePath == path) {
+          return true;
+        }
+      }
+      return false;
+    }
+    return Error() << status.exceptionMessage().c_str();
+  }
+
   Result<std::vector<ApexInfo>> GetAllPackages() {
     std::vector<ApexInfo> list;
     android::binder::Status status = service_->getAllPackages(&list);
@@ -175,6 +207,16 @@
     return Error() << status.toString8().c_str();
   }
 
+  Result<ApexInfo> GetActivePackage(const std::string& name) {
+    ApexInfo package;
+    android::binder::Status status = service_->getActivePackage(name, &package);
+    if (status.isOk()) {
+      return package;
+    }
+
+    return Error() << status.exceptionMessage().c_str();
+  }
+
   std::string GetPackageString(const ApexInfo& p) {
     return p.moduleName + "@" + std::to_string(p.versionCode) +
            " [path=" + p.moduleName + "]";
@@ -249,6 +291,26 @@
     return ret;
   }
 
+  static std::string GetLogcat() {
+    // For simplicity, log to file and read it.
+    std::string file = GetTestFile("logcat.tmp.txt");
+    std::vector<std::string> args{
+        "/system/bin/logcat",
+        "-d",
+        "-f",
+        file,
+    };
+    auto res = ForkAndRun(args);
+    CHECK(res.ok()) << res.error();
+
+    std::string data;
+    CHECK(android::base::ReadFileToString(file, &data));
+
+    unlink(file.c_str());
+
+    return data;
+  }
+
   static void DeleteIfExists(const std::string& path) {
     if (fs::exists(path)) {
       std::error_code ec;
@@ -433,46 +495,83 @@
   ofs.close();
 }
 
-void CreateFileWithExpectedProperties(const std::string& path) {
-  CreateFile(path);
-  std::error_code ec;
-  fs::permissions(
-      path,
-      fs::perms::owner_read | fs::perms::group_write | fs::perms::others_exec,
-      fs::perm_options::replace, ec);
-  ASSERT_FALSE(ec) << "Failed to set permissions: " << ec.message();
-  ASSERT_EQ(0, chown(path.c_str(), 1007 /* log */, 3001 /* net_bt_admin */))
-      << "chown failed: " << strerror(errno);
-  ASSERT_TRUE(RegularFileExists(path));
-  char buf[65536];  // 64kB is max possible xattr list size. See "man 7 xattr".
-  ASSERT_EQ(0, setxattr(path.c_str(), "user.foo", "bar", 4, 0));
-  ASSERT_GE(listxattr(path.c_str(), buf, sizeof(buf)), 9);
-  ASSERT_TRUE(memmem(buf, sizeof(buf), "user.foo", 9) != nullptr);
-  ASSERT_EQ(4, getxattr(path.c_str(), "user.foo", buf, sizeof(buf)));
-  ASSERT_STREQ("bar", buf);
-}
-
-void ExpectFileWithExpectedProperties(const std::string& path) {
-  EXPECT_TRUE(RegularFileExists(path));
-  EXPECT_EQ(fs::status(path).permissions(), fs::perms::owner_read |
-                                                fs::perms::group_write |
-                                                fs::perms::others_exec);
-  struct stat sd;
-  ASSERT_EQ(0, stat(path.c_str(), &sd));
-  EXPECT_EQ(1007u, sd.st_uid);
-  EXPECT_EQ(3001u, sd.st_gid);
-  char buf[65536];  // 64kB is max possible xattr list size. See "man 7 xattr".
-  EXPECT_GE(listxattr(path.c_str(), buf, sizeof(buf)), 9);
-  EXPECT_TRUE(memmem(buf, sizeof(buf), "user.foo", 9) != nullptr);
-  EXPECT_EQ(4, getxattr(path.c_str(), "user.foo", buf, sizeof(buf)));
-  EXPECT_STREQ("bar", buf);
-}
-
 Result<std::vector<std::string>> ReadEntireDir(const std::string& path) {
   static const auto kAcceptAll = [](auto /*entry*/) { return true; };
   return ReadDir(path, kAcceptAll);
 }
 
+Result<std::string> GetBlockDeviceForApex(const std::string& package_id) {
+  std::string mount_point = std::string(kApexRoot) + "/" + package_id;
+  Fstab fstab;
+  if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
+    return Error() << "Failed to read /proc/mounts";
+  }
+  auto entry = GetEntryForMountPoint(&fstab, mount_point);
+  if (entry == nullptr) {
+    return Error() << "Can't find " << mount_point << " in /proc/mounts";
+  }
+  return entry->blk_device;
+}
+
+Result<void> ReadDevice(const std::string& block_device) {
+  static constexpr int kBlockSize = 4096;
+  static constexpr size_t kBufSize = 1024 * kBlockSize;
+  std::vector<uint8_t> buffer(kBufSize);
+
+  unique_fd fd(
+      TEMP_FAILURE_RETRY(open(block_device.c_str(), O_RDONLY | O_CLOEXEC)));
+  if (fd.get() == -1) {
+    return ErrnoError() << "Can't open " << block_device;
+  }
+
+  while (true) {
+    int n = read(fd.get(), buffer.data(), kBufSize);
+    if (n < 0) {
+      return ErrnoError() << "Failed to read " << block_device;
+    }
+    if (n == 0) {
+      break;
+    }
+  }
+  return {};
+}
+
+std::vector<std::string> ListSlavesOfDmDevice(const std::string& name) {
+  DeviceMapper& dm = DeviceMapper::Instance();
+  std::string dm_path;
+  EXPECT_TRUE(dm.GetDmDevicePathByName(name, &dm_path))
+      << "Failed to get path of dm device " << name;
+  // It's a little bit sad we can't use ConsumePrefix here :(
+  constexpr std::string_view kDevPrefix = "/dev/";
+  EXPECT_TRUE(StartsWith(dm_path, kDevPrefix)) << "Illegal path " << dm_path;
+  dm_path = dm_path.substr(kDevPrefix.length());
+  std::vector<std::string> slaves;
+  {
+    std::string slaves_dir = "/sys/" + dm_path + "/slaves";
+    auto st = WalkDir(slaves_dir, [&](const auto& entry) {
+      std::error_code ec;
+      if (entry.is_symlink(ec)) {
+        slaves.push_back("/dev/block/" + entry.path().filename().string());
+      }
+      if (ec) {
+        ADD_FAILURE() << "Failed to scan " << slaves_dir << " : " << ec;
+      }
+    });
+    EXPECT_TRUE(IsOk(st));
+  }
+  return slaves;
+}
+
+Result<void> CopyFile(const std::string& from, const std::string& to,
+                      const fs::copy_options& options) {
+  std::error_code ec;
+  if (!fs::copy_file(from, to, options)) {
+    return Error() << "Failed to copy file " << from << " to " << to << " : "
+                   << ec.message();
+  }
+  return {};
+}
+
 }  // namespace
 
 TEST_F(ApexServiceTest, HaveSelinux) {
@@ -491,6 +590,66 @@
   EXPECT_TRUE(IsSelinuxEnforced() || kIsX86);
 }
 
+TEST_F(ApexServiceTest, StageFailAccess) {
+  if (!IsSelinuxEnforced()) {
+    LOG(WARNING) << "Skipping InstallFailAccess because of selinux";
+    return;
+  }
+
+  // Use an extra copy, so that even if this test fails (incorrectly installs),
+  // we have the testdata file still around.
+  std::string orig_test_file = GetTestFile("apex.apexd_test.apex");
+  std::string test_file = orig_test_file + ".2";
+  ASSERT_EQ(0, link(orig_test_file.c_str(), test_file.c_str()))
+      << strerror(errno);
+  struct Deleter {
+    std::string to_delete;
+    explicit Deleter(std::string t) : to_delete(std::move(t)) {}
+    ~Deleter() {
+      if (unlink(to_delete.c_str()) != 0) {
+        PLOG(ERROR) << "Could not unlink " << to_delete;
+      }
+    }
+  };
+  Deleter del(test_file);
+
+  android::binder::Status st = service_->stagePackages({test_file});
+  ASSERT_FALSE(IsOk(st));
+  std::string error = st.exceptionMessage().c_str();
+  EXPECT_NE(std::string::npos, error.find("Failed to open package")) << error;
+  EXPECT_NE(std::string::npos, error.find("I/O error")) << error;
+}
+
+TEST_F(ApexServiceTest, StageFailKey) {
+  PrepareTestApexForInstall installer(
+      GetTestFile("apex.apexd_test_no_inst_key.apex"));
+  if (!installer.Prepare()) {
+    return;
+  }
+  ASSERT_EQ(std::string("com.android.apex.test_package.no_inst_key"),
+            installer.package);
+
+  android::binder::Status st = service_->stagePackages({installer.test_file});
+  ASSERT_FALSE(IsOk(st));
+
+  // May contain one of two errors.
+  std::string error = st.exceptionMessage().c_str();
+
+  ASSERT_THAT(error, HasSubstr("No preinstalled apex found for package "
+                               "com.android.apex.test_package.no_inst_key"));
+}
+
+TEST_F(ApexServiceTest, StageSuccess) {
+  PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test.apex"));
+  if (!installer.Prepare()) {
+    return;
+  }
+  ASSERT_EQ(std::string("com.android.apex.test_package"), installer.package);
+
+  ASSERT_TRUE(IsOk(service_->stagePackages({installer.test_file})));
+  EXPECT_TRUE(RegularFileExists(installer.test_installed_file));
+}
+
 TEST_F(ApexServiceTest,
        SubmitStagegSessionSuccessDoesNotLeakTempVerityDevices) {
   PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test.apex"),
@@ -552,6 +711,85 @@
   }
 }
 
+TEST_F(ApexServiceTest, StageSuccessClearsPreviouslyActivePackage) {
+  PrepareTestApexForInstall installer1(GetTestFile("apex.apexd_test_v2.apex"));
+  PrepareTestApexForInstall installer2(
+      GetTestFile("apex.apexd_test_different_app.apex"));
+  PrepareTestApexForInstall installer3(GetTestFile("apex.apexd_test.apex"));
+  auto install_fn = [&](PrepareTestApexForInstall& installer) {
+    if (!installer.Prepare()) {
+      return;
+    }
+    ASSERT_TRUE(IsOk(service_->stagePackages({installer.test_file})));
+    EXPECT_TRUE(RegularFileExists(installer.test_installed_file));
+  };
+  install_fn(installer1);
+  install_fn(installer2);
+  // Simulating a revert. After this call test_v2_apex_path should be removed.
+  install_fn(installer3);
+
+  EXPECT_FALSE(RegularFileExists(installer1.test_installed_file));
+  EXPECT_TRUE(RegularFileExists(installer2.test_installed_file));
+  EXPECT_TRUE(RegularFileExists(installer3.test_installed_file));
+}
+
+TEST_F(ApexServiceTest, StageAlreadyStagedPackageSuccess) {
+  PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test.apex"));
+  if (!installer.Prepare()) {
+    return;
+  }
+  ASSERT_EQ(std::string("com.android.apex.test_package"), installer.package);
+
+  ASSERT_TRUE(IsOk(service_->stagePackages({installer.test_file})));
+  ASSERT_TRUE(RegularFileExists(installer.test_installed_file));
+
+  ASSERT_TRUE(IsOk(service_->stagePackages({installer.test_file})));
+  ASSERT_TRUE(RegularFileExists(installer.test_installed_file));
+}
+
+TEST_F(ApexServiceTest, StageAlreadyStagedPackageSuccessNewWins) {
+  PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test.apex"));
+  PrepareTestApexForInstall installer2(
+      GetTestFile("apex.apexd_test_nocode.apex"));
+  if (!installer.Prepare() || !installer2.Prepare()) {
+    return;
+  }
+  ASSERT_EQ(std::string("com.android.apex.test_package"), installer.package);
+  ASSERT_EQ(installer.test_installed_file, installer2.test_installed_file);
+
+  ASSERT_TRUE(IsOk(service_->stagePackages({installer.test_file})));
+  const auto& apex = ApexFile::Open(installer.test_installed_file);
+  ASSERT_TRUE(IsOk(apex));
+  ASSERT_FALSE(apex->GetManifest().nocode());
+
+  ASSERT_TRUE(IsOk(service_->stagePackages({installer2.test_file})));
+  const auto& new_apex = ApexFile::Open(installer.test_installed_file);
+  ASSERT_TRUE(IsOk(new_apex));
+  ASSERT_TRUE(new_apex->GetManifest().nocode());
+}
+
+TEST_F(ApexServiceTest, MultiStageSuccess) {
+  PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test.apex"));
+  if (!installer.Prepare()) {
+    return;
+  }
+  ASSERT_EQ(std::string("com.android.apex.test_package"), installer.package);
+
+  PrepareTestApexForInstall installer2(GetTestFile("apex.apexd_test_v2.apex"));
+  if (!installer2.Prepare()) {
+    return;
+  }
+  ASSERT_EQ(std::string("com.android.apex.test_package"), installer2.package);
+
+  std::vector<std::string> packages;
+  packages.push_back(installer.test_file);
+  packages.push_back(installer2.test_file);
+
+  ASSERT_TRUE(IsOk(service_->stagePackages(packages)));
+  EXPECT_TRUE(RegularFileExists(installer.test_installed_file));
+  EXPECT_TRUE(RegularFileExists(installer2.test_installed_file));
+}
+
 TEST_F(ApexServiceTest, CannotBeRollbackAndHaveRollbackEnabled) {
   PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test.apex"),
                                       "/data/app-staging/session_1543",
@@ -589,13 +827,15 @@
 
 TEST_F(ApexServiceTest, SnapshotCeData) {
   CreateDir("/data/misc_ce/0/apexdata/apex.apexd_test");
-  CreateFileWithExpectedProperties(
-      "/data/misc_ce/0/apexdata/apex.apexd_test/hello.txt");
+  CreateFile("/data/misc_ce/0/apexdata/apex.apexd_test/hello.txt");
+
+  ASSERT_TRUE(
+      RegularFileExists("/data/misc_ce/0/apexdata/apex.apexd_test/hello.txt"));
 
   service_->snapshotCeData(0, 123456, "apex.apexd_test");
 
-  ExpectFileWithExpectedProperties(
-      "/data/misc_ce/0/apexrollback/123456/apex.apexd_test/hello.txt");
+  ASSERT_TRUE(RegularFileExists(
+      "/data/misc_ce/0/apexrollback/123456/apex.apexd_test/hello.txt"));
 }
 
 TEST_F(ApexServiceTest, RestoreCeData) {
@@ -604,22 +844,21 @@
   CreateDir("/data/misc_ce/0/apexrollback/123456/apex.apexd_test");
 
   CreateFile("/data/misc_ce/0/apexdata/apex.apexd_test/newfile.txt");
-  CreateFileWithExpectedProperties(
-      "/data/misc_ce/0/apexrollback/123456/apex.apexd_test/oldfile.txt");
+  CreateFile("/data/misc_ce/0/apexrollback/123456/apex.apexd_test/oldfile.txt");
 
   ASSERT_TRUE(RegularFileExists(
       "/data/misc_ce/0/apexdata/apex.apexd_test/newfile.txt"));
-  ExpectFileWithExpectedProperties(
-      "/data/misc_ce/0/apexrollback/123456/apex.apexd_test/oldfile.txt");
+  ASSERT_TRUE(RegularFileExists(
+      "/data/misc_ce/0/apexrollback/123456/apex.apexd_test/oldfile.txt"));
 
   service_->restoreCeData(0, 123456, "apex.apexd_test");
 
-  ExpectFileWithExpectedProperties(
-      "/data/misc_ce/0/apexdata/apex.apexd_test/oldfile.txt");
-  EXPECT_FALSE(RegularFileExists(
+  ASSERT_TRUE(RegularFileExists(
+      "/data/misc_ce/0/apexdata/apex.apexd_test/oldfile.txt"));
+  ASSERT_FALSE(RegularFileExists(
       "/data/misc_ce/0/apexdata/apex.apexd_test/newfile.txt"));
   // The snapshot should be deleted after restoration.
-  EXPECT_FALSE(
+  ASSERT_FALSE(
       DirExists("/data/misc_ce/0/apexrollback/123456/apex.apexd_test"));
 }
 
@@ -740,6 +979,441 @@
   }
 }
 
+template <typename NameProvider>
+class ApexServiceActivationTest : public ApexServiceTest {
+ public:
+  ApexServiceActivationTest() : stage_package(true) {}
+
+  explicit ApexServiceActivationTest(bool stage_package)
+      : stage_package(stage_package) {}
+
+  void SetUp() override {
+    // TODO(b/136647373): Move this check to environment setup
+    if (!android::base::GetBoolProperty("ro.apex.updatable", false)) {
+      GTEST_SKIP() << "Skipping test because device doesn't support APEX";
+    }
+    ApexServiceTest::SetUp();
+    ASSERT_NE(nullptr, service_.get());
+
+    installer_ = std::make_unique<PrepareTestApexForInstall>(
+        GetTestFile(NameProvider::GetTestName()));
+    if (!installer_->Prepare()) {
+      return;
+    }
+    ASSERT_EQ(NameProvider::GetPackageName(), installer_->package);
+
+    {
+      // Check package is not active.
+      std::string path = stage_package ? installer_->test_installed_file
+                                       : installer_->test_file;
+      Result<bool> active =
+          IsActive(installer_->package, installer_->version, path);
+      ASSERT_TRUE(IsOk(active));
+      ASSERT_FALSE(*active);
+    }
+
+    if (stage_package) {
+      ASSERT_TRUE(IsOk(service_->stagePackages({installer_->test_file})));
+    }
+  }
+
+  void TearDown() override {
+    // Attempt to deactivate.
+    if (installer_ != nullptr) {
+      if (stage_package) {
+        service_->deactivatePackage(installer_->test_installed_file);
+      } else {
+        service_->deactivatePackage(installer_->test_file);
+      }
+    }
+
+    installer_.reset();
+    // ApexServiceTest::TearDown will wipe out everything under /data/apex.
+    // Since some of that information is required for deactivatePackage binder
+    // call, it's required to be called after deactivating package.
+    ApexServiceTest::TearDown();
+  }
+
+  std::unique_ptr<PrepareTestApexForInstall> installer_;
+
+ private:
+  bool stage_package;
+};
+
+struct SuccessNameProvider {
+  static std::string GetTestName() { return "apex.apexd_test.apex"; }
+  static std::string GetPackageName() {
+    return "com.android.apex.test_package";
+  }
+};
+
+struct ManifestMismatchNameProvider {
+  static std::string GetTestName() {
+    return "apex.apexd_test_manifest_mismatch.apex";
+  }
+  static std::string GetPackageName() {
+    return "com.android.apex.test_package";
+  }
+};
+
+class ApexServiceActivationManifestMismatchFailure
+    : public ApexServiceActivationTest<ManifestMismatchNameProvider> {
+ public:
+  ApexServiceActivationManifestMismatchFailure()
+      : ApexServiceActivationTest(false) {}
+};
+
+TEST_F(ApexServiceActivationManifestMismatchFailure,
+       ActivateFailsWithManifestMismatch) {
+  android::binder::Status st = service_->activatePackage(installer_->test_file);
+  ASSERT_FALSE(IsOk(st));
+
+  std::string error = st.exceptionMessage().c_str();
+  ASSERT_THAT(
+      error,
+      HasSubstr(
+          "Manifest inside filesystem does not match manifest outside it"));
+}
+
+class ApexServiceActivationSuccessTest
+    : public ApexServiceActivationTest<SuccessNameProvider> {};
+
+TEST_F(ApexServiceActivationSuccessTest, Activate) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  {
+    // Check package is active.
+    Result<bool> active = IsActive(installer_->package, installer_->version,
+                                   installer_->test_installed_file);
+    ASSERT_TRUE(IsOk(active));
+    ASSERT_TRUE(*active) << Join(GetActivePackagesStrings(), ',');
+  }
+
+  {
+    // Check that the "latest" view exists.
+    std::string latest_path =
+        std::string(kApexRoot) + "/" + installer_->package;
+    struct stat buf;
+    ASSERT_EQ(0, stat(latest_path.c_str(), &buf)) << strerror(errno);
+    // Check that it is a folder.
+    EXPECT_TRUE(S_ISDIR(buf.st_mode));
+
+    // Collect direct entries of a folder.
+    auto collect_entries_fn = [&](const std::string& path) {
+      std::vector<std::string> ret;
+      auto status = WalkDir(path, [&](const fs::directory_entry& entry) {
+        if (!entry.is_directory()) {
+          return;
+        }
+        ret.emplace_back(entry.path().filename());
+      });
+      CHECK(status.has_value())
+          << "Failed to list " << path << " : " << status.error();
+      std::sort(ret.begin(), ret.end());
+      return ret;
+    };
+
+    std::string versioned_path = std::string(kApexRoot) + "/" +
+                                 installer_->package + "@" +
+                                 std::to_string(installer_->version);
+    std::vector<std::string> versioned_folder_entries =
+        collect_entries_fn(versioned_path);
+    std::vector<std::string> latest_folder_entries =
+        collect_entries_fn(latest_path);
+
+    EXPECT_TRUE(versioned_folder_entries == latest_folder_entries)
+        << "Versioned: " << Join(versioned_folder_entries, ',')
+        << " Latest: " << Join(latest_folder_entries, ',');
+  }
+}
+
+TEST_F(ApexServiceActivationSuccessTest, GetActivePackages) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  Result<std::vector<ApexInfo>> active = GetActivePackages();
+  ASSERT_TRUE(IsOk(active));
+  ApexInfo match;
+
+  for (const ApexInfo& info : *active) {
+    if (info.moduleName == installer_->package) {
+      match = info;
+      break;
+    }
+  }
+
+  ASSERT_EQ(installer_->package, match.moduleName);
+  ASSERT_EQ(installer_->version, static_cast<uint64_t>(match.versionCode));
+  ASSERT_EQ(installer_->test_installed_file, match.modulePath);
+}
+
+TEST_F(ApexServiceActivationSuccessTest, GetActivePackage) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  Result<ApexInfo> active = GetActivePackage(installer_->package);
+  ASSERT_TRUE(IsOk(active));
+
+  ASSERT_EQ(installer_->package, active->moduleName);
+  ASSERT_EQ(installer_->version, static_cast<uint64_t>(active->versionCode));
+  ASSERT_EQ(installer_->test_installed_file, active->modulePath);
+}
+
+TEST_F(ApexServiceActivationSuccessTest, ShowsUpInMountedApexDatabase) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  MountedApexDatabase db;
+  db.PopulateFromMounts(kActiveApexPackagesDataDir, kApexDecompressedDir,
+                        kApexHashTreeDir);
+
+  std::optional<MountedApexData> mounted_apex;
+  db.ForallMountedApexes(installer_->package,
+                         [&](const MountedApexData& d, bool active) {
+                           if (active) {
+                             mounted_apex.emplace(d);
+                           }
+                         });
+  ASSERT_TRUE(mounted_apex)
+      << "Haven't found " << installer_->test_installed_file
+      << " in the database of mounted apexes";
+
+  // Get all necessary data for assertions on mounted_apex.
+  std::string package_id =
+      installer_->package + "@" + std::to_string(installer_->version);
+  DeviceMapper& dm = DeviceMapper::Instance();
+  std::string dm_path;
+  ASSERT_TRUE(dm.GetDmDevicePathByName(package_id, &dm_path))
+      << "Failed to get path of dm device " << package_id;
+  auto loop_device = dm.GetParentBlockDeviceByPath(dm_path);
+  ASSERT_TRUE(loop_device) << "Failed to find parent block device of "
+                           << dm_path;
+
+  // Now we are ready to assert on mounted_apex.
+  ASSERT_EQ(*loop_device, mounted_apex->loop_name);
+  ASSERT_EQ(installer_->test_installed_file, mounted_apex->full_path);
+  std::string expected_mount = std::string(kApexRoot) + "/" + package_id;
+  ASSERT_EQ(expected_mount, mounted_apex->mount_point);
+  ASSERT_EQ(package_id, mounted_apex->device_name);
+  ASSERT_EQ("", mounted_apex->hashtree_loop_name);
+}
+
+struct NoHashtreeApexNameProvider {
+  static std::string GetTestName() {
+    return "apex.apexd_test_no_hashtree.apex";
+  }
+  static std::string GetPackageName() {
+    return "com.android.apex.test_package";
+  }
+};
+
+class ApexServiceNoHashtreeApexActivationTest
+    : public ApexServiceActivationTest<NoHashtreeApexNameProvider> {};
+
+TEST_F(ApexServiceNoHashtreeApexActivationTest, Activate) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+  {
+    // Check package is active.
+    Result<bool> active = IsActive(installer_->package, installer_->version,
+                                   installer_->test_installed_file);
+    ASSERT_TRUE(IsOk(active));
+    ASSERT_TRUE(*active) << Join(GetActivePackagesStrings(), ',');
+  }
+
+  std::string package_id =
+      installer_->package + "@" + std::to_string(installer_->version);
+  // Check that hashtree file was created.
+  {
+    std::string hashtree_path =
+        std::string(kApexHashTreeDir) + "/" + package_id;
+    auto exists = PathExists(hashtree_path);
+    ASSERT_TRUE(IsOk(exists));
+    ASSERT_TRUE(*exists);
+  }
+
+  // Check that block device can be read.
+  auto block_device = GetBlockDeviceForApex(package_id);
+  ASSERT_TRUE(IsOk(block_device));
+  ASSERT_TRUE(IsOk(ReadDevice(*block_device)));
+}
+
+TEST_F(ApexServiceNoHashtreeApexActivationTest,
+       NewSessionDoesNotImpactActivePackage) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+  {
+    // Check package is active.
+    Result<bool> active = IsActive(installer_->package, installer_->version,
+                                   installer_->test_installed_file);
+    ASSERT_TRUE(IsOk(active));
+    ASSERT_TRUE(*active) << Join(GetActivePackagesStrings(), ',');
+  }
+
+  PrepareTestApexForInstall installer2(
+      GetTestFile("apex.apexd_test_no_hashtree_2.apex"),
+      "/data/app-staging/session_123", "staging_data_file");
+  if (!installer2.Prepare()) {
+    FAIL();
+  }
+
+  ApexInfoList list;
+  ApexSessionParams params;
+  params.sessionId = 123;
+  ASSERT_TRUE(IsOk(service_->submitStagedSession(params, &list)));
+
+  std::string package_id =
+      installer_->package + "@" + std::to_string(installer_->version);
+  // Check that new hashtree file was created.
+  {
+    std::string hashtree_path =
+        std::string(kApexHashTreeDir) + "/" + package_id + ".new";
+    auto exists = PathExists(hashtree_path);
+    ASSERT_TRUE(IsOk(exists));
+    ASSERT_TRUE(*exists) << hashtree_path << " does not exist";
+  }
+  // Check that active hashtree is still there.
+  {
+    std::string hashtree_path =
+        std::string(kApexHashTreeDir) + "/" + package_id;
+    auto exists = PathExists(hashtree_path);
+    ASSERT_TRUE(IsOk(exists));
+    ASSERT_TRUE(*exists) << hashtree_path << " does not exist";
+  }
+
+  // Check that block device of active APEX can still be read.
+  auto block_device = GetBlockDeviceForApex(package_id);
+  ASSERT_TRUE(IsOk(block_device));
+}
+
+TEST_F(ApexServiceNoHashtreeApexActivationTest, ShowsUpInMountedApexDatabase) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  MountedApexDatabase db;
+  db.PopulateFromMounts(kActiveApexPackagesDataDir, kApexDecompressedDir,
+                        kApexHashTreeDir);
+
+  std::optional<MountedApexData> mounted_apex;
+  db.ForallMountedApexes(installer_->package,
+                         [&](const MountedApexData& d, bool active) {
+                           if (active) {
+                             mounted_apex.emplace(d);
+                           }
+                         });
+  ASSERT_TRUE(mounted_apex)
+      << "Haven't found " << installer_->test_installed_file
+      << " in the database of mounted apexes";
+
+  // Get all necessary data for assertions on mounted_apex.
+  std::string package_id =
+      installer_->package + "@" + std::to_string(installer_->version);
+  std::vector<std::string> slaves = ListSlavesOfDmDevice(package_id);
+  ASSERT_EQ(2u, slaves.size())
+      << "Unexpected number of slaves: " << Join(slaves, ",");
+
+  // Now we are ready to assert on mounted_apex.
+  ASSERT_EQ(installer_->test_installed_file, mounted_apex->full_path);
+  std::string expected_mount = std::string(kApexRoot) + "/" + package_id;
+  ASSERT_EQ(expected_mount, mounted_apex->mount_point);
+  ASSERT_EQ(package_id, mounted_apex->device_name);
+  // For loops we only check that both loop_name and hashtree_loop_name are
+  // slaves of the top device mapper device.
+  ASSERT_THAT(slaves, Contains(mounted_apex->loop_name));
+  ASSERT_THAT(slaves, Contains(mounted_apex->hashtree_loop_name));
+  ASSERT_NE(mounted_apex->loop_name, mounted_apex->hashtree_loop_name);
+}
+
+TEST_F(ApexServiceNoHashtreeApexActivationTest, DeactivateFreesLoopDevices) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  std::string package_id =
+      installer_->package + "@" + std::to_string(installer_->version);
+  std::vector<std::string> slaves = ListSlavesOfDmDevice(package_id);
+  ASSERT_EQ(2u, slaves.size())
+      << "Unexpected number of slaves: " << Join(slaves, ",");
+
+  ASSERT_TRUE(
+      IsOk(service_->deactivatePackage(installer_->test_installed_file)));
+
+  for (const auto& loop : slaves) {
+    struct loop_info li;
+    unique_fd fd(TEMP_FAILURE_RETRY(open(loop.c_str(), O_RDWR | O_CLOEXEC)));
+    ASSERT_NE(-1, fd.get())
+        << "Failed to open " << loop << " : " << strerror(errno);
+    ASSERT_EQ(-1, ioctl(fd.get(), LOOP_GET_STATUS, &li))
+        << loop << " is still alive";
+    ASSERT_EQ(ENXIO, errno) << "Unexpected errno : " << strerror(errno);
+  }
+
+  // Skip deactivatePackage on TearDown.
+  installer_.reset();
+}
+
+TEST_F(ApexServiceTest, NoHashtreeApexStagePackagesMovesHashtree) {
+  PrepareTestApexForInstall installer(
+      GetTestFile("apex.apexd_test_no_hashtree.apex"),
+      "/data/app-staging/session_239", "staging_data_file");
+  if (!installer.Prepare()) {
+    FAIL();
+  }
+
+  auto read_fn = [](const std::string& path) -> std::vector<uint8_t> {
+    static constexpr size_t kBufSize = 4096;
+    std::vector<uint8_t> buffer(kBufSize);
+    unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+    if (fd.get() == -1) {
+      PLOG(ERROR) << "Failed to open " << path;
+      ADD_FAILURE();
+      return buffer;
+    }
+    if (!ReadFully(fd.get(), buffer.data(), kBufSize)) {
+      PLOG(ERROR) << "Failed to read " << path;
+      ADD_FAILURE();
+    }
+    return buffer;
+  };
+
+  ApexInfoList list;
+  ApexSessionParams params;
+  params.sessionId = 239;
+  ASSERT_TRUE(IsOk(service_->submitStagedSession(params, &list)));
+
+  std::string package_id =
+      installer.package + "@" + std::to_string(installer.version);
+  // Check that new hashtree file was created.
+  std::vector<uint8_t> original_hashtree_data;
+  {
+    std::string hashtree_path =
+        std::string(kApexHashTreeDir) + "/" + package_id + ".new";
+    auto exists = PathExists(hashtree_path);
+    ASSERT_TRUE(IsOk(exists));
+    ASSERT_TRUE(*exists);
+    original_hashtree_data = read_fn(hashtree_path);
+  }
+
+  ASSERT_TRUE(IsOk(service_->stagePackages({installer.test_file})));
+  // Check that hashtree file was moved.
+  {
+    std::string hashtree_path =
+        std::string(kApexHashTreeDir) + "/" + package_id + ".new";
+    auto exists = PathExists(hashtree_path);
+    ASSERT_TRUE(IsOk(exists));
+    ASSERT_FALSE(*exists);
+  }
+  {
+    std::string hashtree_path =
+        std::string(kApexHashTreeDir) + "/" + package_id;
+    auto exists = PathExists(hashtree_path);
+    ASSERT_TRUE(IsOk(exists));
+    ASSERT_TRUE(*exists);
+    std::vector<uint8_t> moved_hashtree_data = read_fn(hashtree_path);
+    ASSERT_EQ(moved_hashtree_data, original_hashtree_data);
+  }
+}
+
 TEST_F(ApexServiceTest, GetFactoryPackages) {
   Result<std::vector<ApexInfo>> factory_packages = GetFactoryPackages();
   ASSERT_TRUE(IsOk(factory_packages));
@@ -769,7 +1443,7 @@
   }
 }
 
-TEST_F(ApexServiceTest, DISABLED_NoPackagesAreBothActiveAndInactive) {
+TEST_F(ApexServiceTest, NoPackagesAreBothActiveAndInactive) {
   Result<std::vector<ApexInfo>> active_packages = GetActivePackages();
   ASSERT_TRUE(IsOk(active_packages));
   ASSERT_TRUE(active_packages->size() > 0);
@@ -789,7 +1463,7 @@
   ASSERT_THAT(intersection, SizeIs(0));
 }
 
-TEST_F(ApexServiceTest, DISABLED_GetAllPackages) {
+TEST_F(ApexServiceTest, GetAllPackages) {
   Result<std::vector<ApexInfo>> all_packages = GetAllPackages();
   ASSERT_TRUE(IsOk(all_packages));
   ASSERT_TRUE(all_packages->size() > 0);
@@ -816,6 +1490,247 @@
   }
 }
 
+class ApexSameGradeOfPreInstalledVersionTest : public ApexServiceTest {
+ public:
+  void SetUp() override {
+    // TODO(b/136647373): Move this check to environment setup
+    if (!android::base::GetBoolProperty("ro.apex.updatable", false)) {
+      GTEST_SKIP() << "Skipping test because device doesn't support APEX";
+    }
+    ApexServiceTest::SetUp();
+    ASSERT_NE(nullptr, service_.get());
+
+    installer_ = std::make_unique<PrepareTestApexForInstall>(
+        GetTestFile("com.android.apex.cts.shim.apex"));
+    if (!installer_->Prepare()) {
+      return;
+    }
+    ASSERT_EQ("com.android.apex.cts.shim", installer_->package);
+    // First deactivate currently active shim, otherwise activatePackage will be
+    // no-op.
+    {
+      ApexInfo system_shim;
+      ASSERT_TRUE(IsOk(service_->getActivePackage("com.android.apex.cts.shim",
+                                                  &system_shim)));
+      ASSERT_TRUE(IsOk(service_->deactivatePackage(system_shim.modulePath)));
+    }
+    ASSERT_TRUE(IsOk(service_->stagePackages({installer_->test_file})));
+    ASSERT_TRUE(
+        IsOk(service_->activatePackage(installer_->test_installed_file)));
+  }
+
+  void TearDown() override {
+    // Attempt to deactivate.
+    service_->deactivatePackage(installer_->test_installed_file);
+    installer_.reset();
+    // ApexServiceTest::TearDown will wipe out everything under /data/apex.
+    // Since some of that information is required for deactivatePackage binder
+    // call, it's required to be called after deactivating package.
+    ApexServiceTest::TearDown();
+    ASSERT_TRUE(IsOk(service_->activatePackage(
+        "/system/apex/com.android.apex.cts.shim.apex")));
+  }
+
+  std::unique_ptr<PrepareTestApexForInstall> installer_;
+};
+
+TEST_F(ApexSameGradeOfPreInstalledVersionTest, VersionOnDataWins) {
+  std::vector<ApexInfo> all;
+  ASSERT_TRUE(IsOk(service_->getAllPackages(&all)));
+
+  ApexInfo on_data;
+  on_data.moduleName = "com.android.apex.cts.shim";
+  on_data.modulePath = "/data/apex/active/com.android.apex.cts.shim@1.apex";
+  on_data.preinstalledModulePath =
+      "/system/apex/com.android.apex.cts.shim.apex";
+  on_data.versionCode = 1;
+  on_data.isFactory = false;
+  on_data.isActive = true;
+
+  ApexInfo preinstalled;
+  preinstalled.moduleName = "com.android.apex.cts.shim";
+  preinstalled.modulePath = "/system/apex/com.android.apex.cts.shim.apex";
+  preinstalled.preinstalledModulePath =
+      "/system/apex/com.android.apex.cts.shim.apex";
+  preinstalled.versionCode = 1;
+  preinstalled.isFactory = true;
+  preinstalled.isActive = false;
+
+  ASSERT_THAT(all, Contains(ApexInfoEq(on_data)));
+  ASSERT_THAT(all, Contains(ApexInfoEq(preinstalled)));
+}
+
+class ApexServiceDeactivationTest : public ApexServiceActivationSuccessTest {
+ public:
+  void SetUp() override {
+    ApexServiceActivationSuccessTest::SetUp();
+
+    ASSERT_TRUE(installer_ != nullptr);
+  }
+
+  void TearDown() override {
+    installer_.reset();
+    ApexServiceActivationSuccessTest::TearDown();
+  }
+
+  std::unique_ptr<PrepareTestApexForInstall> installer_;
+};
+
+TEST_F(ApexServiceActivationSuccessTest, DmDeviceTearDown) {
+  std::string package_id =
+      installer_->package + "@" + std::to_string(installer_->version);
+
+  auto find_fn = [](const std::string& name) {
+    auto& dm = DeviceMapper::Instance();
+    std::vector<DeviceMapper::DmBlockDevice> devices;
+    if (!dm.GetAvailableDevices(&devices)) {
+      return Result<bool>(Errorf("GetAvailableDevices failed"));
+    }
+    for (const auto& device : devices) {
+      if (device.name() == name) {
+        return Result<bool>(true);
+      }
+    }
+    return Result<bool>(false);
+  };
+
+#define ASSERT_FIND(type)                   \
+  {                                         \
+    Result<bool> res = find_fn(package_id); \
+    ASSERT_RESULT_OK(res);                  \
+    ASSERT_##type(*res);                    \
+  }
+
+  ASSERT_FIND(FALSE);
+
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  ASSERT_FIND(TRUE);
+
+  ASSERT_TRUE(
+      IsOk(service_->deactivatePackage(installer_->test_installed_file)));
+
+  ASSERT_FIND(FALSE);
+
+  installer_.reset();  // Skip TearDown deactivatePackage.
+}
+
+TEST_F(ApexServiceActivationSuccessTest, DeactivateFreesLoopDevices) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  std::string package_id =
+      installer_->package + "@" + std::to_string(installer_->version);
+  std::vector<std::string> slaves = ListSlavesOfDmDevice(package_id);
+  ASSERT_EQ(1u, slaves.size())
+      << "Unexpected number of slaves: " << Join(slaves, ",");
+  const std::string& loop = slaves[0];
+
+  ASSERT_TRUE(
+      IsOk(service_->deactivatePackage(installer_->test_installed_file)));
+
+  struct loop_info li;
+  unique_fd fd(TEMP_FAILURE_RETRY(open(loop.c_str(), O_RDWR | O_CLOEXEC)));
+  ASSERT_NE(-1, fd.get()) << "Failed to open " << loop << " : "
+                          << strerror(errno);
+  ASSERT_EQ(-1, ioctl(fd.get(), LOOP_GET_STATUS, &li))
+      << loop << " is still alive";
+  ASSERT_EQ(ENXIO, errno) << "Unexpected errno : " << strerror(errno);
+
+  installer_.reset();  // Skip TearDown deactivatePackage.
+}
+
+class ApexServicePrePostInstallTest : public ApexServiceTest {
+ public:
+  template <typename Fn>
+  void RunPrePost(Fn fn, const std::vector<std::string>& apex_names,
+                  const char* test_message, bool expect_success = true) {
+    // Using unique_ptr is just the easiest here.
+    using InstallerUPtr = std::unique_ptr<PrepareTestApexForInstall>;
+    std::vector<InstallerUPtr> installers;
+    std::vector<std::string> pkgs;
+
+    for (const std::string& apex_name : apex_names) {
+      InstallerUPtr installer(
+          new PrepareTestApexForInstall(GetTestFile(apex_name)));
+      if (!installer->Prepare()) {
+        return;
+      }
+      pkgs.push_back(installer->test_file);
+      installers.emplace_back(std::move(installer));
+    }
+    android::binder::Status st = (service_.get()->*fn)(pkgs);
+    if (expect_success) {
+      ASSERT_TRUE(IsOk(st));
+    } else {
+      ASSERT_FALSE(IsOk(st));
+    }
+
+    if (test_message != nullptr) {
+      std::string logcat = GetLogcat();
+      EXPECT_THAT(logcat, HasSubstr(test_message));
+    }
+
+    // Ensure that the package is neither active nor mounted.
+    for (const InstallerUPtr& installer : installers) {
+      Result<bool> active = IsActive(installer->package, installer->version,
+                                     installer->test_file);
+      ASSERT_TRUE(IsOk(active));
+      EXPECT_FALSE(*active);
+    }
+    for (const InstallerUPtr& installer : installers) {
+      Result<ApexFile> apex = ApexFile::Open(installer->test_input);
+      ASSERT_TRUE(IsOk(apex));
+      std::string path =
+          apexd_private::GetPackageMountPoint(apex->GetManifest());
+      std::string entry = std::string("[dir]").append(path);
+      std::vector<std::string> slash_apex = ListDir(kApexRoot);
+      auto it = std::find(slash_apex.begin(), slash_apex.end(), entry);
+      EXPECT_TRUE(it == slash_apex.end()) << Join(slash_apex, ',');
+    }
+  }
+};
+
+TEST_F(ApexServicePrePostInstallTest, Preinstall) {
+  RunPrePost(&IApexService::preinstallPackages,
+             {"apex.apexd_test_preinstall.apex"}, "sh      : PreInstall Test");
+}
+
+TEST_F(ApexServicePrePostInstallTest, MultiPreinstall) {
+  constexpr const char* kLogcatText =
+      "sh      : /apex/com.android.apex.test_package/etc/sample_prebuilt_file";
+  RunPrePost(&IApexService::preinstallPackages,
+             {"apex.apexd_test_preinstall.apex", "apex.apexd_test.apex"},
+             kLogcatText);
+}
+
+TEST_F(ApexServicePrePostInstallTest, PreinstallFail) {
+  RunPrePost(&IApexService::preinstallPackages,
+             {"apex.apexd_test_prepostinstall.fail.apex"},
+             /* test_message= */ nullptr, /* expect_success= */ false);
+}
+
+TEST_F(ApexServicePrePostInstallTest, Postinstall) {
+  RunPrePost(&IApexService::postinstallPackages,
+             {"apex.apexd_test_postinstall.apex"},
+             "sh      : PostInstall Test");
+}
+
+TEST_F(ApexServicePrePostInstallTest, MultiPostinstall) {
+  constexpr const char* kLogcatText =
+      "sh      : /apex/com.android.apex.test_package/etc/sample_prebuilt_file";
+  RunPrePost(&IApexService::postinstallPackages,
+             {"apex.apexd_test_postinstall.apex", "apex.apexd_test.apex"},
+             kLogcatText);
+}
+
+TEST_F(ApexServicePrePostInstallTest, PostinstallFail) {
+  RunPrePost(&IApexService::postinstallPackages,
+             {"apex.apexd_test_prepostinstall.fail.apex"},
+             /* test_message= */ nullptr, /* expect_success= */ false);
+}
+
 TEST_F(ApexServiceTest, SubmitSingleSessionTestSuccess) {
   PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test.apex"),
                                       "/data/app-staging/session_123",
@@ -1309,6 +2224,61 @@
   }
 }
 
+TEST_F(ApexServiceTest, UnstagePackagesSuccess) {
+  PrepareTestApexForInstall installer1(GetTestFile("apex.apexd_test.apex"));
+  PrepareTestApexForInstall installer2(
+      GetTestFile("apex.apexd_test_different_app.apex"));
+
+  if (!installer1.Prepare() || !installer2.Prepare()) {
+    return;
+  }
+
+  std::vector<std::string> pkgs = {installer1.test_file, installer2.test_file};
+  ASSERT_TRUE(IsOk(service_->stagePackages(pkgs)));
+
+  pkgs = {installer2.test_installed_file};
+  ASSERT_TRUE(IsOk(service_->unstagePackages(pkgs)));
+
+  auto active_packages = ReadEntireDir(kActiveApexPackagesDataDir);
+  ASSERT_TRUE(IsOk(active_packages));
+  ASSERT_THAT(*active_packages,
+              UnorderedElementsAre(installer1.test_installed_file));
+}
+
+TEST_F(ApexServiceTest, UnstagePackagesFail) {
+  PrepareTestApexForInstall installer1(GetTestFile("apex.apexd_test.apex"));
+  PrepareTestApexForInstall installer2(
+      GetTestFile("apex.apexd_test_different_app.apex"));
+
+  if (!installer1.Prepare() || !installer2.Prepare()) {
+    return;
+  }
+
+  std::vector<std::string> pkgs = {installer1.test_file};
+  ASSERT_TRUE(IsOk(service_->stagePackages(pkgs)));
+
+  pkgs = {installer1.test_installed_file, installer2.test_installed_file};
+  ASSERT_FALSE(IsOk(service_->unstagePackages(pkgs)));
+
+  // Check that first package wasn't unstaged.
+  auto active_packages = ReadEntireDir(kActiveApexPackagesDataDir);
+  ASSERT_TRUE(IsOk(active_packages));
+  ASSERT_THAT(*active_packages,
+              UnorderedElementsAre(installer1.test_installed_file));
+}
+
+TEST_F(ApexServiceTest, UnstagePackagesFailPreInstalledApex) {
+  auto status = service_->unstagePackages(
+      {"/system/apex/com.android.apex.cts.shim.apex"});
+  ASSERT_FALSE(IsOk(status));
+  const std::string& error_message =
+      std::string(status.exceptionMessage().c_str());
+  ASSERT_THAT(error_message,
+              HasSubstr("Can't uninstall pre-installed apex "
+                        "/system/apex/com.android.apex.cts.shim.apex"));
+  ASSERT_TRUE(RegularFileExists("/system/apex/com.android.apex.cts.shim.apex"));
+}
+
 class ApexServiceRevertTest : public ApexServiceTest {
  protected:
   void SetUp() override { ApexServiceTest::SetUp(); }
@@ -1544,10 +2514,30 @@
   ASSERT_THAT(session_info, SessionInfoEq(expected));
 }
 
+TEST_F(ApexServiceRevertTest, RevertStoresCrashingNativeProcess) {
+  PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test_v2.apex"));
+  if (!installer.Prepare()) {
+    return;
+  }
+  auto session = ApexSession::CreateSession(1543);
+  ASSERT_TRUE(IsOk(session));
+  ASSERT_TRUE(IsOk(session->UpdateStateAndCommit(SessionState::ACTIVATED)));
+
+  // Make sure /data/apex/active is non-empty.
+  ASSERT_TRUE(IsOk(service_->stagePackages({installer.test_file})));
+  std::string native_process = "test_process";
+  // TODO(ioffe): this is calling into internals of apexd which makes test quite
+  //  britle. With some refactoring we should be able to call binder api, or
+  //  make this a unit test of apexd.cpp.
+  Result<void> res = ::android::apex::RevertActiveSessions(native_process, "");
+  session = ApexSession::GetSession(1543);
+  ASSERT_EQ(session->GetCrashingNativeProcess(), native_process);
+}
+
 static pid_t GetPidOf(const std::string& name) {
   char buf[1024];
   const std::string cmd = std::string("pidof -s ") + name;
-  FILE* cmd_pipe = popen(cmd.c_str(), "r");  // NOLINT(cert-env33-c): test code
+  FILE* cmd_pipe = popen(cmd.c_str(), "r");
   if (cmd_pipe == nullptr) {
     PLOG(ERROR) << "Cannot open pipe for " << cmd;
     return 0;
@@ -1701,15 +2691,18 @@
     }
     ApexServiceTest::SetUp();
 
-    // Skip test if for some reason shim APEX is missing.
+    // Assert that shim apex is pre-installed.
     std::vector<ApexInfo> list;
     ASSERT_TRUE(IsOk(service_->getAllPackages(&list)));
-    bool found = std::any_of(list.begin(), list.end(), [](const auto& apex) {
-      return apex.moduleName == "com.android.apex.cts.shim";
-    });
-    if (!found) {
-      GTEST_SKIP() << "Can't find com.android.apex.cts.shim";
-    }
+    ApexInfo expected;
+    expected.moduleName = "com.android.apex.cts.shim";
+    expected.modulePath = "/system/apex/com.android.apex.cts.shim.apex";
+    expected.preinstalledModulePath =
+        "/system/apex/com.android.apex.cts.shim.apex";
+    expected.versionCode = 1;
+    expected.isFactory = true;
+    expected.isActive = true;
+    ASSERT_THAT(list, Contains(ApexInfoEq(expected)));
   }
 };
 
@@ -1847,6 +2840,82 @@
   ASSERT_FALSE(IsOk(service_->stagePackages({installer.test_file})));
 }
 
+TEST_F(ApexServiceTest, RemountPackagesPackageOnSystemChanged) {
+  static constexpr const char* kSystemPath =
+      "/system_ext/apex/apex.apexd_test.apex";
+  static constexpr const char* kPackageName = "com.android.apex.test_package";
+  if (!fs_mgr_overlayfs_is_setup()) {
+    GTEST_SKIP() << "/system_ext is not overlayed into read-write";
+  }
+  if (auto res = IsActive(kPackageName); !res.ok()) {
+    FAIL() << res.error();
+  } else {
+    ASSERT_FALSE(*res) << kPackageName << " is active";
+  }
+  ASSERT_EQ(0, access(kSystemPath, F_OK))
+      << "Failed to stat " << kSystemPath << " : " << strerror(errno);
+  ASSERT_TRUE(IsOk(service_->activatePackage(kSystemPath)));
+  std::string backup_path = GetTestFile("apex.apexd_test.apexd.bak");
+  // Copy original /system_ext apex file. We will need to restore it after test
+  // runs.
+  ASSERT_RESULT_OK(CopyFile(kSystemPath, backup_path, fs::copy_options::none));
+
+  // Make sure we cleanup after ourselves.
+  auto deleter = android::base::make_scope_guard([&]() {
+    if (auto ret = service_->deactivatePackage(kSystemPath); !ret.isOk()) {
+      LOG(ERROR) << ret.exceptionMessage();
+    }
+    auto ret = CopyFile(backup_path, kSystemPath,
+                        fs::copy_options::overwrite_existing);
+    if (!ret.ok()) {
+      LOG(ERROR) << ret.error();
+    }
+  });
+
+  // Copy v2 version to /system_ext/apex/ and then call remountPackages.
+  PrepareTestApexForInstall installer(GetTestFile("apex.apexd_test_v2.apex"));
+  if (!installer.Prepare()) {
+    FAIL() << GetDebugStr(&installer);
+  }
+  ASSERT_RESULT_OK(CopyFile(installer.test_file, kSystemPath,
+                            fs::copy_options::overwrite_existing));
+  // Don't check that remountPackages succeeded. Most likely it will fail, but
+  // it should still remount our test apex.
+  service_->remountPackages();
+
+  // Check that v2 is now active.
+  auto active_apex = GetActivePackage("com.android.apex.test_package");
+  ASSERT_RESULT_OK(active_apex);
+  ASSERT_EQ(2u, active_apex->versionCode);
+  // Check that module path didn't change, modulo symlink.
+  std::string realSystemPath;
+  ASSERT_TRUE(android::base::Realpath(kSystemPath, &realSystemPath));
+  ASSERT_EQ(realSystemPath, active_apex->modulePath);
+}
+
+TEST_F(ApexServiceActivationSuccessTest, RemountPackagesPackageOnDataChanged) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+  // Copy v2 version to /data/apex/active and then call remountPackages.
+  PrepareTestApexForInstall installer2(GetTestFile("apex.apexd_test_v2.apex"));
+  if (!installer2.Prepare()) {
+    FAIL() << GetDebugStr(&installer2);
+  }
+  ASSERT_RESULT_OK(CopyFile(installer2.test_file,
+                            installer_->test_installed_file,
+                            fs::copy_options::overwrite_existing));
+  // Don't check that remountPackages succeeded. Most likely it will fail, but
+  // it should still remount our test apex.
+  service_->remountPackages();
+
+  // Check that v2 is now active.
+  auto active_apex = GetActivePackage("com.android.apex.test_package");
+  ASSERT_RESULT_OK(active_apex);
+  ASSERT_EQ(2u, active_apex->versionCode);
+  // Sanity check that module path didn't change.
+  ASSERT_EQ(installer_->test_installed_file, active_apex->modulePath);
+}
+
 TEST_F(ApexServiceTest,
        SubmitStagedSessionFailsManifestMismatchCleansUpHashtree) {
   PrepareTestApexForInstall installer(
@@ -1884,6 +2953,195 @@
   }
 };
 
+struct NoCodeApexNameProvider {
+  static std::string GetTestName() { return "apex.apexd_test_nocode.apex"; }
+  static std::string GetPackageName() {
+    return "com.android.apex.test_package";
+  }
+};
+
+class ApexServiceActivationNoCode
+    : public ApexServiceActivationTest<NoCodeApexNameProvider> {};
+
+TEST_F(ApexServiceActivationNoCode, NoCodeApexIsNotExecutable) {
+  ASSERT_TRUE(IsOk(service_->activatePackage(installer_->test_installed_file)))
+      << GetDebugStr(installer_.get());
+
+  std::string mountinfo;
+  ASSERT_TRUE(
+      android::base::ReadFileToString("/proc/self/mountinfo", &mountinfo));
+  bool found_apex_mountpoint = false;
+  for (const auto& line : android::base::Split(mountinfo, "\n")) {
+    std::vector<std::string> tokens = android::base::Split(line, " ");
+    // line format:
+    // mnt_id parent_mnt_id major:minor source target option propagation_type
+    // ex) 33 260:19 / /apex rw,nosuid,nodev -
+    if (tokens.size() >= 7 &&
+        tokens[4] ==
+            "/apex/" + NoCodeApexNameProvider::GetPackageName() + "@1") {
+      found_apex_mountpoint = true;
+      // Make sure that option contains noexec
+      std::vector<std::string> options = android::base::Split(tokens[5], ",");
+      EXPECT_NE(options.end(),
+                std::find(options.begin(), options.end(), "noexec"));
+      break;
+    }
+  }
+  EXPECT_TRUE(found_apex_mountpoint);
+}
+
+struct BannedNameProvider {
+  static std::string GetTestName() { return "sharedlibs.apex"; }
+  static std::string GetPackageName() { return "sharedlibs"; }
+};
+
+class ApexServiceActivationBannedName
+    : public ApexServiceActivationTest<BannedNameProvider> {
+ public:
+  ApexServiceActivationBannedName() : ApexServiceActivationTest(false) {}
+};
+
+TEST_F(ApexServiceActivationBannedName, ApexWithBannedNameCannotBeActivated) {
+  ASSERT_FALSE(
+      IsOk(service_->activatePackage(installer_->test_installed_file)));
+}
+
+namespace {
+void PrepareCompressedTestApex(const std::string& input_apex,
+                               const std::string& builtin_dir,
+                               const std::string& decompressed_dir,
+                               const std::string& active_apex_dir) {
+  const Result<ApexFile>& apex_file = ApexFile::Open(input_apex);
+  ASSERT_TRUE(apex_file.ok());
+  ASSERT_TRUE(apex_file->IsCompressed()) << "Not a compressed APEX";
+
+  auto prebuilt_file_path =
+      builtin_dir + "/" + android::base::Basename(input_apex);
+  fs::copy(input_apex, prebuilt_file_path);
+
+  const ApexManifest& manifest = apex_file->GetManifest();
+  const std::string& package = manifest.name();
+  const int64_t& version = manifest.version();
+
+  auto decompressed_file_path = decompressed_dir + "/" + package + "@" +
+                                std::to_string(version) + ".apex";
+  auto result = apex_file->Decompress(decompressed_file_path);
+  ASSERT_TRUE(result.ok()) << "Failed to decompress " << result.error();
+  auto active_apex_file_path =
+      active_apex_dir + "/" + package + "@" + std::to_string(version) + ".apex";
+  auto error =
+      link(decompressed_file_path.c_str(), active_apex_file_path.c_str());
+  ASSERT_EQ(error, 0) << "Failed to hardlink decompressed APEX";
+}
+
+CompressedApexInfo CreateCompressedApex(const std::string& name,
+                                        const int version, const int size) {
+  CompressedApexInfo result;
+  result.moduleName = name;
+  result.versionCode = version;
+  result.decompressedSize = size;
+  return result;
+}
+}  // namespace
+
+class ApexServiceTestForCompressedApex : public ApexServiceTest {
+ public:
+  static constexpr const char* kTempPrebuiltDir = "/data/apex/temp_prebuilt";
+
+  void SetUp() override {
+    ApexServiceTest::SetUp();
+    ASSERT_NE(nullptr, service_.get());
+
+    TemporaryDir decompression_dir, active_apex_dir;
+    if (0 != mkdir(kTempPrebuiltDir, 0777)) {
+      int saved_errno = errno;
+      ASSERT_EQ(saved_errno, EEXIST)
+          << kTempPrebuiltDir << ":" << strerror(saved_errno);
+    }
+    PrepareCompressedTestApex(
+        GetTestFile("com.android.apex.compressed.v1.capex"), kTempPrebuiltDir,
+        kApexDecompressedDir, kActiveApexPackagesDataDir);
+    service_->recollectPreinstalledData({kTempPrebuiltDir});
+    service_->recollectDataApex(kActiveApexPackagesDataDir,
+                                kApexDecompressedDir);
+  }
+
+  void TearDown() override {
+    ApexServiceTest::TearDown();
+    DeleteDirContent(kTempPrebuiltDir);
+    rmdir(kTempPrebuiltDir);
+    DeleteDirContent(kApexDecompressedDir);
+    DeleteDirContent(kActiveApexPackagesDataDir);
+  }
+};
+
+TEST_F(ApexServiceTestForCompressedApex, CalculateSizeForCompressedApex) {
+  int64_t result;
+  // Empty list of compressed apex info
+  {
+    CompressedApexInfoList empty_list;
+    ASSERT_TRUE(
+        IsOk(service_->calculateSizeForCompressedApex(empty_list, &result)));
+    ASSERT_EQ(result, 0ll);
+  }
+
+  // Multiple compressed APEX should get summed
+  {
+    CompressedApexInfoList non_empty_list;
+    CompressedApexInfo new_apex = CreateCompressedApex("new_apex", 1, 1);
+    CompressedApexInfo new_apex_2 = CreateCompressedApex("new_apex_2", 1, 2);
+    CompressedApexInfo compressed_apex_same_version =
+        CreateCompressedApex("com.android.apex.compressed", 1, 4);
+    CompressedApexInfo compressed_apex_higher_version =
+        CreateCompressedApex("com.android.apex.compressed", 2, 8);
+    non_empty_list.apexInfos.push_back(new_apex);
+    non_empty_list.apexInfos.push_back(new_apex_2);
+    non_empty_list.apexInfos.push_back(compressed_apex_same_version);
+    non_empty_list.apexInfos.push_back(compressed_apex_higher_version);
+    ASSERT_TRUE(IsOk(
+        service_->calculateSizeForCompressedApex(non_empty_list, &result)));
+    ASSERT_EQ(result, 11ll);  // 1+2+8. compressed_apex_same_version is ignored
+  }
+}
+
+TEST_F(ApexServiceTestForCompressedApex, ReserveSpaceForCompressedApex) {
+  // Multiple compressed APEX should reserve equal to
+  // CalculateSizeForCompressedApex
+  {
+    CompressedApexInfoList non_empty_list;
+    CompressedApexInfo new_apex = CreateCompressedApex("new_apex", 1, 1);
+    CompressedApexInfo new_apex_2 = CreateCompressedApex("new_apex_2", 1, 2);
+    CompressedApexInfo compressed_apex_same_version =
+        CreateCompressedApex("com.android.apex.compressed", 1, 4);
+    CompressedApexInfo compressed_apex_higher_version =
+        CreateCompressedApex("com.android.apex.compressed", 2, 8);
+    non_empty_list.apexInfos.push_back(new_apex);
+    non_empty_list.apexInfos.push_back(new_apex_2);
+    non_empty_list.apexInfos.push_back(compressed_apex_same_version);
+    non_empty_list.apexInfos.push_back(compressed_apex_higher_version);
+    int64_t required_size;
+    ASSERT_TRUE(IsOk(service_->calculateSizeForCompressedApex(non_empty_list,
+                                                              &required_size)));
+    ASSERT_EQ(required_size,
+              11ll);  // 1+2+8. compressed_apex_same_version is ignored
+
+    ASSERT_TRUE(IsOk(service_->reserveSpaceForCompressedApex(non_empty_list)));
+    auto files = ReadDir(kOtaReservedDir, [](auto _) { return true; });
+    ASSERT_TRUE(IsOk(files));
+    ASSERT_EQ(files->size(), 1u);
+    EXPECT_EQ((int64_t)fs::file_size((*files)[0]), required_size);
+  }
+
+  // Sending empty list should delete reserved file
+  {
+    CompressedApexInfoList empty_list;
+    ASSERT_TRUE(IsOk(service_->reserveSpaceForCompressedApex(empty_list)));
+    auto files = ReadDir(kOtaReservedDir, [](auto _) { return true; });
+    ASSERT_TRUE(IsOk(files));
+    ASSERT_EQ(files->size(), 0u);
+  }
+}
+
 }  // namespace apex
 }  // namespace android
 
diff --git a/apexd/sysprop/Android.bp b/apexd/sysprop/Android.bp
index 050434b..0b81efd 100644
--- a/apexd/sysprop/Android.bp
+++ b/apexd/sysprop/Android.bp
@@ -7,6 +7,5 @@
   srcs: ["ApexProperties.sysprop"],
   property_owner: "Platform",
   api_packages: ["android.sysprop"],
-  ramdisk_available: true,
   recovery_available: true,
 }
diff --git a/apexer/Android.bp b/apexer/Android.bp
index 20d6f27..081bae1 100644
--- a/apexer/Android.bp
+++ b/apexer/Android.bp
@@ -27,7 +27,6 @@
       "zipalign",
       "make_f2fs",
       "sload_f2fs",
-      "make_erofs",
       // TODO(b/124476339) apex doesn't follow 'required' dependencies so we need to include this
       // manually for 'avbtool'.
       "fec",
@@ -44,6 +43,14 @@
     srcs: [
         "apex_manifest.py",
     ],
+    version: {
+        py2: {
+            enabled: true,
+        },
+        py3: {
+            enabled: true,
+        },
+    },
     libs: [
         "apex_manifest_proto",
     ],
@@ -59,9 +66,13 @@
         ":mke2fs_conf",
     ],
     version: {
-        py3: {
+        py2: {
+            enabled: true,
             embedded_launcher: true,
         },
+        py3: {
+            enabled: false,
+        },
     },
     libs: [
         "apex_manifest",
@@ -77,9 +88,13 @@
         "conv_apex_manifest.py",
     ],
     version: {
-        py3: {
+        py2: {
+            enabled: true,
             embedded_launcher: true,
         },
+        py3: {
+            enabled: false,
+        },
     },
     libs: [
         "apex_manifest_proto",
@@ -124,10 +139,21 @@
         "testdata/com.android.example.apex.pk8",
         "testdata/com.android.example.apex.x509.pem",
     ],
+    version: {
+        py2: {
+            enabled: false,
+        },
+        py3: {
+            enabled: true,
+        },
+    },
     test_suites: ["general-tests"],
     libs: [
         "apex_manifest",
     ],
+    test_options: {
+        unit_test: false,
+    },
 }
 
 apexer_deps_minus_go_tools = apexer_tools + [
@@ -151,7 +177,7 @@
     ],
     out: ["apexer_test_host_tools.zip"],
     tools: apexer_deps_tools + [
-        // To force signapk.jar generated in out/host
+        // To force signapk.jar generated in out/soong/host
         "signapk",
     ],
     cmd: "HOST_OUT_BIN=$$(dirname $(location apexer)) && " +
diff --git a/apexer/TEST_MAPPING b/apexer/TEST_MAPPING
index 1ad3078..0b3e797 100644
--- a/apexer/TEST_MAPPING
+++ b/apexer/TEST_MAPPING
@@ -1,9 +1,11 @@
 {
-  "presubmit": [
-    {
-      "name": "apexer_test"
-    }
-  ],
+  // b/214537606: disabled since test lab JDK version has been upgraded to follow newer branches,
+  // and will not be able to match sc-v2-dev
+  //"presubmit": [
+  //  {
+  //    "name": "apexer_test"
+  //  }
+  //],
   "imports": [
     {
       "path": "system/apex/tests"
diff --git a/apexer/apexer.py b/apexer/apexer.py
index 65ea25f..f0c17f4 100644
--- a/apexer/apexer.py
+++ b/apexer/apexer.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
 #
 # Copyright (C) 2018 The Android Open Source Project
 #
@@ -32,8 +32,6 @@
 import tempfile
 import uuid
 import xml.etree.ElementTree as ET
-import zipfile
-import glob
 from apex_manifest import ValidateApexManifest
 from apex_manifest import ApexManifestError
 from manifest import android_ns
@@ -80,7 +78,7 @@
   parser.add_argument(
       '--canned_fs_config',
       help='canned_fs_config specifies uid/gid/mode of files. Required for ' +
-           '"image" APEXS.')
+      '"image" APEXS.')
   parser.add_argument(
       '--key', help='path to the private key file. Required for "image" APEXs.')
   parser.add_argument(
@@ -108,8 +106,8 @@
       metavar='FS_TYPE',
       required=False,
       default='ext4',
-      choices=['ext4', 'f2fs', 'erofs'],
-      help='type of filesystem being used for payload image "ext4", "f2fs" or "erofs"')
+      choices=['ext4', 'f2fs'],
+      help='type of filesystem being used for payload image "ext4" or "f2fs"')
   parser.add_argument(
       '--override_apk_package_name',
       required=False,
@@ -180,14 +178,6 @@
       action='store_true',
       help="""Skip signing the apex payload. Used only for testing purposes."""
   )
-  parser.add_argument(
-      '--test_only',
-      action='store_true',
-      help=(
-          'Add testOnly=true attribute to application element in '
-          'AndroidManifest file.')
-  )
-
   return parser.parse_args(argv)
 
 
@@ -211,7 +201,6 @@
   p = subprocess.Popen(
       cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=env)
   output, _ = p.communicate()
-  output = output.decode()
 
   if verbose or p.returncode not in expected_return_values:
     print(output.rstrip())
@@ -245,19 +234,16 @@
   return (size + unit - 1) & (~(unit - 1))
 
 
-def PrepareAndroidManifest(package, version, test_only):
+def PrepareAndroidManifest(package, version):
   template = """\
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="{package}" android:versionCode="{version}">
   <!-- APEX does not have classes.dex -->
-  <application android:hasCode="false" {test_only_attribute}/>
+  <application android:hasCode="false" />
 </manifest>
 """
-
-  test_only_attribute = 'android:testOnly="true"' if test_only else ''
-  return template.format(package=package, version=version,
-                         test_only_attribute=test_only_attribute)
+  return template.format(package=package, version=version)
 
 
 def ValidateAndroidManifest(package, android_manifest):
@@ -270,17 +256,6 @@
                     "' in the apex_manifest.pb")
 
 
-def ValidateGeneratedAndroidManifest(android_manifest, test_only):
-  tree = ET.parse(android_manifest)
-  manifest_tag = tree.getroot()
-  application_tag = manifest_tag.find('./application')
-  if test_only:
-    test_only_in_xml = application_tag.attrib[
-      '{http://schemas.android.com/apk/res/android}testOnly']
-    if test_only_in_xml != 'true':
-      raise Exception('testOnly attribute must be equal to true.')
-
-
 def ValidateArgs(args):
   build_info = None
 
@@ -288,7 +263,7 @@
     if not os.path.exists(args.build_info):
       print("Build info file '" + args.build_info + "' does not exist")
       return False
-    with open(args.build_info, 'rb') as buildInfoFile:
+    with open(args.build_info) as buildInfoFile:
       build_info = apex_build_info_pb2.ApexBuildInfo()
       build_info.ParseFromString(buildInfoFile.read())
 
@@ -382,19 +357,18 @@
 
   return True
 
-
 def GenerateBuildInfo(args):
   build_info = apex_build_info_pb2.ApexBuildInfo()
   if (args.include_cmd_line_in_build_info):
     build_info.apexer_command_line = str(sys.argv)
 
-  with open(args.file_contexts, 'rb') as f:
+  with open(args.file_contexts) as f:
     build_info.file_contexts = f.read()
 
-  with open(args.canned_fs_config, 'rb') as f:
+  with open(args.canned_fs_config) as f:
     build_info.canned_fs_config = f.read()
 
-  with open(args.android_manifest, 'rb') as f:
+  with open(args.android_manifest) as f:
     build_info.android_manifest = f.read()
 
   if args.target_sdk_version:
@@ -417,7 +391,6 @@
 
   return build_info
 
-
 def AddLoggingParent(android_manifest, logging_parent_value):
   """Add logging parent as an additional <meta-data> tag.
 
@@ -462,257 +435,202 @@
     indent = get_indent(application.previousSibling, 1)
     application.appendChild(doc.createTextNode(indent))
 
-  with tempfile.NamedTemporaryFile(delete=False, mode='w') as temp:
-    write_xml(temp, doc)
-    return temp.name
+  with tempfile.NamedTemporaryFile(delete=False) as temp:
+      write_xml(temp, doc)
+      return temp.name
 
+def CreateApex(args, work_dir):
+  if not ValidateArgs(args):
+    return False
 
-def ShaHashFiles(file_paths):
-  """get hash for a number of files."""
-  h = hashlib.sha256()
-  for file_path in file_paths:
-    with open(file_path, 'rb') as file:
-      while True:
-        chunk = file.read(h.block_size)
-        if not chunk:
-          break
-        h.update(chunk)
-  return h.hexdigest()
+  if args.verbose:
+    print 'Using tools from ' + str(tool_path_list)
 
+  def copyfile(src, dst):
+    if args.verbose:
+      print('Copying ' + src + ' to ' + dst)
+    shutil.copyfile(src, dst)
 
-def CreateImageExt4(args, work_dir, manifests_dir, img_file):
-  """Create image for ext4 file system."""
+  try:
+    manifest_apex = ValidateApexManifest(args.manifest)
+  except ApexManifestError as err:
+    print("'" + args.manifest + "' is not a valid manifest file")
+    print err.errmessage
+    return False
+  except IOError:
+    print("Cannot read manifest file: '" + args.manifest + "'")
+    return False
 
-  lost_found_location = os.path.join(args.input_dir, 'lost+found')
-  if os.path.exists(lost_found_location):
-    print('Warning: input_dir contains a lost+found/ root folder, which '
-          'has been known to cause non-deterministic apex builds.')
+  # create an empty image that is sufficiently big
+  size_in_mb = (GetDirSize(args.input_dir) / (1024 * 1024))
 
-  # sufficiently big = size + 16MB margin
-  size_in_mb = (GetDirSize(args.input_dir) // (1024 * 1024))
-  size_in_mb += 16
+  content_dir = os.path.join(work_dir, 'content')
+  os.mkdir(content_dir)
 
-  # Margin is for files that are not under args.input_dir. this consists of
-  # n inodes for apex_manifest files and 11 reserved inodes for ext4.
-  # TOBO(b/122991714) eliminate these details. Use build_image.py which
-  # determines the optimal inode count by first building an image and then
-  # count the inodes actually used.
-  inode_num_margin = GetFilesAndDirsCount(manifests_dir) + 11
-  inode_num = GetFilesAndDirsCount(args.input_dir) + inode_num_margin
+  # APEX manifest is also included in the image. The manifest is included
+  # twice: once inside the image and once outside the image (but still
+  # within the zip container).
+  manifests_dir = os.path.join(work_dir, 'manifests')
+  os.mkdir(manifests_dir)
+  copyfile(args.manifest, os.path.join(manifests_dir, 'apex_manifest.pb'))
+  if args.manifest_json:
+    # manifest_json is for compatibility
+    copyfile(args.manifest_json, os.path.join(manifests_dir, 'apex_manifest.json'))
 
-  cmd = ['mke2fs']
-  cmd.extend(['-O', '^has_journal'])  # because image is read-only
-  cmd.extend(['-b', str(BLOCK_SIZE)])
-  cmd.extend(['-m', '0'])  # reserved block percentage
-  cmd.extend(['-t', 'ext4'])
-  cmd.extend(['-I', '256'])  # inode size
-  cmd.extend(['-N', str(inode_num)])
-  uu = str(uuid.uuid5(uuid.NAMESPACE_URL, 'www.android.com'))
-  cmd.extend(['-U', uu])
-  cmd.extend(['-E', 'hash_seed=' + uu])
-  cmd.append(img_file)
-  cmd.append(str(size_in_mb) + 'M')
-  with tempfile.NamedTemporaryFile(dir=work_dir,
-                                   suffix='mke2fs.conf') as conf_file:
-    conf_data = pkgutil.get_data('apexer', 'mke2fs.conf')
-    conf_file.write(conf_data)
-    conf_file.flush()
-    RunCommand(cmd, args.verbose,
-               {'MKE2FS_CONFIG': conf_file.name, 'E2FSPROGS_FAKE_TIME': '1'})
-
-    # Compile the file context into the binary form
-    compiled_file_contexts = os.path.join(work_dir, 'file_contexts.bin')
-    cmd = ['sefcontext_compile']
-    cmd.extend(['-o', compiled_file_contexts])
-    cmd.append(args.file_contexts)
-    RunCommand(cmd, args.verbose)
-
-    # Add files to the image file
-    cmd = ['e2fsdroid']
-    cmd.append('-e')  # input is not android_sparse_file
-    cmd.extend(['-f', args.input_dir])
-    cmd.extend(['-T', '0'])  # time is set to epoch
-    cmd.extend(['-S', compiled_file_contexts])
-    cmd.extend(['-C', args.canned_fs_config])
-    cmd.extend(['-a', '/'])
-    cmd.append('-s')  # share dup blocks
-    cmd.append(img_file)
-    RunCommand(cmd, args.verbose, {'E2FSPROGS_FAKE_TIME': '1'})
-
-    cmd = ['e2fsdroid']
-    cmd.append('-e')  # input is not android_sparse_file
-    cmd.extend(['-f', manifests_dir])
-    cmd.extend(['-T', '0'])  # time is set to epoch
-    cmd.extend(['-S', compiled_file_contexts])
-    cmd.extend(['-C', args.canned_fs_config])
-    cmd.extend(['-a', '/'])
-    cmd.append('-s')  # share dup blocks
-    cmd.append(img_file)
-    RunCommand(cmd, args.verbose, {'E2FSPROGS_FAKE_TIME': '1'})
-
-    # Resize the image file to save space
-    cmd = ['resize2fs']
-    cmd.append('-M')  # shrink as small as possible
-    cmd.append(img_file)
-    RunCommand(cmd, args.verbose, {'E2FSPROGS_FAKE_TIME': '1'})
-
-
-def CreateImageF2fs(args, manifests_dir, img_file):
-  """Create image for f2fs file system."""
-  # F2FS requires a ~100M minimum size (necessary for ART, could be reduced
-  # a bit for other)
-  # TODO(b/158453869): relax these requirements for readonly devices
-  size_in_mb = (GetDirSize(args.input_dir) // (1024 * 1024))
-  size_in_mb += 100
-
-  # Create an empty image
-  cmd = ['/usr/bin/fallocate']
-  cmd.extend(['-l', str(size_in_mb) + 'M'])
-  cmd.append(img_file)
-  RunCommand(cmd, args.verbose)
-
-  # Format the image to F2FS
-  cmd = ['make_f2fs']
-  cmd.extend(['-g', 'android'])
-  uu = str(uuid.uuid5(uuid.NAMESPACE_URL, 'www.android.com'))
-  cmd.extend(['-U', uu])
-  cmd.extend(['-T', '0'])
-  cmd.append('-r')  # sets checkpointing seed to 0 to remove random bits
-  cmd.append(img_file)
-  RunCommand(cmd, args.verbose)
-
-  # Add files to the image
-  cmd = ['sload_f2fs']
-  cmd.extend(['-C', args.canned_fs_config])
-  cmd.extend(['-f', manifests_dir])
-  cmd.extend(['-s', args.file_contexts])
-  cmd.extend(['-T', '0'])
-  cmd.append(img_file)
-  RunCommand(cmd, args.verbose, expected_return_values={0, 1})
-
-  cmd = ['sload_f2fs']
-  cmd.extend(['-C', args.canned_fs_config])
-  cmd.extend(['-f', args.input_dir])
-  cmd.extend(['-s', args.file_contexts])
-  cmd.extend(['-T', '0'])
-  cmd.append(img_file)
-  RunCommand(cmd, args.verbose, expected_return_values={0, 1})
-
-  # TODO(b/158453869): resize the image file to save space
-
-
-def CreateImageErofs(args, work_dir, manifests_dir, img_file):
-  """Create image for erofs file system."""
-  # mkfs.erofs doesn't support multiple input
-
-  tmp_input_dir = os.path.join(work_dir, 'tmp_input_dir')
-  os.mkdir(tmp_input_dir)
-  cmd = ['/bin/cp', '-ra']
-  cmd.extend(glob.glob(manifests_dir + '/*'))
-  cmd.extend(glob.glob(args.input_dir + '/*'))
-  cmd.append(tmp_input_dir)
-  RunCommand(cmd, args.verbose)
-
-  cmd = ['make_erofs']
-  cmd.extend(['-z', 'lz4hc'])
-  cmd.extend(['--fs-config-file', args.canned_fs_config])
-  cmd.extend(['--file-contexts', args.file_contexts])
-  uu = str(uuid.uuid5(uuid.NAMESPACE_URL, 'www.android.com'))
-  cmd.extend(['-U', uu])
-  cmd.extend(['-T', '0'])
-  cmd.extend([img_file, tmp_input_dir])
-  RunCommand(cmd, args.verbose)
-  shutil.rmtree(tmp_input_dir)
-
-  # The minimum image size of erofs is 4k, which will cause an error
-  # when execute generate_hash_tree in avbtool
-  cmd = ['/bin/ls', '-lgG', img_file]
-  output, _ = RunCommand(cmd, verbose=False)
-  image_size = int(output.split()[2])
-  if image_size == 4096:
-    cmd = ['/usr/bin/fallocate', '-l', '8k', img_file]
-    RunCommand(cmd, verbose=False)
-
-
-def CreateImage(args, work_dir, manifests_dir, img_file):
-  """create payload image."""
-  if args.payload_fs_type == 'ext4':
-    CreateImageExt4(args, work_dir, manifests_dir, img_file)
-  elif args.payload_fs_type == 'f2fs':
-    CreateImageF2fs(args, manifests_dir, img_file)
-  elif args.payload_fs_type == 'erofs':
-    CreateImageErofs(args, work_dir, manifests_dir, img_file)
-
-
-def SignImage(args, manifest_apex, img_file):
-  """sign payload image.
-
-  Args:
-    args: apexer options
-    manifest_apex: apex manifest proto
-    img_file: unsigned payload image file
-  """
-
-  if args.do_not_check_keyname or args.unsigned_payload:
-    key_name = manifest_apex.name
-  else:
-    key_name = os.path.basename(os.path.splitext(args.key)[0])
-
-  cmd = ['avbtool']
-  cmd.append('add_hashtree_footer')
-  cmd.append('--do_not_generate_fec')
-  cmd.extend(['--algorithm', 'SHA256_RSA4096'])
-  cmd.extend(['--hash_algorithm', 'sha256'])
-  cmd.extend(['--key', args.key])
-  cmd.extend(['--prop', 'apex.key:' + key_name])
-  # Set up the salt based on manifest content which includes name
-  # and version
-  salt = hashlib.sha256(manifest_apex.SerializeToString()).hexdigest()
-  cmd.extend(['--salt', salt])
-  cmd.extend(['--image', img_file])
-  if args.no_hashtree:
-    cmd.append('--no_hashtree')
-  if args.signing_args:
-    cmd.extend(shlex.split(args.signing_args))
-  RunCommand(cmd, args.verbose)
-
-  # Get the minimum size of the partition required.
-  # TODO(b/113320014) eliminate this step
-  info, _ = RunCommand(['avbtool', 'info_image', '--image', img_file],
-                       args.verbose)
-  vbmeta_offset = int(re.search('VBMeta\ offset:\ *([0-9]+)', info).group(1))
-  vbmeta_size = int(re.search('VBMeta\ size:\ *([0-9]+)', info).group(1))
-  partition_size = RoundUp(vbmeta_offset + vbmeta_size,
-                           BLOCK_SIZE) + BLOCK_SIZE
-
-  # Resize to the minimum size
-  # TODO(b/113320014) eliminate this step
-  cmd = ['avbtool']
-  cmd.append('resize_image')
-  cmd.extend(['--image', img_file])
-  cmd.extend(['--partition_size', str(partition_size)])
-  RunCommand(cmd, args.verbose)
-
-
-def CreateApexPayload(args, work_dir, content_dir, manifests_dir,
-                      manifest_apex):
-  """Create payload.
-
-  Args:
-    args: apexer options
-    work_dir: apex container working directory
-    content_dir: the working directory for payload contents
-    manifests_dir: manifests directory
-    manifest_apex: apex manifest proto
-
-  Returns:
-    payload file
-  """
   if args.payload_type == 'image':
+    if args.do_not_check_keyname or args.unsigned_payload:
+      key_name = manifest_apex.name
+    else:
+      key_name = os.path.basename(os.path.splitext(args.key)[0])
+
     img_file = os.path.join(content_dir, 'apex_payload.img')
-    CreateImage(args, work_dir, manifests_dir, img_file)
+
+    if args.payload_fs_type == 'ext4':
+      # sufficiently big = size + 16MB margin
+      size_in_mb += 16
+
+      # margin is for files that are not under args.input_dir. this consists of
+      # n inodes for apex_manifest files and 11 reserved inodes for ext4.
+      # TOBO(b/122991714) eliminate these details. use build_image.py which
+      # determines the optimal inode count by first building an image and then
+      # count the inodes actually used.
+      inode_num_margin = GetFilesAndDirsCount(manifests_dir) + 11
+      inode_num = GetFilesAndDirsCount(args.input_dir) + inode_num_margin
+
+      cmd = ['mke2fs']
+      cmd.extend(['-O', '^has_journal'])  # because image is read-only
+      cmd.extend(['-b', str(BLOCK_SIZE)])
+      cmd.extend(['-m', '0'])  # reserved block percentage
+      cmd.extend(['-t', 'ext4'])
+      cmd.extend(['-I', '256'])  # inode size
+      cmd.extend(['-N', str(inode_num)])
+      uu = str(uuid.uuid5(uuid.NAMESPACE_URL, 'www.android.com'))
+      cmd.extend(['-U', uu])
+      cmd.extend(['-E', 'hash_seed=' + uu])
+      cmd.append(img_file)
+      cmd.append(str(size_in_mb) + 'M')
+      with tempfile.NamedTemporaryFile(dir=work_dir, suffix="mke2fs.conf") as conf_file:
+        conf_data = pkgutil.get_data('apexer', 'mke2fs.conf')
+        conf_file.write(conf_data)
+        conf_file.flush()
+        RunCommand(cmd, args.verbose,
+            {"MKE2FS_CONFIG": conf_file.name, 'E2FSPROGS_FAKE_TIME': '1'})
+
+      # Compile the file context into the binary form
+      compiled_file_contexts = os.path.join(work_dir, 'file_contexts.bin')
+      cmd = ['sefcontext_compile']
+      cmd.extend(['-o', compiled_file_contexts])
+      cmd.append(args.file_contexts)
+      RunCommand(cmd, args.verbose)
+
+      # Add files to the image file
+      cmd = ['e2fsdroid']
+      cmd.append('-e')  # input is not android_sparse_file
+      cmd.extend(['-f', args.input_dir])
+      cmd.extend(['-T', '0'])  # time is set to epoch
+      cmd.extend(['-S', compiled_file_contexts])
+      cmd.extend(['-C', args.canned_fs_config])
+      cmd.append('-s')  # share dup blocks
+      cmd.append(img_file)
+      RunCommand(cmd, args.verbose, {'E2FSPROGS_FAKE_TIME': '1'})
+
+      cmd = ['e2fsdroid']
+      cmd.append('-e')  # input is not android_sparse_file
+      cmd.extend(['-f', manifests_dir])
+      cmd.extend(['-T', '0'])  # time is set to epoch
+      cmd.extend(['-S', compiled_file_contexts])
+      cmd.extend(['-C', args.canned_fs_config])
+      cmd.append('-s')  # share dup blocks
+      cmd.append(img_file)
+      RunCommand(cmd, args.verbose, {'E2FSPROGS_FAKE_TIME': '1'})
+
+      # Resize the image file to save space
+      cmd = ['resize2fs']
+      cmd.append('-M')  # shrink as small as possible
+      cmd.append(img_file)
+      RunCommand(cmd, args.verbose, {'E2FSPROGS_FAKE_TIME': '1'})
+
+    elif args.payload_fs_type == 'f2fs':
+      # F2FS requires a ~100M minimum size (necessary for ART, could be reduced a bit for other)
+      # TODO(b/158453869): relax these requirements for readonly devices
+      size_in_mb += 100
+
+      # Create an empty image
+      cmd = ['/usr/bin/fallocate']
+      cmd.extend(['-l', str(size_in_mb)+'M'])
+      cmd.append(img_file)
+      RunCommand(cmd, args.verbose)
+
+      # Format the image to F2FS
+      cmd = ['make_f2fs']
+      cmd.extend(['-g', 'android'])
+      uu = str(uuid.uuid5(uuid.NAMESPACE_URL, 'www.android.com'))
+      cmd.extend(['-U', uu])
+      cmd.extend(['-T', '0'])
+      cmd.append('-r') # sets checkpointing seed to 0 to remove random bits
+      cmd.append(img_file)
+      RunCommand(cmd, args.verbose)
+
+      # Add files to the image
+      cmd = ['sload_f2fs']
+      cmd.extend(['-C', args.canned_fs_config])
+      cmd.extend(['-f', manifests_dir])
+      cmd.extend(['-s', args.file_contexts])
+      cmd.extend(['-T', '0'])
+      cmd.append(img_file)
+      RunCommand(cmd, args.verbose, expected_return_values={0,1})
+
+      cmd = ['sload_f2fs']
+      cmd.extend(['-C', args.canned_fs_config])
+      cmd.extend(['-f', args.input_dir])
+      cmd.extend(['-s', args.file_contexts])
+      cmd.extend(['-T', '0'])
+      cmd.append(img_file)
+      RunCommand(cmd, args.verbose, expected_return_values={0,1})
+
+      # TODO(b/158453869): resize the image file to save space
+
+    if args.unsigned_payload_only:
+      shutil.copyfile(img_file, args.output)
+      if (args.verbose):
+        print('Created (unsigned payload only) ' + args.output)
+      return True
+
     if not args.unsigned_payload:
-      SignImage(args, manifest_apex, img_file)
+      cmd = ['avbtool']
+      cmd.append('add_hashtree_footer')
+      cmd.append('--do_not_generate_fec')
+      cmd.extend(['--algorithm', 'SHA256_RSA4096'])
+      cmd.extend(['--hash_algorithm', 'sha256'])
+      cmd.extend(['--key', args.key])
+      cmd.extend(['--prop', 'apex.key:' + key_name])
+      # Set up the salt based on manifest content which includes name
+      # and version
+      salt = hashlib.sha256(manifest_apex.SerializeToString()).hexdigest()
+      cmd.extend(['--salt', salt])
+      cmd.extend(['--image', img_file])
+      if args.no_hashtree:
+        cmd.append('--no_hashtree')
+      if args.signing_args:
+        cmd.extend(shlex.split(args.signing_args))
+      RunCommand(cmd, args.verbose)
+
+      # Get the minimum size of the partition required.
+      # TODO(b/113320014) eliminate this step
+      info, _ = RunCommand(['avbtool', 'info_image', '--image', img_file],
+                           args.verbose)
+      vbmeta_offset = int(re.search('VBMeta\ offset:\ *([0-9]+)', info).group(1))
+      vbmeta_size = int(re.search('VBMeta\ size:\ *([0-9]+)', info).group(1))
+      partition_size = RoundUp(vbmeta_offset + vbmeta_size,
+                               BLOCK_SIZE) + BLOCK_SIZE
+
+      # Resize to the minimum size
+      # TODO(b/113320014) eliminate this step
+      cmd = ['avbtool']
+      cmd.append('resize_image')
+      cmd.extend(['--image', img_file])
+      cmd.extend(['--partition_size', str(partition_size)])
+      RunCommand(cmd, args.verbose)
   else:
     img_file = os.path.join(content_dir, 'apex_payload.zip')
     cmd = ['soong_zip']
@@ -722,102 +640,37 @@
     cmd.extend(['-C', manifests_dir])
     cmd.extend(['-D', manifests_dir])
     RunCommand(cmd, args.verbose)
-  return img_file
 
+  if args.payload_only:
+    shutil.copyfile(img_file, args.output)
+    if (args.verbose):
+      print('Created (payload only) ' + args.output)
+    return True
 
-def CreateAndroidManifestXml(args, work_dir, manifest_apex):
-  """Create AndroidManifest.xml file.
-
-  Args:
-    args: apexer options
-    work_dir: apex container working directory
-    manifest_apex: apex manifest proto
-
-  Returns:
-    AndroidManifest.xml file inside the work dir
-  """
+  # package the image file and APEX manifest as an APK.
+  # The AndroidManifest file is automatically generated if not given.
   android_manifest_file = os.path.join(work_dir, 'AndroidManifest.xml')
   if not args.android_manifest:
     if args.verbose:
       print('Creating AndroidManifest ' + android_manifest_file)
-    with open(android_manifest_file, 'w') as f:
+    with open(android_manifest_file, 'w+') as f:
       app_package_name = manifest_apex.name
-      f.write(PrepareAndroidManifest(app_package_name, manifest_apex.version,
-                                     args.test_only))
+      f.write(PrepareAndroidManifest(app_package_name, manifest_apex.version))
     args.android_manifest = android_manifest_file
-    ValidateGeneratedAndroidManifest(args.android_manifest, args.test_only)
   else:
     ValidateAndroidManifest(manifest_apex.name, args.android_manifest)
     shutil.copyfile(args.android_manifest, android_manifest_file)
 
   # If logging parent is specified, add it to the AndroidManifest.
-  if args.logging_parent:
+  if args.logging_parent != "":
     android_manifest_file = AddLoggingParent(android_manifest_file,
                                              args.logging_parent)
-  return android_manifest_file
 
-
-def CreateApex(args, work_dir):
-  if not ValidateArgs(args):
-    return False
-
-  if args.verbose:
-    print('Using tools from ' + str(tool_path_list))
-
-  def CopyFile(src, dst):
-    if args.verbose:
-      print('Copying ' + src + ' to ' + dst)
-    shutil.copyfile(src, dst)
-
-  try:
-    manifest_apex = ValidateApexManifest(args.manifest)
-  except ApexManifestError as err:
-    print("'" + args.manifest + "' is not a valid manifest file")
-    print(err.errmessage)
-    return False
-  except IOError:
-    print("Cannot read manifest file: '" + args.manifest + "'")
-    return False
-
-  # Create content dir and manifests dir, the manifests dir is used to
-  # create the payload image
-  content_dir = os.path.join(work_dir, 'content')
-  os.mkdir(content_dir)
-  manifests_dir = os.path.join(work_dir, 'manifests')
-  os.mkdir(manifests_dir)
-
-  # Create AndroidManifest.xml file first so that we can hash the file
-  # and store the hashed value in the manifest proto buf that goes into
-  # the payload image. So any change in this file will ensure changes
-  # in payload image file
-  android_manifest_file = CreateAndroidManifestXml(
-      args, work_dir, manifest_apex)
-
-  # APEX manifest is also included in the image. The manifest is included
-  # twice: once inside the image and once outside the image (but still
-  # within the zip container).
-  with open(os.path.join(manifests_dir, 'apex_manifest.pb'), 'wb') as f:
-    f.write(manifest_apex.SerializeToString())
-  with open(os.path.join(content_dir, 'apex_manifest.pb'), 'wb') as f:
-    f.write(manifest_apex.SerializeToString())
+  # copy manifest to the content dir so that it is also accessible
+  # without mounting the image
+  copyfile(args.manifest, os.path.join(content_dir, 'apex_manifest.pb'))
   if args.manifest_json:
-    CopyFile(args.manifest_json,
-             os.path.join(manifests_dir, 'apex_manifest.json'))
-    CopyFile(args.manifest_json,
-             os.path.join(content_dir, 'apex_manifest.json'))
-
-  # Create payload
-  img_file = CreateApexPayload(args, work_dir, content_dir, manifests_dir,
-                               manifest_apex)
-
-  if args.unsigned_payload_only or args.payload_only:
-    shutil.copyfile(img_file, args.output)
-    if args.verbose:
-      if args.unsigned_payload_only:
-        print('Created (unsigned payload only) ' + args.output)
-      else:
-        print('Created (payload only) ' + args.output)
-    return True
+    copyfile(args.manifest_json, os.path.join(content_dir, 'apex_manifest.json'))
 
   # copy the public key, if specified
   if args.pubkey:
@@ -825,7 +678,7 @@
 
   if args.include_build_info:
     build_info = GenerateBuildInfo(args)
-    with open(os.path.join(content_dir, 'apex_build_info.pb'), 'wb') as f:
+    with open(os.path.join(content_dir, 'apex_build_info.pb'), "wb") as f:
       f.write(build_info.SerializeToString())
 
   apk_file = os.path.join(work_dir, 'apex.apk')
@@ -853,10 +706,33 @@
   RunCommand(cmd, args.verbose)
 
   zip_file = os.path.join(work_dir, 'apex.zip')
-  CreateZip(content_dir, zip_file)
-  MergeZips([apk_file, zip_file], args.output)
+  cmd = ['soong_zip']
+  cmd.append('-d')  # include directories
+  cmd.extend(['-C', content_dir])  # relative root
+  cmd.extend(['-D', content_dir])  # input dir
+  for file_ in os.listdir(content_dir):
+    if os.path.isfile(os.path.join(content_dir, file_)):
+      cmd.extend(['-s', file_])  # don't compress any files
+  cmd.extend(['-o', zip_file])
+  RunCommand(cmd, args.verbose)
 
-  if args.verbose:
+  unaligned_apex_file = os.path.join(work_dir, 'unaligned.apex')
+  cmd = ['merge_zips']
+  cmd.append('-j')  # sort
+  cmd.append(unaligned_apex_file)  # output
+  cmd.append(apk_file)  # input
+  cmd.append(zip_file)  # input
+  RunCommand(cmd, args.verbose)
+
+  # Align the files at page boundary for efficient access
+  cmd = ['zipalign']
+  cmd.append('-f')
+  cmd.append(str(BLOCK_SIZE))
+  cmd.append(unaligned_apex_file)
+  cmd.append(args.output)
+  RunCommand(cmd, args.verbose)
+
+  if (args.verbose):
     print('Created ' + args.output)
 
   return True
@@ -872,39 +748,6 @@
     shutil.rmtree(self.name)
 
 
-def CreateZip(content_dir, apex_zip):
-  with zipfile.ZipFile(apex_zip, 'w', compression=zipfile.ZIP_DEFLATED) as out:
-    for root, _, files in os.walk(content_dir):
-      for file in files:
-        path = os.path.join(root, file)
-        rel_path = os.path.relpath(path, content_dir)
-        # "apex_payload.img" shouldn't be compressed
-        if rel_path == 'apex_payload.img':
-          out.write(path, rel_path, compress_type=zipfile.ZIP_STORED)
-        else:
-          out.write(path, rel_path)
-
-
-def MergeZips(zip_files, output_zip):
-  with zipfile.ZipFile(output_zip, 'w') as out:
-    for file in zip_files:
-      # copy to output_zip
-      with zipfile.ZipFile(file, 'r') as inzip:
-        for info in inzip.infolist():
-          # reset timestamp for deterministic output
-          info.date_time = (1980, 1, 1, 0, 0, 0)
-          # reset filemode for deterministic output. The high 16 bits are for
-          # filemode. 0x81A4 corresponds to 0o100644(a regular file with
-          # '-rw-r--r--' permission).
-          info.external_attr = 0x81A40000
-          # "apex_payload.img" should be 4K aligned
-          if info.filename == 'apex_payload.img':
-            data_offset = out.fp.tell() + len(info.FileHeader())
-            info.extra = b'\0' * (BLOCK_SIZE - data_offset % BLOCK_SIZE)
-          data = inzip.read(info)
-          out.writestr(info, data)
-
-
 def main(argv):
   global tool_path_list
   args = ParseArgs(argv)
diff --git a/apexer/apexer_test.py b/apexer/apexer_test.py
index da5becd..7fec4ec 100644
--- a/apexer/apexer_test.py
+++ b/apexer/apexer_test.py
@@ -41,6 +41,7 @@
 TEST_PK8_KEY = os.path.join("testdata", "com.android.example.apex.pk8")
 TEST_AVB_PUBLIC_KEY = os.path.join("testdata", "com.android.example.apex.avbpubkey")
 
+
 def run(args, verbose=None, **kwargs):
     """Creates and returns a subprocess.Popen object.
 
@@ -73,7 +74,7 @@
 def run_host_command(args, verbose=None, **kwargs):
     host_build_top = os.environ.get("ANDROID_BUILD_TOP")
     if host_build_top:
-        host_command_dir = os.path.join(host_build_top, "out/host/linux-x86/bin")
+        host_command_dir = os.path.join(host_build_top, "out/soong/host/linux-x86/bin")
         args[0] = os.path.join(host_command_dir, args[0])
     return run_and_check_output(args, verbose, **kwargs)
 
@@ -269,7 +270,7 @@
             payload_only = True
 
         os.environ["APEXER_TOOL_PATH"] = (self.host_tools_path +
-            ":out/host/linux-x86/bin:prebuilts/sdk/tools/linux/bin")
+            ":out/soong/host/linux-x86/bin:prebuilts/sdk/tools/linux/bin")
         cmd = ["apexer", "--force", "--include_build_info", "--do_not_check_keyname"]
         if DEBUG_TEST:
             cmd.append('-v')
@@ -280,7 +281,7 @@
             cmd.extend(["--manifest_json", container_files["apex_manifest.json"]])
         cmd.extend(["--build_info", container_files["apex_build_info.pb"]])
         if not payload_only and "assets" in container_files:
-            cmd.extend(["--assets_dir", container_files["assets"]])
+            cmd.extend(["--assets_dir", "assets"])
         if not unsigned_payload_only:
             cmd.extend(["--key", os.path.join(get_current_dir(), TEST_PRIVATE_KEY)])
             cmd.extend(["--pubkey", os.path.join(get_current_dir(), TEST_AVB_PUBLIC_KEY)])
@@ -314,7 +315,7 @@
             java_dep_lib += ":" + os.path.join(os.environ["ANDROID_HOST_OUT"], "lib64")
         if "ANDROID_BUILD_TOP" in os.environ:
             java_dep_lib += ":" + os.path.join(os.environ["ANDROID_BUILD_TOP"],
-                "out/host/linux-x86/lib64")
+                "out/soong/host/linux-x86/lib64")
 
         return [java_toolchain, java_dep_lib]
 
@@ -327,7 +328,7 @@
             java_toolchain,
             "-Djava.library.path=" + java_dep_lib,
             "-jar", self.host_tools['signapk.jar'],
-            "-a", "4096", "--align-file-size",
+            "-a", "4096",
             os.path.join(get_current_dir(), TEST_X509_KEY),
             os.path.join(get_current_dir(), TEST_PK8_KEY),
             unsigned_apex, fn]
@@ -425,5 +426,6 @@
     def test_apex_with_overridden_package_name(self):
       self._run_build_test(TEST_APEX_WITH_OVERRIDDEN_PACKAGE_NAME)
 
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)
diff --git a/apexer/conv_apex_manifest.py b/apexer/conv_apex_manifest.py
index 9ebf3f9..dd598db 100644
--- a/apexer/conv_apex_manifest.py
+++ b/apexer/conv_apex_manifest.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env python
 #
 # Copyright (C) 2019 The Android Open Source Project
 #
diff --git a/apexer/runtests.sh b/apexer/runtests.sh
index 4d9d602..e2eacc9 100755
--- a/apexer/runtests.sh
+++ b/apexer/runtests.sh
@@ -25,10 +25,10 @@
 
 source ${ANDROID_BUILD_TOP}/build/envsetup.sh
 m -j apexer
-export APEXER_TOOL_PATH="${ANDROID_BUILD_TOP}/out/host/linux-x86/bin:${ANDROID_BUILD_TOP}/prebuilts/sdk/tools/linux/bin"
+export APEXER_TOOL_PATH="${ANDROID_BUILD_TOP}/out/soong/host/linux-x86/bin:${ANDROID_BUILD_TOP}/prebuilts/sdk/tools/linux/bin"
 PATH+=":${ANDROID_BUILD_TOP}/prebuilts/sdk/tools/linux/bin"
 
-for fs_type in ext4 f2fs erofs
+for fs_type in ext4 f2fs
 do
 input_dir=$(mktemp -d)
 output_dir=$(mktemp -d)
@@ -57,7 +57,7 @@
 manifest_dir=$(mktemp -d)
 manifest_file=${manifest_dir}/apex_manifest.pb
 echo '{"name": "com.android.example.apex", "version": 1}' > ${manifest_dir}/apex_manifest.json
-${ANDROID_BUILD_TOP}/out/host/linux-x86/bin/conv_apex_manifest proto ${manifest_dir}/apex_manifest.json -o ${manifest_file}
+${ANDROID_BUILD_TOP}/out/soong/host/linux-x86/bin/conv_apex_manifest proto ${manifest_dir}/apex_manifest.json -o ${manifest_file}
 
 # Create the file_contexts file
 file_contexts_file=$(mktemp)
diff --git a/docs/howto.md b/docs/howto.md
index 270d12f..a704249 100644
--- a/docs/howto.md
+++ b/docs/howto.md
@@ -520,8 +520,8 @@
 
 ```
 $ java \
-  -Djava.library.path=$(dirname out/host/linux-x86/lib64/libconscrypt_openjdk_jni.so)\
-  -jar out/host/linux-x86/framework/signapk.jar \
+  -Djava.library.path=$(dirname out/soong/host/linux-x86/lib64/libconscrypt_openjdk_jni.so)\
+  -jar out/soong/host/linux-x86/framework/signapk.jar \
   -a 4096 \
   <apk_certificate_file> \
   <apk_private_key_file> \
diff --git a/proto/apex_manifest.proto b/proto/apex_manifest.proto
index 9f93594..22fb7d7 100644
--- a/proto/apex_manifest.proto
+++ b/proto/apex_manifest.proto
@@ -33,8 +33,7 @@
   string preInstallHook = 3;
 
   // Post Install Hook
-  // This feature is not supported.
-  string postInstallHook = 4 [ deprecated = true ];
+  string postInstallHook = 4;
 
   // Version Name
   string versionName = 5;
@@ -57,12 +56,9 @@
   // marked as "is_jni: true" from the list of "native_shared_libs".
   repeated string jniLibs = 9;
 
-  // List of libs required that are located in a shared libraries APEX.  The
-  // Android platform only checks whether this list is non-empty, and by default
-  // the Android build system never sets this. This field can be used when
-  // producing or processing an APEX using libraries in /apex/sharedlibs (see
-  // `provideSharedApexLibs` field) to store some information about the
-  // libraries.
+  // List of libs required that are located in a shared libraries APEX.
+  // Format of the content is 'library:hash'.
+  // Example) libc++.so:83d8f50...
   repeated string requireSharedApexLibs = 10;
 
   // Whether this APEX provides libraries to be shared with other APEXs. This
@@ -83,3 +79,4 @@
   // Indicates that this APEX can be updated without rebooting device.
   bool supportsRebootlessUpdate = 13;
 }
+
diff --git a/shim/build/Android.bp b/shim/build/Android.bp
index 99121d2..2fa99bf 100644
--- a/shim/build/Android.bp
+++ b/shim/build/Android.bp
@@ -265,7 +265,6 @@
     ":com.android.apex.cts.shim.v2_with_post_install_hook",
     ":com.android.apex.cts.shim.v2_sdk_target_p",
     ":com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p",
-    ":com.android.apex.cts.shim.v2_apk_in_apex_upgrades",
     ":com.android.apex.cts.shim.v2_rebootless",
     ":com.android.apex.cts.shim.v3",
     ":com.android.apex.cts.shim.v3_rebootless",
@@ -448,7 +447,7 @@
     targets: ["com.android.apex.cts.shim.v2_signed_bob_rot"],
     dest: "com.android.apex.cts.shim.v2_signed_bob_rot.apex",
   },
-  cmd: "$(location :apksigner) sign --v1-signing-enabled false --v2-signing-enabled false --key $(location :com.android.apex.rotation.key.bob.pk8) --cert $(location :com.android.apex.rotation.key.bob.x509.pem) --lineage $(location :com.android.apex.rotation.key.bob.rot) --rotation-min-sdk-version 28 --out $(out) $(location :com.android.apex.cts.shim.v2)",
+  cmd: "$(location :apksigner) sign --v1-signing-enabled false --v2-signing-enabled false --key $(location :com.android.apex.rotation.key.bob.pk8) --cert $(location :com.android.apex.rotation.key.bob.x509.pem) --lineage $(location :com.android.apex.rotation.key.bob.rot) --out $(out) $(location :com.android.apex.cts.shim.v2)",
 }
 
 // v2 cts shim package signed by bob + lineage + rollback capability
@@ -466,7 +465,7 @@
     targets: ["com.android.apex.cts.shim.v2_signed_bob_rot_rollback"],
     dest: "com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex",
   },
-  cmd: "$(location :apksigner) sign --v1-signing-enabled false --v2-signing-enabled false --key $(location :com.android.apex.rotation.key.bob.pk8) --cert $(location :com.android.apex.rotation.key.bob.x509.pem) --lineage $(location :com.android.apex.rotation.key.bob.rot.rollback) --rotation-min-sdk-version 28 --out $(out) $(location :com.android.apex.cts.shim.v2)",
+  cmd: "$(location :apksigner) sign --v1-signing-enabled false --v2-signing-enabled false --key $(location :com.android.apex.rotation.key.bob.pk8) --cert $(location :com.android.apex.rotation.key.bob.x509.pem) --lineage $(location :com.android.apex.rotation.key.bob.rot.rollback) --out $(out) $(location :com.android.apex.cts.shim.v2)",
 }
 
 // v3 cts shim package signed by bob
@@ -501,7 +500,7 @@
     targets: ["com.android.apex.cts.shim.v3_signed_bob_rot"],
     dest: "com.android.apex.cts.shim.v3_signed_bob_rot.apex",
   },
-  cmd: "$(location :apksigner) sign --v1-signing-enabled false --v2-signing-enabled false --key $(location :com.android.apex.rotation.key.bob.pk8) --cert $(location :com.android.apex.rotation.key.bob.x509.pem) --lineage $(location :com.android.apex.rotation.key.bob.rot) --rotation-min-sdk-version 28 --out $(out) $(location :com.android.apex.cts.shim.v3)",
+  cmd: "$(location :apksigner) sign --v1-signing-enabled false --v2-signing-enabled false --key $(location :com.android.apex.rotation.key.bob.pk8) --cert $(location :com.android.apex.rotation.key.bob.x509.pem) --lineage $(location :com.android.apex.rotation.key.bob.rot) --out $(out) $(location :com.android.apex.cts.shim.v3)",
 }
 
 // This one is only used in ApexdHostTest and not meant to be installed
@@ -583,16 +582,3 @@
   installable: false,
   updatable: false,
 }
-
-// Apex shim with upgraded apk-in-apexes
-apex {
-  name: "com.android.apex.cts.shim.v2_apk_in_apex_upgrades",
-  manifest: "manifest_v2.json",
-  androidManifest: "AndroidManifest.xml",
-  file_contexts: ":apex.test-file_contexts",
-  key: "com.android.apex.cts.shim.key",
-  prebuilts: ["hash_of_dev_null"],
-  apps: ["CtsShim", "CtsShimPrivUpgrade"],
-  installable: false,
-  updatable: false,
-}
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v1.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v1.apex
index c2dc28f..791d0dd 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v1.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v1.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2.apex
index 880ab4a..0a26d23 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_additional_file.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_additional_file.apex
index 8c84cd5..5ed2c7e 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_additional_file.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_additional_file.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_additional_folder.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_additional_folder.apex
index b519bbe..133f7f7 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_additional_folder.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_additional_folder.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
index 38e2339..6ce5397 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex
deleted file mode 100644
index 3d7bf51..0000000
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex
+++ /dev/null
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_different_certificate.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_different_certificate.apex
index f4bc7e8..4228ffe 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_different_certificate.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_different_certificate.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_different_package_name.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_different_package_name.apex
index 59e9fe1..de090f1 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_different_package_name.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_different_package_name.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_no_hashtree.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_no_hashtree.apex
index 353949b..162044c 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_no_hashtree.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_no_hashtree.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_rebootless.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_rebootless.apex
index c39b790..9d68887 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_rebootless.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_rebootless.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_sdk_target_p.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_sdk_target_p.apex
index da25328..44f7613 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_sdk_target_p.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_sdk_target_p.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
index 3eaf372..389871d 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob.apex
index 6f38273..f8fa44f 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob_rot.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob_rot.apex
index 1969746..9658818 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob_rot.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob_rot.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
index be642bf..3440043 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_unsigned_payload.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_unsigned_payload.apex
index 7bebb77..d6f7d8f 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_unsigned_payload.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_unsigned_payload.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_with_post_install_hook.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_with_post_install_hook.apex
index 8006022..cc214f8 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_with_post_install_hook.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_with_post_install_hook.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_with_pre_install_hook.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
index 3465dbb..dab82a0 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_without_apk_in_apex.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
index 67743a9..9706f2f 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_wrong_sha.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_wrong_sha.apex
index aa1c10c..f305cff 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v2_wrong_sha.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v2_wrong_sha.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v3.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v3.apex
index b345bca..3122c96 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v3.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v3.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v3_rebootless.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v3_rebootless.apex
index c3bab7c..0f5134d 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v3_rebootless.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v3_rebootless.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v3_signed_bob.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v3_signed_bob.apex
index 4733bad..a83bf51 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v3_signed_bob.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v3_signed_bob.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim.v3_signed_bob_rot.apex b/shim/prebuilts/arm/com.android.apex.cts.shim.v3_signed_bob_rot.apex
index 6972daa..703b641 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim.v3_signed_bob_rot.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim.v3_signed_bob_rot.apex
Binary files differ
diff --git a/shim/prebuilts/arm/com.android.apex.cts.shim_not_pre_installed.apex b/shim/prebuilts/arm/com.android.apex.cts.shim_not_pre_installed.apex
index 4cda1c6..806ccc7 100644
--- a/shim/prebuilts/arm/com.android.apex.cts.shim_not_pre_installed.apex
+++ b/shim/prebuilts/arm/com.android.apex.cts.shim_not_pre_installed.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v1.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v1.apex
index 030c53b..a94ae75 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v1.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v1.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2.apex
index b090a96..a9c2758 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_additional_file.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_additional_file.apex
index c498b32..5ed2c7e 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_additional_file.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_additional_file.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_additional_folder.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_additional_folder.apex
index e83ec07..133f7f7 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_additional_folder.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_additional_folder.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
index 4545b1c..6ce5397 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_apk_in_apex_sdk_target_p.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex
deleted file mode 100644
index 298fd85..0000000
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_apk_in_apex_upgrades.apex
+++ /dev/null
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_different_certificate.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_different_certificate.apex
index d911fe0..4228ffe 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_different_certificate.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_different_certificate.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_different_package_name.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_different_package_name.apex
index 053df91..de090f1 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_different_package_name.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_different_package_name.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_no_hashtree.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_no_hashtree.apex
index 65a5473..19ec142 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_no_hashtree.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_no_hashtree.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_rebootless.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_rebootless.apex
index 9f94684..9d68887 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_rebootless.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_rebootless.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_sdk_target_p.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_sdk_target_p.apex
index 8fd510c..9929c3d 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_sdk_target_p.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_sdk_target_p.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
index baae3e3..389871d 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_sign_payload_with_different_key.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob.apex
index 1e80788..3f2fc50 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob_rot.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob_rot.apex
index c064928..cf628ab 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob_rot.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob_rot.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
index 685f347..ba5af3b 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_signed_bob_rot_rollback.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_unsigned_payload.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_unsigned_payload.apex
index f2329ae..38c073f 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_unsigned_payload.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_unsigned_payload.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_with_post_install_hook.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_with_post_install_hook.apex
index bb2d96e..cc214f8 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_with_post_install_hook.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_with_post_install_hook.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_with_pre_install_hook.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
index fd00bd5..dab82a0 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_with_pre_install_hook.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_without_apk_in_apex.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
index e7da653..9706f2f 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_without_apk_in_apex.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_wrong_sha.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_wrong_sha.apex
index 32bf141..f305cff 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v2_wrong_sha.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v2_wrong_sha.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v3.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v3.apex
index 1bd8b1b..7f3e9ec 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v3.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v3.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v3_rebootless.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v3_rebootless.apex
index 2f7a2e5..0f5134d 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v3_rebootless.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v3_rebootless.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v3_signed_bob.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v3_signed_bob.apex
index 38fe019..1aeb0b0 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v3_signed_bob.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v3_signed_bob.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim.v3_signed_bob_rot.apex b/shim/prebuilts/x86/com.android.apex.cts.shim.v3_signed_bob_rot.apex
index 68505d5..20f1c85 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim.v3_signed_bob_rot.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim.v3_signed_bob_rot.apex
Binary files differ
diff --git a/shim/prebuilts/x86/com.android.apex.cts.shim_not_pre_installed.apex b/shim/prebuilts/x86/com.android.apex.cts.shim_not_pre_installed.apex
index 7fd07b5..806ccc7 100644
--- a/shim/prebuilts/x86/com.android.apex.cts.shim_not_pre_installed.apex
+++ b/shim/prebuilts/x86/com.android.apex.cts.shim_not_pre_installed.apex
Binary files differ
diff --git a/tests/Android.bp b/tests/Android.bp
index 956af99..425f2bc 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -87,7 +87,6 @@
 apex {
     name: "apex.test",
     manifest: "testdata/apex_manifest.json",
-    androidManifest: "testdata/AndroidManifest.xml",
     prebuilts: ["sample_prebuilt_file"],
     key: "apex.test.key",
     certificate: ":apex.test.certificate",
@@ -221,8 +220,8 @@
 
 android_test_helper_app {
     name: "apex_compression_tests_app",
-    manifest: "app/ApexCompressionTests_AndroidManifest.xml",
-    srcs: ["app/src/**/ApexCompressionTests.java"],
+    manifest: "app/AndroidManifest.xml",
+    srcs: ["app/src/**/*.java"],
     static_libs: ["androidx.test.rules", "cts-install-lib", "cts-rollback-lib", "testng"],
     test_suites: ["general-tests"],
     java_resources: [
@@ -230,89 +229,3 @@
         ":com.android.apex.compressed.v2_original",
     ]
 }
-
-java_test_host {
-    name: "apex_apkinapex_tests",
-    srcs:  ["src/**/ApkInApexTests.java"],
-    libs: ["tradefed", "truth-prebuilt"],
-    static_libs: ["cts-install-lib-host", "frameworks-base-hostutils", "testng"],
-    test_config: "apk-in-apex-tests.xml",
-    test_suites: ["general-tests"],
-    data: [
-        ":apex_apkinapex_tests_app",
-    ],
-    java_resources: [
-        ":com.android.apex.product.test",
-        ":com.android.apex.product.app.test.xml",
-        ":com.android.apex.system.test",
-        ":com.android.apex.system.app.test.xml",
-        ":com.android.apex.system_ext.test",
-        ":com.android.apex.system_ext.app.test.xml",
-        ":com.android.apex.vendor.test",
-        ":com.android.apex.vendor.app.test.xml",
-    ],
-}
-
-cc_test_library {
-    name: "libApkInApex_jni",
-    gtest: false,
-    srcs: [
-        "app/jni/com_android_tests_apex_app_ApkInApexTests.cpp",
-    ],
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-    header_libs: [
-        "jni_headers"
-    ],
-    stl: "c++_shared",
-    sdk_version: "current",
-}
-
-java_test_host {
-    name: "apex_apkinapexmaxsdk_tests",
-    srcs: ["src/**/MaxSdkTests.java"],
-    libs: [
-        "tradefed",
-        "truth-prebuilt"
-    ],
-    static_libs: [
-        "cts-install-lib-host",
-        "frameworks-base-hostutils",
-        "testng"
-    ],
-    test_config: "max-sdk-tests.xml",
-    test_suites: ["general-tests"],
-    data: [
-        ":apex_maxsdk_tests_app",
-        ":apex_maxsdk_regular_app_tests",
-    ],
-    java_resources: [
-        ":com.android.apex.maxsdk.test",
-    ],
-}
-
-android_test_helper_app {
-    name: "apex_apkinapex_tests_app",
-    manifest: "app/ApkInApexTests_AndroidManifest.xml",
-    srcs: ["app/src/**/ApkInApexTests.java"],
-    jni_libs: [
-        "libApkInApex_jni",
-    ],
-    static_libs: ["androidx.test.rules", "cts-install-lib", "cts-rollback-lib", "testng"],
-    test_suites: ["general-tests"],
-}
-
-android_test_helper_app {
-    name: "apex_maxsdk_tests_app",
-    manifest: "app/MaxSdkTests_AndroidManifest.xml",
-    srcs: ["app/src/**/MaxSdkTests.java"],
-    static_libs: ["androidx.test.rules", "cts-install-lib", "cts-rollback-lib", "testng"],
-    test_suites: ["general-tests"],
-}
-
-android_test_helper_app {
-    name: "apex_maxsdk_regular_app_tests",
-    manifest: "testdata/maxsdk/app/AndroidManifest_normalApp.xml",
-}
diff --git a/tests/OWNERS b/tests/OWNERS
index 93a9224..0ffc7cf 100644
--- a/tests/OWNERS
+++ b/tests/OWNERS
@@ -1,4 +1,3 @@
 chenzhu@google.com
 jiyong@google.com
-satayev@google.com
 yuwu@google.com
diff --git a/tests/README.md b/tests/README.md
index ae42641..1d71d30 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -1 +1,4 @@
 Integration tests for Apex OS Infrastructure.
+
+Presently, these tests require an unreleased version of the framework, and
+therefore will not likely succeed on a pure AOSP build.
diff --git a/tests/TEST_MAPPING b/tests/TEST_MAPPING
index dd4daa2..d3177a8 100644
--- a/tests/TEST_MAPPING
+++ b/tests/TEST_MAPPING
@@ -7,9 +7,6 @@
       "name": "timezone_data_e2e_tests"
     },
     {
-      "name": "apex_apkinapex_tests"
-    },
-    {
       "name": "CtsApexSharedLibrariesTestCases"
     }
   ],
diff --git a/tests/apk-in-apex-tests.xml b/tests/apk-in-apex-tests.xml
deleted file mode 100644
index baa00b6..0000000
--- a/tests/apk-in-apex-tests.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Runs the apk-in-apex test cases">
-    <option name="test-suite-tag" value="apk-in-apex-tests" />
-    <option name="test-suite-tag" value="apct" />
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="apex_apkinapex_tests_app.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.HostTest" >
-        <option name="class"
-                value="com.android.tests.apex.host.ApkInApexTests" />
-    </test>
-</configuration>
diff --git a/tests/app/ApexCompressionTests_AndroidManifest.xml b/tests/app/AndroidManifest.xml
similarity index 93%
rename from tests/app/ApexCompressionTests_AndroidManifest.xml
rename to tests/app/AndroidManifest.xml
index 428ab69..0644ba7 100644
--- a/tests/app/ApexCompressionTests_AndroidManifest.xml
+++ b/tests/app/AndroidManifest.xml
@@ -16,7 +16,7 @@
   -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.tests.apex.compression.app" >
+          package="com.android.tests.apex.app" >
 
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
     <application>
@@ -27,7 +27,7 @@
 
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.tests.apex.compression.app"
+                     android:targetPackage="com.android.tests.apex.app"
                      android:label="ApexCompression Test"/>
 
 </manifest>
diff --git a/tests/app/ApkInApexTests_AndroidManifest.xml b/tests/app/ApkInApexTests_AndroidManifest.xml
deleted file mode 100644
index 59e7fa9..0000000
--- a/tests/app/ApkInApexTests_AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2021 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.
-  -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.tests.apex.apkinapex.app" >
-
-    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
-    <application>
-        <receiver android:name="com.android.cts.install.lib.LocalIntentSender"
-                  android:exported="true" />
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.tests.apex.apkinapex.app"
-                     android:label="ApexCompression Test"/>
-
-</manifest>
diff --git a/tests/app/MaxSdkTests_AndroidManifest.xml b/tests/app/MaxSdkTests_AndroidManifest.xml
deleted file mode 100644
index 1aec150..0000000
--- a/tests/app/MaxSdkTests_AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2022 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.
-  -->
-
-<manifest
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.tests.apex.maxsdk.app">
-
-    <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
-
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-
-    <instrumentation
-            android:name="androidx.test.runner.AndroidJUnitRunner"
-            android:targetPackage="com.android.tests.apex.maxsdk.app"
-            android:label="ApexMaxSdk Test" />
-</manifest>
diff --git a/tests/app/jni/com_android_tests_apex_app_ApkInApexTests.cpp b/tests/app/jni/com_android_tests_apex_app_ApkInApexTests.cpp
deleted file mode 100644
index a948c7a..0000000
--- a/tests/app/jni/com_android_tests_apex_app_ApkInApexTests.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2022 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.
- *
- */
-
-#include <jni.h>
-
-namespace {
-
-bool fakeMethod() { return true; }
-
-jint com_android_tests_apex_app_nativeFakeMethod(JNIEnv * /*env*/,
-                                                 jclass /*clazz*/) {
-  return (jboolean)fakeMethod();
-}
-
-static JNINativeMethod gMethods[] = {
-    {"nativeFakeMethod", "()Z",
-     (void *)com_android_tests_apex_app_nativeFakeMethod}};
-
-} // anonymous namespace
-
-int register_android_native_code_test_data(JNIEnv *env) {
-  jclass clazz = env->FindClass("com/android/tests/apex/app/ApkInApexTests");
-  return env->RegisterNatives(clazz, gMethods,
-                              sizeof(gMethods) / sizeof(JNINativeMethod));
-}
-
-jint JNI_OnLoad(JavaVM *vm, void * /*reserved*/) {
-  JNIEnv *env = nullptr;
-  if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK)
-    return JNI_ERR;
-  if (register_android_native_code_test_data(env))
-    return JNI_ERR;
-  return JNI_VERSION_1_6;
-}
diff --git a/tests/app/src/com/android/tests/apex/app/ApexCompressionTests.java b/tests/app/src/com/android/tests/apex/app/ApexCompressionTests.java
index b0989d0..a97293c 100644
--- a/tests/app/src/com/android/tests/apex/app/ApexCompressionTests.java
+++ b/tests/app/src/com/android/tests/apex/app/ApexCompressionTests.java
@@ -28,6 +28,7 @@
 import androidx.test.InstrumentationRegistry;
 
 import com.android.cts.install.lib.Install;
+import com.android.cts.install.lib.InstallUtils;
 import com.android.cts.install.lib.TestApp;
 import com.android.cts.rollback.lib.RollbackUtils;
 
@@ -146,6 +147,8 @@
         // Trigger rollback
         RollbackInfo available = RollbackUtils.getAvailableRollback(COMPRESSED_APEX_PACKAGE_NAME);
         RollbackUtils.rollback(available.getRollbackId(), UNCOMPRESSED_APEX_V2);
+        RollbackInfo committed = RollbackUtils.getCommittedRollbackById(available.getRollbackId());
+        InstallUtils.waitForSessionReady(committed.getCommittedSessionId());
     }
 
     @Test
diff --git a/tests/app/src/com/android/tests/apex/app/ApkInApexTests.java b/tests/app/src/com/android/tests/apex/app/ApkInApexTests.java
deleted file mode 100644
index f069378..0000000
--- a/tests/app/src/com/android/tests/apex/app/ApkInApexTests.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2021 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.tests.apex.app;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-
-import androidx.test.InstrumentationRegistry;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ApkInApexTests {
-    private final Context mContext = InstrumentationRegistry.getContext();
-    private final PackageManager mPm = mContext.getPackageManager();
-
-
-    @Before
-    public void adoptShellPermissions() {
-        InstrumentationRegistry
-                .getInstrumentation()
-                .getUiAutomation()
-                .adoptShellPermissionIdentity(
-                        Manifest.permission.INSTALL_PACKAGES,
-                        Manifest.permission.DELETE_PACKAGES,
-                        Manifest.permission.TEST_MANAGE_ROLLBACKS);
-    }
-
-    @After
-    public void dropShellPermissions() {
-        InstrumentationRegistry
-                .getInstrumentation()
-                .getUiAutomation()
-                .dropShellPermissionIdentity();
-    }
-
-    @Test
-    public void testPrivPermissionIsGranted() throws Exception {
-        PackageInfo pi = mPm.getPackageInfo("com.android.apex.product.app.test",
-                PackageManager.GET_PERMISSIONS);
-        assertThat(pi.requestedPermissions).asList()
-                .contains("android.permission.PACKAGE_USAGE_STATS");
-
-        pi = mPm.getPackageInfo("com.android.apex.system.app.test",
-                PackageManager.GET_PERMISSIONS);
-        assertThat(pi.requestedPermissions).asList()
-                .contains("android.permission.PACKAGE_USAGE_STATS");
-
-        pi = mPm.getPackageInfo("com.android.apex.system_ext.app.test",
-                PackageManager.GET_PERMISSIONS);
-        assertThat(pi.requestedPermissions).asList()
-                .contains("android.permission.PACKAGE_USAGE_STATS");
-
-        pi = mPm.getPackageInfo("com.android.apex.vendor.app.test",
-                PackageManager.GET_PERMISSIONS);
-
-        assertThat(pi.requestedPermissions).asList()
-                .contains("android.permission.START_ACTIVITIES_FROM_BACKGROUND");
-    }
-
-    @Test
-    public void testJniCalls() throws Exception {
-        System.loadLibrary("ApkInApex_jni");
-        assertThat(nativeFakeMethod()).isTrue();
-    }
-
-    private native boolean nativeFakeMethod();
-}
diff --git a/tests/app/src/com/android/tests/apex/app/MaxSdkTests.java b/tests/app/src/com/android/tests/apex/app/MaxSdkTests.java
deleted file mode 100644
index e149022..0000000
--- a/tests/app/src/com/android/tests/apex/app/MaxSdkTests.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2022 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.tests.apex.app;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-
-import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-
-import androidx.test.InstrumentationRegistry;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class MaxSdkTests {
-    // these apps are installed via apk-in-apex
-    private static final String APP_NO_MAX_SDK = "com.android.apex.maxsdk.app.available.test";
-    private static final String APP_MAX_SDK_10K =
-            "com.android.apex.maxsdk.app.available.target10k.test";
-    private static final String APP_MAX_SDK_31 = "com.android.apex.maxsdk.app.unavailable.test";
-    // REGULAR_APP is installed as a normal app
-    private static final String REGULAR_APP_WITH_MAX_SDK =
-            "com.android.apex.maxsdk.regular.app.test";
-    private final Context mContext = InstrumentationRegistry.getContext();
-    private final PackageManager mPm = mContext.getPackageManager();
-
-    @Test
-    public void testApkInApexIsAvailable() throws Exception {
-        PackageInfo pi = mPm.getPackageInfo(APP_NO_MAX_SDK, 0);
-        assertThat(pi).isNotNull();
-    }
-
-    @Test
-    public void testAppWithMaxSdk10KIsAvailable() throws Exception {
-        PackageInfo pi = mPm.getPackageInfo(APP_MAX_SDK_10K, 0);
-        assertThat(pi).isNotNull();
-    }
-
-    @Test
-    public void testAppWithMaxSdk31() throws Exception {
-        // this app should not be available because it has uses-sdk maxSdkVersion="31"
-        assertThrows(PackageManager.NameNotFoundException.class,
-                () -> mPm.getPackageInfo(APP_MAX_SDK_31, 0));
-    }
-
-    @Test
-    public void testRegularAppIsAvailable() throws Exception {
-        // because this is a regular app, max-sdk should not be checked
-        PackageInfo pi = mPm.getPackageInfo(REGULAR_APP_WITH_MAX_SDK, 0);
-        assertThat(pi).isNotNull();
-    }
-}
diff --git a/tests/max-sdk-tests.xml b/tests/max-sdk-tests.xml
deleted file mode 100644
index afc1ef8..0000000
--- a/tests/max-sdk-tests.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<configuration description="Runs the max-sdk support test cases">
-    <option name="test-suite-tag" value="max-sdk-tests" />
-    <option name="test-suite-tag" value="apct" />
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="apex_maxsdk_tests_app.apk" />
-        <option name="test-file-name" value="apex_maxsdk_regular_app_tests.apk" />
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.HostTest" >
-        <option name="class"
-                value="com.android.tests.apex.host.MaxSdkTests" />
-    </test>
-</configuration>
diff --git a/tests/native/AndroidTest.xml b/tests/native/AndroidTest.xml
index be00cda..fa189d5 100644
--- a/tests/native/AndroidTest.xml
+++ b/tests/native/AndroidTest.xml
@@ -26,7 +26,4 @@
         <option name="module-name" value="CtsApexSharedLibrariesTestCases" />
         <option name="runtime-hint" value="65s" />
     </test>
-    <!-- Controller that will skip the module if a native bridge situation is detected -->
-    <!-- For example: module wants to run arm32 and device is x86 -->
-    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.NativeBridgeModuleController" />
 </configuration>
diff --git a/tests/src/com/android/tests/apex/ApexE2EBaseHostTest.java b/tests/src/com/android/tests/apex/ApexE2EBaseHostTest.java
index 6203b9b..e0871df 100644
--- a/tests/src/com/android/tests/apex/ApexE2EBaseHostTest.java
+++ b/tests/src/com/android/tests/apex/ApexE2EBaseHostTest.java
@@ -16,11 +16,13 @@
 
 package com.android.tests.apex;
 
+import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.junit.Assume.assumeTrue;
 
 import android.cts.install.lib.host.InstallUtilsHost;
+import android.platform.test.annotations.RequiresDevice;
 
 import com.android.tests.rollback.host.AbandonSessionsRule;
 import com.android.tradefed.config.Option;
@@ -49,6 +51,9 @@
 
     private static final Duration BOOT_COMPLETE_TIMEOUT = Duration.ofMinutes(2);
 
+    private static final String USERSPACE_REBOOT_SUPPORTED_PROP =
+            "init.userspace_reboot.is_supported";
+
     // Protected so that derived tests can have access to test utils automatically
     protected final InstallUtilsHost mHostUtils = new InstallUtilsHost(this);
 
@@ -80,13 +85,21 @@
 
     @Test
     public final void testStageActivateUninstallApexPackage()  throws Exception {
-        stageActivateUninstallApexPackage();
+        stageActivateUninstallApexPackage(false/*userspaceReboot*/);
     }
 
-    private void stageActivateUninstallApexPackage()  throws Exception {
+    @Test
+    @RequiresDevice // TODO(b/147726967): Remove when Userspace reboot works on cuttlefish
+    public final void testStageActivateUninstallApexPackageWithUserspaceReboot()  throws Exception {
+        assumeTrue("Userspace reboot not supported on the device",
+                getDevice().getBooleanProperty(USERSPACE_REBOOT_SUPPORTED_PROP, false));
+        stageActivateUninstallApexPackage(true/*userspaceReboot*/);
+    }
+
+    private void stageActivateUninstallApexPackage(boolean userspaceReboot)  throws Exception {
         ApexInfo apex = installApex(mApexFileName);
 
-        getDevice().reboot(); // for install to take affect
+        reboot(userspaceReboot); // for install to take affect
         Set<ApexInfo> activatedApexes = getDevice().getActiveApexes();
         assertWithMessage("Failed to activate %s", apex).that(activatedApexes).contains(apex);
 
@@ -112,6 +125,25 @@
         return testApexInfo;
     }
 
+    protected final void reboot(boolean userspaceReboot) throws Exception {
+        if (userspaceReboot) {
+            assertThat(getDevice().setProperty("test.userspace_reboot.requested", "1")).isTrue();
+            getDevice().rebootUserspace();
+        } else {
+            getDevice().reboot();
+        }
+        boolean success = getDevice().waitForBootComplete(BOOT_COMPLETE_TIMEOUT.toMillis());
+        assertWithMessage("Device didn't boot in %s", BOOT_COMPLETE_TIMEOUT).that(success).isTrue();
+        if (userspaceReboot) {
+            // If userspace reboot fails and fallback to hard reboot is triggered then
+            // test.userspace_reboot.requested won't be set.
+            boolean res = getDevice().getBooleanProperty("test.userspace_reboot.requested", false);
+            String message = "Userspace reboot failed, fallback to full reboot was triggered. ";
+            message += "Boot reason: " + getDevice().getProperty("sys.boot.reason.last");
+            assertWithMessage(message).that(res).isTrue();
+        }
+    }
+
     /**
      * Do some additional check, invoked by {@link #testStageActivateUninstallApexPackage()}.
      */
diff --git a/tests/src/com/android/tests/apex/ApexRollbackTests.java b/tests/src/com/android/tests/apex/ApexRollbackTests.java
index b7cb78b..68f82ca 100644
--- a/tests/src/com/android/tests/apex/ApexRollbackTests.java
+++ b/tests/src/com/android/tests/apex/ApexRollbackTests.java
@@ -52,10 +52,6 @@
 
     private boolean mWasAdbRoot = false;
 
-    private static boolean sCheckedIfCrashingProcessExists = false;
-    private static boolean sAlreadyCrashingProcessExists = false;
-    private static String sCrashingProcess;
-
     @Before
     public void setUp() throws Exception {
         mHostUtils.uninstallShimApexIfNecessary();
@@ -64,12 +60,6 @@
         if (!mWasAdbRoot) {
             assumeTrue("Requires root", getDevice().enableAdbRoot());
         }
-        if (!sCheckedIfCrashingProcessExists) {
-            sAlreadyCrashingProcessExists =
-                    getDevice().getBooleanProperty("sys.init.updatable_crashing", false);
-            sCrashingProcess = getDevice().getProperty("sys.init.updatable_crashing_process_name");
-            sCheckedIfCrashingProcessExists = true;
-        }
     }
 
     /**
@@ -105,9 +95,11 @@
         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
         ITestDevice device = getDevice();
         // Skip this test if there is already crashing process on device
+        boolean hasCrashingProcess =
+                device.getBooleanProperty("sys.init.updatable_crashing", false);
+        String crashingProcess = device.getProperty("sys.init.updatable_crashing_process_name");
         assumeFalse(
-                "Device already has a crashing process: " + sCrashingProcess,
-                sAlreadyCrashingProcessExists);
+                "Device already has a crashing process: " + crashingProcess, hasCrashingProcess);
         File apexFile = mHostUtils.getTestFile("com.android.apex.cts.shim.v2.apex");
 
         // To simulate an apex update that causes a boot loop, we install a
@@ -261,6 +253,8 @@
         assertThat(activatedApexes).doesNotContain(ctsShimV1);
     }
 
+    // TODO(ioffe): check that we recover from the boot loop in case of userspace reboot.
+
     /**
      * Test to verify that apexd won't boot loop a device in case {@code sys.init
      * .updatable_crashing} is {@code true} and there is no apex session to revert.
@@ -281,6 +275,97 @@
     }
 
     /**
+     * Test to verify that if a hard reboot is triggered during userspace reboot boot
+     * sequence, an apex update will not be reverted.
+     */
+    @Test
+    public void testFailingUserspaceReboot_doesNotRevertUpdate() throws Exception {
+        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+        assumeTrue("Device doesn't support userspace reboot",
+                getDevice().getBooleanProperty("init.userspace_reboot.is_supported", false));
+        assumeTrue("Device doesn't support fs checkpointing", mHostUtils.isCheckpointSupported());
+
+        File apexFile = mHostUtils.getTestFile("com.android.apex.cts.shim.v2.apex");
+        // Simulate failure in userspace reboot by triggering a full reboot in the middle of the
+        // boot sequence.
+        assertThat(getDevice().setProperty("test.apex_revert_test_force_reboot", "1")).isTrue();
+        String error = mHostUtils.installStagedPackage(apexFile);
+        assertWithMessage("Failed to stage com.android.apex.cts.shim.v2.apex : %s", error).that(
+                error).isNull();
+        // After we reboot the device, apexd will apply the update
+        getDevice().rebootUserspace();
+        // Verify that hard reboot happened.
+        assertThat(getDevice().getIntProperty("sys.init.userspace_reboot.last_finished",
+                -1)).isEqualTo(-1);
+        Set<ApexInfo> activatedApexes = getDevice().getActiveApexes();
+        assertThat(activatedApexes).doesNotContain(new ApexInfo("com.android.apex.cts.shim", 1L));
+        assertThat(activatedApexes).contains(new ApexInfo("com.android.apex.cts.shim", 2L));
+    }
+
+    /**
+     * Test to verify that if a hard reboot is triggered before executing init executes {@code
+     * /system/bin/vdc checkpoint markBootAttempt} of userspace reboot boot sequence, apex update
+     * still will be installed.
+     */
+    @Test
+    public void testUserspaceRebootFailedShutdownSequence_doesNotRevertUpdate() throws Exception {
+        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+        assumeTrue("Device doesn't support userspace reboot",
+                getDevice().getBooleanProperty("init.userspace_reboot.is_supported", false));
+        assumeTrue("Device doesn't support fs checkpointing", mHostUtils.isCheckpointSupported());
+
+        File apexFile = mHostUtils.getTestFile("com.android.apex.cts.shim.v2.apex");
+        // Simulate failure in userspace reboot by triggering a full reboot in the middle of the
+        // boot sequence.
+        assertThat(getDevice().setProperty("test.apex_userspace_reboot_simulate_shutdown_failed",
+                "1")).isTrue();
+        String error = mHostUtils.installStagedPackage(apexFile);
+        assertWithMessage("Failed to stage com.android.apex.cts.shim.v2.apex : %s", error).that(
+                error).isNull();
+        // After the userspace reboot started, we simulate it's failure by rebooting device during
+        // on userspace-reboot-requested action. Since boot attempt hasn't been marked yet, next
+        // boot will apply the update.
+        assertThat(getDevice().getIntProperty("test.apex_userspace_reboot_simulate_shutdown_failed",
+                0)).isEqualTo(1);
+        getDevice().rebootUserspace();
+        // Verify that hard reboot happened.
+        assertThat(getDevice().getIntProperty("sys.init.userspace_reboot.last_finished",
+                -1)).isEqualTo(-1);
+        Set<ApexInfo> activatedApexes = getDevice().getActiveApexes();
+        assertThat(activatedApexes).contains(new ApexInfo("com.android.apex.cts.shim", 2L));
+    }
+
+    /**
+     * Test to verify that if a hard reboot is triggered around the time of
+     * executing {@code /system/bin/vdc checkpoint markBootAttempt} of userspace reboot boot
+     * sequence, apex update will still be installed.
+     */
+    @Test
+    public void testUserspaceRebootFailedRemount_revertsUpdate() throws Exception {
+        assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
+        assumeTrue("Device doesn't support userspace reboot",
+                getDevice().getBooleanProperty("init.userspace_reboot.is_supported", false));
+        assumeTrue("Device doesn't support fs checkpointing", mHostUtils.isCheckpointSupported());
+
+        File apexFile = mHostUtils.getTestFile("com.android.apex.cts.shim.v2.apex");
+        // Simulate failure in userspace reboot by triggering a full reboot in the middle of the
+        // boot sequence.
+        assertThat(getDevice().setProperty("test.apex_userspace_reboot_simulate_remount_failed",
+                "1")).isTrue();
+        String error = mHostUtils.installStagedPackage(apexFile);
+        assertWithMessage("Failed to stage com.android.apex.cts.shim.v2.apex : %s", error).that(
+                error).isNull();
+        // After we reboot the device, apexd will apply the update
+        getDevice().rebootUserspace();
+        // Verify that hard reboot happened.
+        assertThat(getDevice().getIntProperty("sys.init.userspace_reboot.last_finished",
+                -1)).isEqualTo(-1);
+        Set<ApexInfo> activatedApexes = getDevice().getActiveApexes();
+        assertThat(activatedApexes).doesNotContain(new ApexInfo("com.android.apex.cts.shim", 1L));
+        assertThat(activatedApexes).contains(new ApexInfo("com.android.apex.cts.shim", 2L));
+    }
+
+    /**
      * Test to verify that boot cleanup logic in apexd is triggered when there is a crash looping
      * process, but there is nothing to revert.
      */
@@ -321,9 +406,13 @@
         assumeTrue("Fs checkpointing is enabled", mHostUtils.isCheckpointSupported());
 
         ITestDevice device = getDevice();
+        // Skip this test if there is already crashing process on device
+        final boolean hasCrashingProcess =
+                device.getBooleanProperty("sys.init.updatable_crashing", false);
+        final String crashingProcess =
+                device.getProperty("sys.init.updatable_crashing_process_name");
         assumeFalse(
-                "Device already has a crashing process: " + sCrashingProcess,
-                sAlreadyCrashingProcessExists);
+                "Device already has a crashing process: " + crashingProcess, hasCrashingProcess);
         final File apexFile = mHostUtils.getTestFile("com.android.apex.cts.shim.v2.apex");
 
         // To simulate an apex update that causes a boot loop, we install a
diff --git a/tests/src/com/android/tests/apex/SharedLibsApexTest.java b/tests/src/com/android/tests/apex/SharedLibsApexTest.java
index df49f62..fdeac2c 100644
--- a/tests/src/com/android/tests/apex/SharedLibsApexTest.java
+++ b/tests/src/com/android/tests/apex/SharedLibsApexTest.java
@@ -33,7 +33,6 @@
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 
-import java.time.Duration;
 
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class SharedLibsApexTest extends BaseHostJUnit4Test {
@@ -512,13 +511,12 @@
         assertThat(getDevice().doesFileExist("/data/apex/active/"
                 + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE))).isTrue();
         mPreparer.reboot();
-        mHostUtils.waitForFileDeleted("/data/apex/active/"
-                + getInstalledApexFileName(ApexName.BAR, ApexVersion.ONE), Duration.ofMinutes(3));
-        mHostUtils.waitForFileDeleted("/data/apex/active/"
-                + getInstalledApexFileName(ApexName.FOO, ApexVersion.ONE), Duration.ofMinutes(3));
-        mHostUtils.waitForFileDeleted("/data/apex/active/"
-                + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE),
-                Duration.ofMinutes(3));
+        assertThat(getDevice().doesFileExist("/data/apex/active/"
+                + getInstalledApexFileName(ApexName.BAR, ApexVersion.ONE))).isFalse();
+        assertThat(getDevice().doesFileExist("/data/apex/active/"
+                + getInstalledApexFileName(ApexName.FOO, ApexVersion.ONE))).isFalse();
+        assertThat(getDevice().doesFileExist("/data/apex/active/"
+                + getInstalledApexFileName(ApexName.SHAREDLIBS, ApexVersion.ONE))).isFalse();
 
         getDevice().disableAdbRoot();
         runAsResult = getDevice().executeShellCommand(
diff --git a/tests/src/com/android/tests/apex/host/ApexCompressionTests.java b/tests/src/com/android/tests/apex/host/ApexCompressionTests.java
index e37bc0d..a09ca60 100644
--- a/tests/src/com/android/tests/apex/host/ApexCompressionTests.java
+++ b/tests/src/com/android/tests/apex/host/ApexCompressionTests.java
@@ -91,7 +91,7 @@
      * For example, <code>runPhase("testApkOnlyEnableRollback");</code>
      */
     private void runPhase(String phase) throws Exception {
-        assertTrue(runDeviceTests("com.android.tests.apex.compression.app",
+        assertTrue(runDeviceTests("com.android.tests.apex.app",
                 "com.android.tests.apex.app.ApexCompressionTests",
                 phase));
     }
@@ -283,10 +283,10 @@
         runPhase("testUnusedDecompressedApexIsCleanedUp_HigherVersion");
         getDevice().reboot();
 
-        // Verify that the decompressed APEX has been cleaned up
-        String filePath = Paths.get(DECOMPRESSED_DIR_PATH,
-                COMPRESSED_APEX_PACKAGE_NAME + "@1" + DECOMPRESSED_APEX_SUFFIX).toString();
-        mHostUtils.waitForFileDeleted(filePath, Duration.ofSeconds(15));
+        // Verify that DECOMPRESSED_DIR_PATH does not contain the decompressed APEX
+        files = getFilesInDir(DECOMPRESSED_DIR_PATH);
+        assertThat(files).doesNotContain(
+                COMPRESSED_APEX_PACKAGE_NAME + "@1" + DECOMPRESSED_APEX_SUFFIX);
     }
 
     @Test
@@ -302,10 +302,10 @@
         runPhase("testUnusedDecompressedApexIsCleanedUp_SameVersion");
         getDevice().reboot();
 
-        // Verify that the decompressed APEX has been cleaned up
-        String filePath = Paths.get(DECOMPRESSED_DIR_PATH,
-                COMPRESSED_APEX_PACKAGE_NAME + "@1" + DECOMPRESSED_APEX_SUFFIX).toString();
-        mHostUtils.waitForFileDeleted(filePath, Duration.ofSeconds(15));
+        // Verify that DECOMPRESSED_DIR_PATH does not contain the decompressed APEX
+        files = getFilesInDir(DECOMPRESSED_DIR_PATH);
+        assertThat(files).doesNotContain(
+                COMPRESSED_APEX_PACKAGE_NAME + "@1" + DECOMPRESSED_APEX_SUFFIX);
     }
 
     @Test
@@ -378,9 +378,8 @@
                         "Can't find " + COMPRESSED_APEX_PACKAGE_NAME));
         assertThat(activeApex.sourceDir).startsWith("/system");
         // Ensure previous decompressed APEX has been cleaned up
-        String filePath = Paths.get(DECOMPRESSED_DIR_PATH,
-                COMPRESSED_APEX_PACKAGE_NAME + "@1" + DECOMPRESSED_APEX_SUFFIX).toString();
-        mHostUtils.waitForFileDeleted(filePath, Duration.ofSeconds(15));
+        assertThat(getFilesInDir(DECOMPRESSED_DIR_PATH))
+            .doesNotContain(COMPRESSED_APEX_PACKAGE_NAME + "@1" + DECOMPRESSED_APEX_SUFFIX);
     }
 
     @Test
@@ -432,9 +431,8 @@
                         "Can't find " + COMPRESSED_APEX_PACKAGE_NAME));
         assertThat(activeApex.sourceDir).startsWith("/system");
         // Ensure orphaned decompressed APEX has been cleaned up
-        String filePath = Paths.get(DECOMPRESSED_DIR_PATH,
-                COMPRESSED_APEX_PACKAGE_NAME + "@1" + DECOMPRESSED_APEX_SUFFIX).toString();
-        mHostUtils.waitForFileDeleted(filePath, Duration.ofSeconds(15));
+        assertThat(getFilesInDir(APEX_ACTIVE_DIR))
+            .doesNotContain(COMPRESSED_APEX_PACKAGE_NAME + "@1" + DECOMPRESSED_APEX_SUFFIX);
     }
 }
 
diff --git a/tests/src/com/android/tests/apex/host/ApkInApexTests.java b/tests/src/com/android/tests/apex/host/ApkInApexTests.java
deleted file mode 100644
index 8452e41..0000000
--- a/tests/src/com/android/tests/apex/host/ApkInApexTests.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2021 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.tests.apex.host;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-
-import android.cts.install.lib.host.InstallUtilsHost;
-
-import com.android.internal.util.test.SystemPreparer;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class ApkInApexTests extends BaseHostJUnit4Test {
-    private static final String PRODUCT_APEX = "com.android.apex.product.test.apex";
-    private static final String SYSTEM_APEX = "com.android.apex.system.test.apex";
-    private static final String SYSTEM_EXT_APEX = "com.android.apex.system_ext.test.apex";
-    private static final String VENDOR_APEX = "com.android.apex.vendor.test.apex";
-
-    private static final String PRODUCT_PRIVAPP_XML = "com.android.apex.product.app.test.xml";
-    private static final String SYSTEM_PRIVAPP_XML = "com.android.apex.system.app.test.xml";
-    private static final String SYSTEM_EXT_PRIVAPP_XML = "com.android.apex.system_ext.app.test.xml";
-    private static final String VENDOR_PRIVAPP_XML = "com.android.apex.vendor.app.test.xml";
-
-    private final InstallUtilsHost mHostUtils = new InstallUtilsHost(this);
-    private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-    private final SystemPreparer mPreparer = new SystemPreparer(mTemporaryFolder,
-            this::getDevice);
-
-    @Rule
-    public final RuleChain ruleChain = RuleChain.outerRule(mTemporaryFolder).around(mPreparer);
-
-    @Before
-    public void setUp() throws Exception {
-        assumeTrue("Updating APEX is not supported", mHostUtils.isApexUpdateSupported());
-        mPreparer.pushResourceFile(PRODUCT_APEX,
-                "/product/apex/" + PRODUCT_APEX);
-        mPreparer.pushResourceFile(PRODUCT_PRIVAPP_XML,
-                "/product/etc/permissions/" + PRODUCT_PRIVAPP_XML);
-        mPreparer.pushResourceFile(SYSTEM_APEX,
-                "/system/apex/" + SYSTEM_APEX);
-        mPreparer.pushResourceFile(SYSTEM_PRIVAPP_XML,
-                "/system/etc/permissions/" + SYSTEM_PRIVAPP_XML);
-        mPreparer.pushResourceFile(SYSTEM_EXT_APEX,
-                "/system_ext/apex/" + SYSTEM_EXT_APEX);
-        mPreparer.pushResourceFile(SYSTEM_EXT_PRIVAPP_XML,
-                "/system_ext/etc/permissions/" + SYSTEM_EXT_PRIVAPP_XML);
-        mPreparer.pushResourceFile(VENDOR_APEX,
-                "/vendor/apex/" + VENDOR_APEX);
-        mPreparer.pushResourceFile(VENDOR_PRIVAPP_XML,
-                "/vendor/etc/permissions/" + VENDOR_PRIVAPP_XML);
-        mPreparer.reboot();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        getDevice().disableAdbRoot();
-    }
-
-    /**
-     * Runs the given phase of a test by calling into the device.
-     * Throws an exception if the test phase fails.
-     * <p>
-     * For example, <code>runPhase("testApkOnlyEnableRollback");</code>
-     */
-    private void runPhase(String phase) throws Exception {
-        assertThat(runDeviceTests("com.android.tests.apex.apkinapex.app",
-                "com.android.tests.apex.app.ApkInApexTests",
-                phase)).isTrue();
-    }
-    @Test
-    public void testPrivPermissionIsGranted() throws Exception {
-        runPhase("testPrivPermissionIsGranted");
-    }
-
-    @Test
-    public void testJniCalls() throws Exception {
-        runPhase("testJniCalls");
-    }
-}
diff --git a/tests/src/com/android/tests/apex/host/MaxSdkTests.java b/tests/src/com/android/tests/apex/host/MaxSdkTests.java
deleted file mode 100644
index d6eadb1..0000000
--- a/tests/src/com/android/tests/apex/host/MaxSdkTests.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2022 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.tests.apex.host;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeTrue;
-
-import android.cts.install.lib.host.InstallUtilsHost;
-
-import com.android.internal.util.test.SystemPreparer;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.RuleChain;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class MaxSdkTests extends BaseHostJUnit4Test {
-
-    private static final String APEX = "com.android.apex.maxsdk.test.apex";
-
-    private final InstallUtilsHost mHostUtils = new InstallUtilsHost(this);
-    private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-    private final SystemPreparer mPreparer = new SystemPreparer(mTemporaryFolder,
-            this::getDevice);
-
-    @Rule
-    public final RuleChain ruleChain = RuleChain.outerRule(mTemporaryFolder).around(mPreparer);
-
-    @Before
-    public void setUp() throws Exception {
-        assumeTrue("Updating APEX is not supported", mHostUtils.isApexUpdateSupported());
-        mPreparer.pushResourceFile(APEX, "/product/apex/" + APEX);
-        mPreparer.reboot();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        getDevice().disableAdbRoot();
-    }
-
-    @Test
-    public void verifyMaxSdk() throws Exception {
-        assertThat(
-            runDeviceTests(
-                "androidx.test.runner.AndroidJUnitRunner",
-                "com.android.tests.apex.maxsdk.app",
-                (String) null /* class */,
-                (String) null /* method */
-            )
-        ).isTrue();
-    }
-}
diff --git a/tests/testdata/AndroidManifest.xml b/tests/testdata/AndroidManifest.xml
index e7c5c02..04bc559 100644
--- a/tests/testdata/AndroidManifest.xml
+++ b/tests/testdata/AndroidManifest.xml
@@ -1,26 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.apex.test">
-    <!-- APEX does not have classes.dex -->
-    <application android:hasCode="false">
-        <apex-system-service
-            android:name="com.android.apex.test.ApexSystemService"
-            android:path="/apex/com.android.apex.test/javalib/fake.jar"
-            android:minSdkVersion="30"/>
-
-        <!-- Always inactive system service, since maxSdkVersion is low -->
-        <apex-system-service
-            android:name="com.android.apex.test.OldApexSystemService"
-            android:path="/apex/com.android.apex.test/javalib/fake.jar"
-            android:minSdkVersion="1"
-            android:maxSdkVersion="1"
-        />
-
-        <!-- Always inactive system service, since minSdkVersion is high -->
-        <apex-system-service
-            android:name="com.android.apex.test.NewApexSystemService"
-            android:path="/apex/com.android.apex.test/javalib/fake.jar"
-            android:minSdkVersion="999999"
-        />
-    </application>
+  package="com.android.apex.test">
+  <!-- APEX does not have classes.dex -->
+  <application android:hasCode="false" />
 </manifest>
+
diff --git a/tests/testdata/apkinapex/com.android.apex.product.test/Android.bp b/tests/testdata/apkinapex/com.android.apex.product.test/Android.bp
deleted file mode 100644
index df7fc12..0000000
--- a/tests/testdata/apkinapex/com.android.apex.product.test/Android.bp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2021 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-apex_key {
-    name: "com.android.apex.product.test.key",
-    public_key: "com.android.apex.product.test.avbpubkey",
-    private_key: "com.android.apex.product.test.pem",
-}
-
-android_app_certificate {
-    name: "com.android.apex.product.test.certificate",
-    certificate: "com.android.apex.product.test",
-}
-
-apex {
-    name: "com.android.apex.product.test",
-    manifest: "manifest.json",
-    file_contexts: ":apex.test-file_contexts",  // Default, please edit, see go/android-apex-howto
-    key: "com.android.apex.product.test.key",
-    updatable: false,
-    apps: ["com.android.apex.product.app.test"],
-}
-
-android_app {
-    name: "com.android.apex.product.app.test",
-    manifest: "App_AndroidManifest.xml",
-    sdk_version: "31",
-    privileged: true,
-    apex_available: [
-        "com.android.apex.product.test",
-    ]
-}
-
-filegroup {
-    name: "com.android.apex.product.app.test.xml",
-    srcs: ["com.android.apex.product.app.test.xml"],
-}
diff --git a/tests/testdata/apkinapex/com.android.apex.product.test/App_AndroidManifest.xml b/tests/testdata/apkinapex/com.android.apex.product.test/App_AndroidManifest.xml
deleted file mode 100644
index d9aae58..0000000
--- a/tests/testdata/apkinapex/com.android.apex.product.test/App_AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2021 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.apex.product.app.test">
-    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
-</manifest>
diff --git a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.app.test.xml b/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.app.test.xml
deleted file mode 100644
index 839d058..0000000
--- a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.app.test.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-    <!--
-  ~ Copyright (C) 2021 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.
-  -->
-<permissions>
-    <privapp-permissions package="com.android.apex.product.app.test">
-        <permission name="android.permission.PACKAGE_USAGE_STATS" />
-    </privapp-permissions>
-</permissions>
\ No newline at end of file
diff --git a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.avbpubkey b/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.avbpubkey
deleted file mode 100644
index bef1df6..0000000
--- a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.pem b/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.pem
deleted file mode 100644
index e3d0e23..0000000
--- a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJJwIBAAKCAgEAr38x/rCRXvNcq8I9zjWh8HNcKJOeaFCP52OQKGiaZlRofQ1g
-VGqvFAxWZY81WlitPBQQ/LtGB26bUSsUn3D7Z4VxHKL9zlY3brhqEBTcLRy4kaFS
-LMInAdWbID9cjUfnWvXe5+ELUpqP822T9CsnrnzxgO60HpbqigENs1NtkcFG4Qi1
-vqG6UdRkufyz671+/N/1lttKNySL8OxFZSfPj66XqhEW5kKrLSj3Fa1hOQY3Ml9V
-arLjcxIO9Lx83ns/QiQV6wwgy62zThTyYgPPEeulY8CyurhC8TMLhnGzTY71KmK2
-XrSHSzVqm92NZSI8OCaoDes8JOns0ey4Z2g2Tn0TCcmi27Oe6+2mIMOuxrWP5coc
-KVZ+o/NmeyXoSbM6+NdVhaUBaGdxe2lrrfvsL3Pn7zKZSMadVx+Th+7epLmYUp78
-VWfb7Ub1JCvHDm03Cf29Hv6SOlrXz64p1UnAbWbeUrCcIhhgE/DvUxBgIc+2Epqb
-GGRIp5XYciHFpNoDnWHTU/sDvCdZbz7p0312OFmb3oslzQdT7wTi8lcmWxr16rAD
-ZA8V0IdUngGPUPM6Vi3fNv/78tD+Bo6I2ul5MWgEUO3Vy26fZTWgCGvLa0JkTK9s
-nQilgQPdvrH7ad4HJINK2npWc6gPE0EH4eGifa16ZQ9MC6pZyk7rYNkK/csCAwEA
-AQKCAf9MF9qVk/l0MhD8aDxkLN0KZPqQnXERydybd5AJ9VD9DZxAnIwoDhnbl33e
-izmW8twqMIktDAZRMqQljYhjmZloSXPB9uoVjUx7tXpHfsP4y3s7qbb3sTc4lGWu
-lcqLd6HYzsLXx7whFONVqS19sTiDb6lHPjjbCpSnQc2u832OtT8GU8B556Xh1TXX
-brqUfJWTD4hs4KhNQIts6wUr1xcoNYuNMdu7+yw9aIW54HNHRmqobK2clfQI8MuL
-Ui7SSJ4lD4BxadDOf4I/WNW/qece3g3YMrVMQJjF/FwC70nPVyz2M9bfOWdwNLkE
-3AtyzmVN83TqlBR/7O3CF+Hc9FKW/dLw4u35+2WBmN84WUOv8bx7xaGINcdAKI8Z
-TRe0e1wpmRn/GuO1NusVpTVnBenVCSjWGvDH8+Ggg+xBNshj8ce6IM951Tp94Zos
-ED0E2EPL4ubajk8uRI8uGaCz3424+SwIxEHX4KToKffR3weeRcWzJiz/U4KCyV6p
-qgGybNIiUQRX8jkiXDGDN0dQL8QNzaeIKGPny/JyfmNUqeoJNQIIcGZlQ4WG/srV
-BISYuBTghGO/D+XEOh/3tN8Ftx0QQjqa0EYfd+4GGSvZO764veoFAdvo8rJxXQf8
-PPXH9hxHZQUcnqblCLG2KVxkCB1Up7HyrUTJwUn4clKxAWzBAoIBAQDV+53JfHFJ
-i5EmLnAU6N0QsyyHGnMVkjRx4Eft1qnYwSHJ4HE8y+xRT1I4dpSlifjyQNrApq3j
-6jk8u6m5JYM9jdkaYyZrkx2GWn9TuJE5Q7VRfpVtduMsR6rGfkEpLdGEsoScQ69g
-M0SYQk3gqqz2w74tlPgCoU3c8wXgV66JSJP/6v367e3HSJJW8HzRoukScrBdJRL9
-SPDAdb3+OpM4pzMtkU7vtDU2ACyBESDC8brvmeIZ0ZnE6eyrrkA3VsxrW4mRg02g
-q8SIzUO8ar9L/lXlJj2uMAP4auZUbODmkJ3XHRGDJUpRjRsN/zABY/tfiZecALtR
-EsCgW8B+24UhAoIBAQDR9PuozxeXV2rwG9v+YFor9RtCviC11E9dD/wwtVulR+vn
-8o4qM5wihvLYpESfdP9FtTZt2X90xoleHZZmEa7MXkJgw5w0UUm7xlczXLarOVjv
-0r2ObKsvKaI7I/YkmCdaV5t7dQYDKLHOlf6jXv6HU0IoHyhy7zjAFyARwnZ5DMYu
-0g6W/o7Cez8iHQTgsCkQe28wfR8V6iR1PS1PIYS4sVWdH2/YE6yTeb4MXsoqG2lu
-FpkL4z9j9/n8mFjERX/N29UZuB2IpBPs8y3Xha0lXUn/mZcmUf4O986E49LzGbg/
-F9w/O4GztUuPHnvs6qVuK2AyN8qHOdU/LnF35jlrAoIBABaWdvN75WGEEBBduosa
-gatvnnWsfxV513tl13HtxQQSbwSmYo2uYQW8P8uiCNLom5TG79CCR7zVTrFwhdv7
-b70hqhc0/CtC3kz+ZI5r3ziSQyOVHyTs9dIIxqgpT6uPIJzHU2RDaNHY15bS+PGM
-UrHBu+OH5B4y9MssBCTIXK41MRpErga88uqkaH4w6JwgfEXsQV2zuitudat7QlEB
-0eSbEbXvrsty1GMc5ZXCPxkU90yvi8R58adtogQFYtX0naN/iCgKGjmpqBdgw5Oy
-GPtmn56OyNgITYL9lc63p43vGhpJAT48w3mUUZTKqUCcUz6kgZKAKUXHmvnSdaFu
-fsECggEBANA6HKDWCrqhC0DpEG0fWC7CX2/5Km3LC47rfJ0+MI8iXlfi2pYGK3Ke
-zhiICjrvCQE0cK/PhrXk9XXu+CtwnCC51zEqry+/8tWVJwScjdoQ/SCUrESlh701
-mFz5FHREprrVqjFt5TGa2YVeg3W5j8vcif9Kr44VrP3tsXOLnn39akwjLi8YdbNy
-EjId/6lrbL6Y/LRlU0AjwFa5/sa9ImkeDx/OftkY4g49LnwMQooyN4TkSpNcpJDb
-7gVTfq3hk5gxzw476KaMu+pDX5KhVBB7jhk+VYa+yK5FnH91h9BsEKwaWOgpd0Ao
-rLBbdmKIcNtrj3Mem/EzLUgFIqncHdMCggEAP4FNHcLLWWQFvTog4rUeDeEvVyiF
-sfz5KD8fXDIHwSQRg4877qa96aSuXUUSLIr3/QlZyI/kh9inrLbJTzq9FSf5PJB+
-A1fSKH67H696hZUy04qtQDFt7HVD8UZ/vBn79HO/nGWnnc3hWJTSnniuvBTwxM++
-4//Vnmm5SF4a7gUYczbuHiSG9kltCFSO7SfqaCStsZWdxfxvxD4JYLS5AvZ/eNwk
-oko2AgS29BWySJBV7CT29ch1YHccvm9UEaaJunN10qkufWQ8RFeUk/CGe14f+fR1
-blkU3+rHZppVvNMAsTNoXbcbqfptZb+4IPbPg1lLp9gwETvfMnb4cXVX8w==
------END RSA PRIVATE KEY-----
diff --git a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.pk8 b/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.pk8
deleted file mode 100644
index a16e635..0000000
--- a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.pk8
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.x509.pem b/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.x509.pem
deleted file mode 100644
index 44a6506..0000000
--- a/tests/testdata/apkinapex/com.android.apex.product.test/com.android.apex.product.test.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF3zCCA8cCFFS0AutXdKo2HIVPZD/RDZDd2LqMMA0GCSqGSIb3DQEBCwUAMIGq
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEmMCQGA1UEAwwdY29t
-LmFuZHJvaWQuYXBleC5wcm9kdWN0LnRlc3QwIBcNMjExMTA0MTc0NjI3WhgPNDc1
-OTEwMDExNzQ2MjdaMIGqMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5p
-YTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4G
-A1UECwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNv
-bTEmMCQGA1UEAwwdY29tLmFuZHJvaWQuYXBleC5wcm9kdWN0LnRlc3QwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC6Qyaym34nAtGBoH5JwJAxxieNK83Q
-jG4wf56qMX1Kq+NFc+rYqsMebq3Tijc/3CSdE5f/4FE3cXwBJzhUKKDuBjKOGgyY
-YMYrgbdB23LyWlgmuRfUX68MAOAQ9GJrzBhVWKYRn66j6HJ9mEkHxNq0QO1XcSkB
-3K0bNS7rp4rfzOZnGtnGSoDdAjwyaN4NhBxkWTvZ7+LiHQixkL6yxPTtQEEbGh06
-Ni6X9upoByhXVYlaGDhfYhMksSaEVgCQQrXuCbnu9SRwCYfGL6HHeOO2F2XPyIi4
-K4ND490/mlNpk1p225IARQA/PAQcZFgb+++X75/fd/KzI9lcRKR3Gj1DS4giHp5Z
-3PUgB7q/nFJl4UcqkbwkasDC9vgVp7vgjIYJB9jrw4hAfsubsjKkOYbl4WrPGBTa
-Me9K6Bqk5mWUFHKyqt8ztLiJhq62CzE3dK5zo+koixYMHRJoup+7fDNi8O8j5G7D
-JDmAnPMhru/Ey9UQOxSQT+lvl4PRB11qZtmY1BT695IyKs+LxukPPGqOh3qBYt2G
-B2QRwXJVbqrfyMG32t2KY42j053hI4sY5kv+Mmt4tK2xrrWJ6VUJuQKWXoF8+1px
-O2xVXkIjsRpx9+rx5N5Gh29yvFCLsYFikDYFolmVSA+rfQxgQ0I4qUcZWWhYXu9b
-gKoY2pOpwdjDXQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQBTdD9Aa179TBSBHJQK
-STQ1m8mX7RTdI854AkcdLrFR+NNukmaV5aep2dDRB6zj2uU8bjRvNLe/KgQROj24
-S4WSHcX2AyjeBHzH28vfbqZJee/a01VVv9id4h7sbN+P4k2kd8K0pMLuDLryu64q
-7qEej2E5eiROUVrgeMUrzmMV3ef4CJfi5Myw1+HEekR4LfaHAbUZJ7A9rmX0N+LX
-ysNj2wSL5Yj/3sn8XvOJU2K4v/1M6JphzJLDT6N+uOmmuzSTk9uh6Aq4WWUjShp9
-6k2NfNffbE+Ds/AgRmkxFMFARCLgdvu1PfjCua6sGnbH5xJvvkXpvipb8vnbmWjj
-EyJi7oPXZFtDyB5wG92q7YA/PCyXRuPG4QXkKSHqCN4An0t+/0VnusUGZyXE6SQc
-6EkLdn3Sm++sZS/Vix7Xn7okHwtN1UR2MOIRsYPNqofeQ4Qnt96vzm5pdHCHa9eu
-5lys3wplCmyyATiWcQqRKJ4jLDaYbErfIb5mK8TQEP5E/Hw/hZvtqk4+fKTt8me3
-SUnLN1LXGhio0m3Os6vv22KL5BIa2kdVUdZpOJh85jUPnJcxaGCt/owNN6gkbfbp
-VWal+dzAw40U3SWqsMETgNUtCj+rHRdoaidnV3dI9dGXWWTK9q2HE6W5aYZxtHrz
-Xrfar3a04h4eewoDgbxeCcz5Bg==
------END CERTIFICATE-----
diff --git a/tests/testdata/apkinapex/com.android.apex.product.test/manifest.json b/tests/testdata/apkinapex/com.android.apex.product.test/manifest.json
deleted file mode 100644
index 59a9184..0000000
--- a/tests/testdata/apkinapex/com.android.apex.product.test/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.apex.product.test",
-  "version": 1
-}
diff --git a/tests/testdata/apkinapex/com.android.apex.system.test/Android.bp b/tests/testdata/apkinapex/com.android.apex.system.test/Android.bp
deleted file mode 100644
index 7282270..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system.test/Android.bp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2021 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-apex_key {
-    name: "com.android.apex.system.test.key",
-    public_key: "com.android.apex.system.test.avbpubkey",
-    private_key: "com.android.apex.system.test.pem",
-}
-
-android_app_certificate {
-    name: "com.android.apex.system.test.certificate",
-    certificate: "com.android.apex.system.test",
-}
-
-apex {
-    name: "com.android.apex.system.test",
-    manifest: "manifest.json",
-    file_contexts: ":apex.test-file_contexts",  // Default, please edit, see go/android-apex-howto
-    key: "com.android.apex.system.test.key",
-    updatable: false,
-    apps: ["com.android.apex.system.app.test"],
-}
-
-android_app {
-    name: "com.android.apex.system.app.test",
-    manifest: "App_AndroidManifest.xml",
-    sdk_version: "31",
-    privileged: true,
-    apex_available: [
-        "com.android.apex.system.test",
-    ]
-}
-
-filegroup {
-    name: "com.android.apex.system.app.test.xml",
-    srcs: ["com.android.apex.system.app.test.xml"],
-}
diff --git a/tests/testdata/apkinapex/com.android.apex.system.test/App_AndroidManifest.xml b/tests/testdata/apkinapex/com.android.apex.system.test/App_AndroidManifest.xml
deleted file mode 100644
index b990458..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system.test/App_AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2021 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.apex.system.app.test">
-    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
-</manifest>
diff --git a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.app.test.xml b/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.app.test.xml
deleted file mode 100644
index 08f4843..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.app.test.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-    <!--
-  ~ Copyright (C) 2021 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.
-  -->
-<permissions>
-    <privapp-permissions package="com.android.apex.system.app.test">
-        <permission name="android.permission.PACKAGE_USAGE_STATS" />
-    </privapp-permissions>
-</permissions>
\ No newline at end of file
diff --git a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.avbpubkey b/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.avbpubkey
deleted file mode 100644
index ef0438e..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.pem b/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.pem
deleted file mode 100644
index 2a70c45..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEAtg292H3PefeFs4TuslvGRKy4je+e9x58GqGY/ADAwu5Hj/Id
-Lrn0Q29eeG66fmFCIQaid76eGs8dnPn9cz9GVltzuv0GX/KCn9+vz1/WGZ5KyMDQ
-8C9ZJ1+AtEPdO1QiLcQ2Sv33d84BBAaeypWfqCcADkMzYrU3zVuaLy/dwdX67Y8i
-NhQi50QhKCM26wtYpNB6XL70/awptR8dAA7Q9iFTKTJGBc3/W+lwZvkzyPMCbZs1
-gjywRN2B2nFmn6Cz1GRD43rMGhJGSCgUyjYXCfvmqX80Lxlw8aIsHAueMaoVlq9T
-6xlrfyWGIhqJfdK/dmu+JP7RJO1MjkY0F4BSowvPvCyjXQfX0d7+PFK2C2CARySe
-XNkCSjLzOh0LPRP7ytUKaaYb23AeynzZhSJK9Ux8k1sdDKQw9t8D1ba6Nn06SG1n
-q5jGusFMi2lYgKFsKs6W/kuwP7LnFXpMVMBy0DkIQFmCBbItSvb05DXR0cUAgSa5
-8hOaUFL3l3kLKu9MFZ8CsxBwbu+WqN7Zp3//tZEC9iasPbogaqjQcHUhIBU0VKlH
-V8cbg2PS4nuPb2xYFsNcsP70U2xschjqwhdzticNv5ChMI/yACEHxdRrEDc3dUYt
-anDTjLLgARYdi9wgPo8jZc9nNE1hoaG4Z45aNcWSnlVKSTJOZLH7laVQvykCAwEA
-AQKCAgEAls7hUgI+KYnqnqBi3yr5HhB6PVGfPJRrN+Bfi3nQNGoQq+RjWj6+YlJS
-Tq9jG6fTkOofEdS8wfaKUGwiESL8UDMntmE9s6N/o5I34DBCeixPROe87Qo770rE
-og+Jp0j1mzXrx8mEAyGKY9xcE/NIM5JDEI2Idp8pn5rfKXGcYKKyX7HvJB8gHrWo
-RciOCLz4bGcqxcOFzNGeJySj8FVVsl4+tmSn7s0LWQcSjqqmxDLR8xvcgotldVaM
-5/iCi38jGLEKL9mcU4iJ4eIZ/rw575JVLFlsUAviLLgrk/vnyrpbcdzBRoJjMwtR
-htS2yp0W77Em7RyNAer1PPJY2pL5YCNptr8YLGIetkydo7WOdnRV/W7m5tgn1+hR
-gGSmx0mSu0dY9ugqF6LTpFTs9z5iRfVmlRbrj9SmkLJUfCUbfYssVHYFmI3Z+ge3
-S0Qoc+fuA0FWjGtR+jKzrqdQAGKAG4RGxHsRRrjzYyA9Qd7C/JRcgd2cUAPYCrzE
-LEgr7ym+IZ+y3HSAYUxs6avnhg/aeHpPTDHpYvMoeMo0YT0vT3PwamDpb97H+B9k
-fR9HnbbkWlcLPqvBG3x4DlV2wP5Otksq0QqhBfra8KrgVFZQ0SXVBMz4s/x5V1gl
-CHYq3uwGcMpQbFFh8vjVDUdZIrnHAPNI24JkrCz8ns8EHGjz3ZUCggEBAN4/Gw7+
-1pESmTGk0IXFVe+JFRucnVdW4Fw+0zC0rota7FYv6f4309diEU+r2kN+JmSvtxrx
-H3Yu2BdsSrB3zixC0ucgGkiO3Iy6vwGjDYrbPBJ1Umqhxg9Vzu8zVxt6EF6DP8U4
-K4wHSM+PcAYPGdzo5L2YTj7/P5rP9eGSe+nmn74cI+YXPFRkkZVnnOsW1L9GzYNT
-IeVTQoPNNQ3e6K4QW8dJT/oMYAHB6TsE2a7qrMgevIbWu59bLFEFre6SpnkybZt5
-2yhio6o37Q8s2CTLDn6p03ggDrzayycB4v7cWcRq1jE4Lg8MMRpV1BouBum9d5mP
-43ymezcRUGnAJj8CggEBANGz8p6Vc8ZnxujLEWOm1LXyVbj+GXbDm78vwZs4oLSi
-JdEwlW08Dg/dGWhmJO3y0XtO3oQ2luPD+RRm5oCfrVV/s354bU28QZ56bH1YR8PX
-qgwVdZqzCMxmS/nDQA4icGoWILTuK2o5xoOSu0qjwTkJxRhxji0YuxKTNK5Hf9gP
-YcW8rhyPomgzgocav4JSyDqdE5Pg5G5Sc0ExEcIRNvCJalOreifaKimJ5nsUsoVf
-tuARinz+Esr2OH13BEhEVXu5xeex/q6pJww5AGHkMD29QVfPj7kRjsnR9bBlHgkg
-it5NrSlVDaI7SW94hYeB5xszUiXUsDKCX3RPH6ZZ0JcCggEBANqTyAH0goSFfSNF
-DEw0K3N9J8RTQK+wYtJ2e3BwkyW9U6jkUMbUk0VGTu5Df1NX01y9MGGP+bhbE+3d
-dIugGKaRRilH+nGYB7NkywxKF7yUJ72jo136IvfcFbxNiwMcBtNdVC+cMb/zPhnc
-4XkkCvSoHKeXDoWItj6E/zdNwQ7m4f6wYGIgQhZiHoiJMdxIRQ6mDON2tGR9gXJt
-NRuiOsdOkWUrZjvvRdEUrFR+TbVpWmsrR5F5yWdN3QUGh+yWUKHsBb6elvteH8b+
-X+jH2wA8sNHEJpYDOVtl990yTtUHVEYIKQaZUTs9a2GSPhtNX0EtNV5TFJH4jkA3
-iBWphDMCggEAHKaTTWtp5/+hw4iLFaxjf4BeiendnMZY7yQdNZHlEwjcVdpncAc2
-fKBeqk7aWNBGIqzB5hp3PyM1Ur5EW+p1CitqYKsfc/F2napoTC/VjkJW71O3P62a
-VCLd2n/8rnGyHixrx4yKzfaa0rsnb6kz6xEUpqRNIogwdvc5yV3nb6OaXiPLPge5
-zrbK7J6Q78NTq/5uAFRHoXMOYCfOH0+uy+paZpgVFoDOJeK7ZLGNOn+7Qp3i5/Tm
-qGg/i5TJNv5vF3poOaGuBDsEJL1c+gLtPGIxHUg0gLqPYa+X+8O0+NZDYuAF+pGu
-TS4AeIRk6gCrjKHUZWrLr/r0A7YTwuyefQKCAQAYHLBC8GJyZ4XKa710Z8E6pyPQ
-8O6gKDCn9dwOPU/MySmjCzy1WN907qfaUOAu8V8lwbrgleabx55qm5mgJvgeACJV
-SRs3R6xGBeglD9p8ffdLJpl+H6ToD7LprsidnoJ86JzdujnZ0n11I+LFJNSx9so/
-mnBtYII7GmDo5e+whi9mBKy9HfmzjIY0SsPx3d3UGLhyYsd3GlIJVlwpMYMNzzKO
-vPG/zlSr6nVuwErc4lISP+v8ThuCNX2iCJ8T304utIm8f9xnWXGVgl2WYWqpKWlV
-YbMWY9X+U46jr9ZdwUeGdQFYIwuIHJ2OEXUPfm12zW5ZyNvvIcaN4u75XlKT
------END RSA PRIVATE KEY-----
diff --git a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.pk8 b/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.pk8
deleted file mode 100644
index 025f2cd..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.pk8
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.x509.pem b/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.x509.pem
deleted file mode 100644
index 3c7bb6f..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system.test/com.android.apex.system.test.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF3TCCA8UCFDZWDufIf2NnqQxJ6twoAcosGjeiMA0GCSqGSIb3DQEBCwUAMIGp
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTElMCMGA1UEAwwcY29t
-LmFuZHJvaWQuYXBleC5zeXN0ZW0udGVzdDAgFw0yMTExMDQxNzQ2MDZaGA80NzU5
-MTAwMTE3NDYwNlowgakxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
-MSUwIwYDVQQDDBxjb20uYW5kcm9pZC5hcGV4LnN5c3RlbS50ZXN0MIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAugO3YGqR0dJFmL2H7QDOiSHYPGOvMZD0
-udb0YM0wEcvq8MKxakhJuprrQPITIrA/19EbsPnVW2dVgg5Ss0O1pXMpsGL7CppS
-pLJOkNWHnPtAe8BkUGLJmUrqyYLygyM2iJ8J32Q6oyFV/Wxfk5tNTLL9bl3SrM/V
-0nrLkEmt0yvTh8kxdc/41oYPbUSaDbfk/zkiK1hkJaraqPaCir+Pt/dogwjyFyGy
-8+DkTDZFaG749ONASGJUfYptkHyVPGvbCY0MkVvUB+b7Z2n55LHJoQL+Xypr4364
-ShOHGvSsHcfM3UkaH8lRh59zd0xRcGARA71vclNBBrzNTINsd8jvh/UGdt1Ncedr
-gFC+mDnkdphMF3LeAtim1hnZ96h1pDNvTzLbygoSoquBrHRbQLnhjrzCRII3xLxQ
-GSdPLXUOA/8S7hf154H9RIwdiRyZ9hTYcjVPPXeKkqhR0Pb0cnlAncgd74dHKyIj
-QGlGTiih3jP9aYqQBCZQoNhiuQJaG3n2XgddPr5FnmFsssmSNGCbIRlhkbh9dCWx
-gQmA8fbuzzDTp2Wlcpe4dcEhIpHK96bBn439n/1LK8Ffn8K77+MDqz0Yic/Nuolg
-EyUu8kephLXoCJI85IhclOr9hrCQnlA3jMQmF0XXxh3pKXejbI3Y1sMHjmOBiyYt
-rIdmfWDiO5ECAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAnYLicSFfR+sa+mXNzgn3
-jdUtilK5L97f1OcvSzC0e0Zc87iZGP1A/6CxjVousa9s+z4Emi80bTUmSDH2K7pr
-BRyUU4U9kUCEtnGxi9OUDdX9hYloWkJx4Ub83cjzCRZYKNo4mKSBs4Q/MuiJ+/Op
-LbHCDYu6H49lHzfDe+ELhiBXrWSbmDVK8NFizN/eJhAyX/DCqkmdZ+AjUqSfZfUs
-WcozlWBF8hIQ1dKUQOQSCUzqbHXZwC8y03DuLtWIhZ6SXOdD1uSvvdaWP6IjzuzF
-WRiFlO3Rrxf80RKnQWe2JE1Nautb5RCNdfNUJTowFBvdLFc+LQeHOTZ3SILn64wu
-zPWVLUx4n/oNPNJAfLxTtXH1nzhVkgYIdrvm/2lOWfLCvVDLncGULm8+w3MWY9oX
-Fq8CMhKx9Uj+vleQX5yV4TenW92/51ATXCSN3w8Wk1OBH+pzWzFFjRIyYOPa1oqv
-Xs1/HJSK3FZcjKY+W5qSSXU7RptAZh8/1HA9oP12nYsHm3Aa9G1VDrFw34rMMz13
-QN17B72y0hoPs1Fm9vI0qDy+lAgnq6HNIrgrEUDtlXYaDZcCaPgBTFXDoBj4/L7b
-lg/O8MyJ9Tx4b94qfhesgYOwgO/95hY2L3XBI77MbLvJA5VQ6lHfuTsKoPDf4z2/
-XFK/sUlIc3Nig/PVVEo4mxE=
------END CERTIFICATE-----
diff --git a/tests/testdata/apkinapex/com.android.apex.system.test/manifest.json b/tests/testdata/apkinapex/com.android.apex.system.test/manifest.json
deleted file mode 100644
index 35c429f..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system.test/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.apex.system.test",
-  "version": 1
-}
diff --git a/tests/testdata/apkinapex/com.android.apex.system_ext.test/Android.bp b/tests/testdata/apkinapex/com.android.apex.system_ext.test/Android.bp
deleted file mode 100644
index ebab455..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system_ext.test/Android.bp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2021 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-apex_key {
-    name: "com.android.apex.system_ext.test.key",
-    public_key: "com.android.apex.system_ext.test.avbpubkey",
-    private_key: "com.android.apex.system_ext.test.pem",
-}
-
-android_app_certificate {
-    name: "com.android.apex.system_ext.test.certificate",
-    certificate: "com.android.apex.system_ext.test",
-}
-
-apex {
-    name: "com.android.apex.system_ext.test",
-    manifest: "manifest.json",
-    file_contexts: ":apex.test-file_contexts",  // Default, please edit, see go/android-apex-howto
-    key: "com.android.apex.system_ext.test.key",
-    updatable: false,
-    apps: ["com.android.apex.system_ext.app.test"],
-}
-
-android_app {
-    name: "com.android.apex.system_ext.app.test",
-    manifest: "App_AndroidManifest.xml",
-    sdk_version: "31",
-    privileged: true,
-    apex_available: [
-        "com.android.apex.system_ext.test",
-    ]
-}
-
-filegroup {
-    name: "com.android.apex.system_ext.app.test.xml",
-    srcs: ["com.android.apex.system_ext.app.test.xml"],
-}
diff --git a/tests/testdata/apkinapex/com.android.apex.system_ext.test/App_AndroidManifest.xml b/tests/testdata/apkinapex/com.android.apex.system_ext.test/App_AndroidManifest.xml
deleted file mode 100644
index 08e6e8d..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system_ext.test/App_AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2021 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.apex.system_ext.app.test">
-    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
-</manifest>
diff --git a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.app.test.xml b/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.app.test.xml
deleted file mode 100644
index c7da76f..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.app.test.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-    <!--
-  ~ Copyright (C) 2021 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.
-  -->
-<permissions>
-    <privapp-permissions package="com.android.apex.system_ext.app.test">
-        <permission name="android.permission.PACKAGE_USAGE_STATS" />
-    </privapp-permissions>
-</permissions>
\ No newline at end of file
diff --git a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.avbpubkey b/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.avbpubkey
deleted file mode 100644
index 0d978b8..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.pem b/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.pem
deleted file mode 100644
index fe56f0b..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKAIBAAKCAgEA8rwV0tBSXu3BFaM7+7KS/KpOK6q9yGzqZz4Pg8PUxelI1dBQ
-/Jja6s5ow8NugACWP4pOBXmDj0sGoUE5DrC+03mQKjTibZqrH8AUY6+cE+YQPVdy
-/wEVO1VmO9MXiF+VY+3IBUodtKPMj+jlsRPlIALH20QQY4wygcK9CLQAZe3op5zA
-EOv+BUz1GMxDUqxbmnzRbJimpbXkR2R98/QIBlbqCey0c48fdRykq9zkXWa3GrjZ
-ikW/SYYcv9qQzkJlN8/WUEE69mAH2ny1HQ4KUsfXAvyeNvjt5xQk3DGvzWuNYCRj
-1ptKfGkOVlr4kr8PMpGgY+KpL2gJlN/xc1hRCP3XPfGX5IU0NOa5WjyKfA8CIHzO
-oxa8haifcwkcQvbMy69QD+XZ4Pge8KW7D8+UnBeGU1TqAWz4l2ZPq67/Fb/uLvOo
-0WVdT/cmeSF/NfQnzAwiV/WBzzZWSjNMHhQEEongSg5Gd22QPBd1slgVdUfYNhCi
-iGHVHEGqruYbhXdmAo9UCPLWUrCCjgaANDV6u6/2nge/UCyAx1vPYgHXxMTpTErY
-yqsDacgRhYIFFYaeuDt5qcQs/c1p62GJdAwJwN3ziZvuou4jEopHeaQsWkzL99ai
-NYmWsG8USpshP47OA7vt5dbX++UXwp4QXeZqGz0OShRTNL4CUolq5I++JMMCAwEA
-AQKCAgEAlH0AsKzlptK0ymLH/+o2xr/7//R8Eo6mOjAZ15ZFpChYeQvtbwim6vsH
-1bHI+B7jysz1e53hIBhaXu0CVX1DzyRPT7J4TWpPgqXDE1RLG1Ui3BOR8nMcJObS
-GojAnZkzTyUXtjynvWhybBqh4Fh2UsXAst6JVAxgnUae0yMiFziZmWdnizKCe4Wf
-beMO0BVGGFSA3HjpgPerRQ0xi7nd6triYt3dac/FA6RZDBWd0ZFTM9KeqVqPcQ/M
-qISxDqxJNQI8bW3p/uuyAjNFrBd5szgyzM3yj1hqWHDXN6hhjj1cB9NbC96Fi2PM
-9IDEDSk5x8qUHmZ67tgq/FqeXtxI/RET027E2bxDUc3hJ1pJtx6hh2B6USUnFOnj
-tvSkpUun1KhdhZwnOXg5AEg6rcZNbyl4nhSlsfT/rVNSj3LpPCeoHULozuPbP0PS
-CIJyt5y2Fo5T/VRPokWsqxi768wJHotNuGbqiMbyPKKvL7XZOU08ERapaMxNHxeC
-km4Pjo5s41XxDxGewZxnwy0bAzVhiH8ii0piD8OdxZKF3Mo6+mTd3b+YvgpePDA5
-37NgJDgqV9pvYVQGLDe5qr7ddhgJPqWhFQ0kLQJvbm4gNrBsSDHfYBMm1dn51DZA
-pZk2H99K3n3oaecL3mBOAcvkFjKLvleXzDbQgoSqzdbG9xW0lqECggEBAP7XZ6CE
-VhjDGqSZYneJT+4YvTL3/sfy9OX80yURnG6+q/8VsodUbeXy/Bqfmf5eqtzOA1tP
-6SxOOvnbJkflD3l5e0uKQpsh+yfwSDsKFjRMW2j8D+x9PikCZAX3IrwldugIt3mM
-aKBD2QqIk/VeHSkbLAi61U4njpHCPxkdOAar+heGNR7sVWbaPU2jrxpsZme+O6Lx
-IEGiMBh7KlvIx0lEmaW6CUm8gqtiVx/iSazMCr1O0Cva+i1jfUBrlgMnofFQzZr0
-WbyLTbujxpkjxgFezF8Xwu/J+MHMmwO0c9iKYs4j0FycWN3eZ11iI2SrqAZbdip3
-sVFa6PGitEwr4HMCggEBAPPWlxPbZ9kl0uSaf0kenPoQkAtOtdU4Iso0VEwaEMB7
-mCYqoY4tWFuR2FMTMoibRtvyvGewXQhQ5gLt98a9KQAHXSVrypXvEZ1aHROe2kq6
-+XtR4jKh1+3Iq/br1dDrZPNgYhrSdw3zgpumKsx6rMT00hOjbfMX6EsAHu5biGkJ
-Jo6zJhzwfQPrWknUYF+6HaxTNqDR+q1s0DTu73XWQfSVIevzeHhOvzm2VvsH28se
-uOEqkGvZRq36ZZ7aCOJqP5L3Wa9tZvphmGSFhDU93lVNFupGi2WTLuSkmhRqfxcL
-RziE6Ul82vhhuy0G3wFdSHRS6AykEpRHt286piX1JnECggEAY52sAlD4nsFVXtYe
-aX+hYP8Gpi/OxjYwiN5lYu4ZaijabuH6YXAdbW+oIHgW6Bn1TE6zfTQlf44s+5Iw
-ypW9kMxt579p/d4woRIKChoNR/A5Iza0usrSS5GFq9dJGqbCbj1KCxdZppwe8UEm
-JRne6DyY3+i4jM5lqpB1vclwJxt+rUdm6GmVkJjqsbi0L+4DsbXo9e6vnzhY+Jjc
-m/hF/lv0e5XXH52yrm/Igswf5I31/L4cHaiBdtCXG2FyyFTrtrrRRCsUEOGbRyfj
-7+TN96co2FsfdkBLHuZuCeq2BgVCTjYtsqXjDwdq/FPqZeW7zpBeBoe3JogU2q+x
-Lr1QBQKCAQBG7wEqJKSUNf2gxRUMN1yhHlpY/7/D1D3CpvBy5w5CgHHlgHdY/fX7
-RXUxzZ7gwJMffwCyBUs7FRWkeoefB/46ZOoC7dWUQmTUapeU0pxcKwJSjqKH6i7/
-nGXyQe8EhMXsSvifJuS9aT5weyluLK2/6hyG2/8rPaQ01UcqPfRz4daWoqUOvCMS
-FdBBNAgJMQJa1CZLKGqNMt9q1qtQk1DCjvO8SSqdjQLyDgpFoqac80YDMrequB1o
-lTQkvvbgrtnprg0oDGJtqiCD9ZddSa85D2EALB93IBb/KqcsE0L/eCdy2K9o0mp8
-4SlrUtli8zkVpdydeMly214QfHZDCorxAoIBAAgxpIbntMADhpGPzN7d/XcgcHaz
-+kOxatnVYePxosAQOVPN5GrJzUUZ5rRTpqEoe+j9OJFIR6+p6yHdz9SeACdI2707
-hKoAAfB35CjfH23jGKu9ocMnSu2B7Ssp8NVN9c7iVcvXj6+MihFTxHBwRJq5pRg1
-RXdyZkidmB5vy9kxvVwRWbRQm9env8Eb8yyTCNlDd61FfJBO6gB9llEncj+fILOG
-5fyVq/V/wnm156IXe7C/y0HTwjWWpOT5bFW4cvSy/hp/+fR8Kv19WDRK3GngcnJW
-sGe7PECIYPbKJvuOMt3aP+poeOm9rV5i7f5K+vRdxrDHz7xK4Is/ur1OG6Y=
------END RSA PRIVATE KEY-----
diff --git a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.pk8 b/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.pk8
deleted file mode 100644
index e9b17b5..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.pk8
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.x509.pem b/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.x509.pem
deleted file mode 100644
index 516effd..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system_ext.test/com.android.apex.system_ext.test.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF5TCCA80CFFkJTEXUYaClwWvv+oDTGGGDUJE9MA0GCSqGSIb3DQEBCwUAMIGt
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEpMCcGA1UEAwwgY29t
-LmFuZHJvaWQuYXBleC5zeXN0ZW1fZXh0LnRlc3QwIBcNMjExMTA0MTc0NjE0WhgP
-NDc1OTEwMDExNzQ2MTRaMIGtMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZv
-cm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQ
-MA4GA1UECwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lk
-LmNvbTEpMCcGA1UEAwwgY29tLmFuZHJvaWQuYXBleC5zeXN0ZW1fZXh0LnRlc3Qw
-ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDU2EVWNLhekkYf1mT8RnED
-9pf7v/1RN65CAFDmNydLsd8S4ef0xiIJEgaOH70T3AinLIq5o9EYJenGkvhLWdB1
-YEMcaNlmIz/HjxFOHwIyzNoUyHOP049ZggW8sCWzrB2srO0Dv9EjIzuA3c8s2cFx
-mKKzarW45CDACoFQ5KXn73LzKc3CI/qBnnMGlzWpCY2VW4rJjUCiSmAg2F6+bC7M
-xu0YPIabo6OL4dFHFI37Zhh8RkbrMyT+C6sA7wJym2X1dIt6NQ7/kDKRwjWAMz9D
-Myt1mg7CiK+rNgWsYJZcPopxvuis4RXppgl2JZhi+31NWlaxgPEOo+u1jUWCJRLG
-z1qjL1icGWB6f3oG2hMpV+QuNCAJyQj7Ixn6zLXjQaV2YngK0PJwKYW+jKc3/w8T
-mF4MsMmPGYg7734VsK/K+IAl5KkcYRMvAbBMJ+cm/V89yKLuWngf73F7AOQn6jyZ
-Puo3y9k7vdIVO1TGKltCx66R+omMwjt8OmqMDPQcaXo1fb1CZbvOEPrGIFn1pdN9
-H7IjszxldJzBSBD4Pee1XyykI4tkEIG4ZvwF7NNSPUPkTIgcu47YASe2Z+aWhAwp
-fyz+0D2NOtEBvjg+jDq1jgr1716DP7h91iwOSDt+/VCmuUzaN2IEeIM7m24/X+iq
-79oUCfEu2sEuNz9LHJONKQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQB0rOMaVXta
-sa8o1ijJkZYu3xR17aZcq5FjiziqF22pkVOKNMLm8/IlSFEYgXFzHdtplslHD6Sm
-0ohITbEOJVarAchphl0WiW9YU9tvEbV06feOBE8UgOkAm6eLW4ahfxKUGtikL3UK
-Cudjjz56uzXoxsJuylwP3e+rhKH4otL7bzEHI7Unmz2eNd5ro67avzIuxCUVKcQL
-ne43YWLvlO0DjUBUXQcYIuhNTaGkgzRwezKZHQCG61LDdTVVrxzh+H3H1A6yYD9h
-BsuTJn3ybuXhS+NGo5PEbSPMN9m6nWPMOhzov0fMp3q78riBERw8K1Ut1v2UWmto
-w6xDV7WBhUWT3U8fvYKni+L0dAEDImCvIMgi7+2ucQUhhIyMkShABlYOrWmgYa9W
-/gljh9yrtMc/r/LEsgf/CUSiMDW/fQZrP9LaApwH5LF0ObXiklrhhC3UT+utlRZi
-9RMvlW7OZQCefEwRAVk/KM69tLZaafKuGFgEtvqRvBqK/NQwsgJ0F6zQpUQ2x0qP
-YIv8qbSJYLybAcm3cYwJ7KZQesdydVgY/AVRzFOoT9T7h4Lx3B/UG054LYW4UoTT
-XQjRK9jufPsLvDIbkf02TX1N5RSp2U5EvViaujUmFLlqQfJZcIo9dGKltVThuBuh
-gFuk3Y7JQVZ0GDt6gpeSLReRjGD1OBAbZA==
------END CERTIFICATE-----
diff --git a/tests/testdata/apkinapex/com.android.apex.system_ext.test/manifest.json b/tests/testdata/apkinapex/com.android.apex.system_ext.test/manifest.json
deleted file mode 100644
index 2249493..0000000
--- a/tests/testdata/apkinapex/com.android.apex.system_ext.test/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.apex.system_ext.test",
-  "version": 1
-}
diff --git a/tests/testdata/apkinapex/com.android.apex.vendor.test/Android.bp b/tests/testdata/apkinapex/com.android.apex.vendor.test/Android.bp
deleted file mode 100644
index 8300d6f..0000000
--- a/tests/testdata/apkinapex/com.android.apex.vendor.test/Android.bp
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (C) 2021 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-apex_key {
-    name: "com.android.apex.vendor.test.key",
-    public_key: "com.android.apex.vendor.test.avbpubkey",
-    private_key: "com.android.apex.vendor.test.pem",
-}
-
-android_app_certificate {
-    name: "com.android.apex.vendor.test.certificate",
-    certificate: "com.android.apex.vendor.test",
-}
-
-apex {
-    name: "com.android.apex.vendor.test",
-    manifest: "manifest.json",
-    file_contexts: ":apex.test-file_contexts",  // Default, please edit, see go/android-apex-howto
-    key: "com.android.apex.vendor.test.key",
-    updatable: false,
-    apps: ["com.android.apex.vendor.app.test"],
-}
-
-android_app {
-    name: "com.android.apex.vendor.app.test",
-    manifest: "App_AndroidManifest.xml",
-    sdk_version: "31",
-    privileged: true,
-    apex_available: [
-        "com.android.apex.vendor.test",
-    ]
-}
-
-filegroup {
-    name: "com.android.apex.vendor.app.test.xml",
-    srcs: ["com.android.apex.vendor.app.test.xml"],
-}
diff --git a/tests/testdata/apkinapex/com.android.apex.vendor.test/App_AndroidManifest.xml b/tests/testdata/apkinapex/com.android.apex.vendor.test/App_AndroidManifest.xml
deleted file mode 100644
index 1b3df04..0000000
--- a/tests/testdata/apkinapex/com.android.apex.vendor.test/App_AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2021 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.apex.vendor.app.test">
-    <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
-</manifest>
diff --git a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.app.test.xml b/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.app.test.xml
deleted file mode 100644
index 6c68a2b..0000000
--- a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.app.test.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-    <!--
-  ~ Copyright (C) 2021 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.
-  -->
-<permissions>
-    <privapp-permissions package="com.android.apex.vendor.app.test">
-        <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />
-    </privapp-permissions>
-</permissions>
\ No newline at end of file
diff --git a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.avbpubkey b/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.avbpubkey
deleted file mode 100644
index 3ad68fc..0000000
--- a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.pem b/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.pem
deleted file mode 100644
index 686044f..0000000
--- a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKQIBAAKCAgEAsZO4GlL/2dGKXPIPaTweLINGRQQoDsZwS1FCR5kYaGj2Wgn5
-cM+HpmMuNAkb7IZYStfG/6mrIydweMHEaW9pr8vMzHC+4EJOCzsDZKTCM+C3UXUQ
-8u8/RT+c48LVPpxpp9YPBS1WXlVJFh5ejQL5dZlSJMiMRsStp4KODi/uy0zo3ULW
-AKStB5cShBUTb8SzzqP0OaPR7q6D0gCxgW+BjmbyoKnM/ba4dXZ/Sqf5LYwHSRub
-nNfUA3lGuFQ8KD4IA+Qt9N4MoPkxpa3/Pjp5rltYUv8WHQYhm6jtFZXQLHgJh/EC
-1kJzFnM2lz/Z70DoGf7XOJ/chv4tT7ft1c4lFhPBjLCPoIsdzbSByYVU3ff0dowh
-Yh3Ec7TtIUL+OsLN8M/LC+uBNUyz1WN/q6+OEY+71NgDgAo9pebzfaH5F9+HqGBH
-7pCqT2tviip6xHcpLdT4Wsu839i44b1l9NI7YIMEXodsdhocicGAjIRlV/bvdMAk
-M5MaIAyt7jqIaJAuUoQ41+aByUFMYqzeDrjnWkXjqQuo0hMl5vUQW+YATLvUxwEh
-IqQx8kmm0IEvgn/wgUDiN2hBEjc/AuFZXPMzk1SKcR6Ia9HwMRuWh2BkF5xmb+v1
-iZeB/cew5OZM2Al3cJ5eBbAXsLDvM3P4NlUh8Mb6jPM5Cyru0KQIXUGWq9cCAwEA
-AQKCAgBTGYrFHuRGPY3fcxONLqn8MK6Yq5pHV8vDI1K+CMHoUn4+on5NsYCMd8tu
-ZHjh1fjJhXLFv9OrjtBOYncU1COENf4wCe75KW42STaMSaHr/xQqlXsKBLX6JQu5
-djquoym6dizvQkkxuf2K0Ulz+dldlBNhzUv/7hhJ1Im/z+SS1PoAWT+ma2nhrGvo
-zagb3NQ8NnOa6bPbW2Wqx9JJfTIGvtx6HRwl+vUVWw+0kyjDjMz4BGhtHH9F5OIY
-bqr8NhMwJv7uoV8NkbAPFX7l0x2QX4TUyjTB/lWJ76KLQGF7/eyP5lRqigwrjF0W
-qLXHBfvX9m8nO4BK1/XCYZN2Q5MMmmGVc/9RXhYed2Zv+UaMBODlbu4SZqNiQcqU
-9VlYQiwK84pLbCV2pVDLzQSdFFHBJuRcOuTstZF6trQU4EKX+VDilCc4oGxHcShH
-NCZXiLsuxLqxNKPRzh1Hg1wMdid8jUO0EB7mZlpfnoFNuA35ll/FffRtV8iSKVi+
-MCR0+AK2cWN34K+FQolVZh3fIs2OL8QvGc/KRYQjo/yelsyrzEhkdCW+DQ/X2Bq1
-VzhOc/mPZvI1eHLyc6gigOIDUylxbink9r34Scbz8W5WEEcuOxMQGu5ZgXg0caSU
-Ce3+ChTt2tZFvRMeHiKk1RApWONYP+VVgjQfkbdyljgup6/YgQKCAQEA6ii7+Q5T
-/xP/z6TVLpHlaQq61WGY/Fd4mp5NphP3PrZ+tGnyzpDV4w1Sf8EAIICZVszklTep
-No3XMQef/p5MvgWBdGbdXtPH9bfLoHbG12HpmRnbKZT18YhlW0RpJWNTCiEgNdAh
-C/fAz7NJ+SFFistRn6hslY4CqljOBSBYuPf/FwECG50viRCCwF5GXooDz3iObbaH
-IFwm28FaaflPYfckqm8S1rcH1Yr4CDDG/dw8NhA/0lpCig3zGcu1x4cuyQsK0ZuK
-zJ0Jahxzj8HYlLpvyc2b0LMp54lMs83HvW0gJMhyEG0Er+eDQDbje2lFImhxqq3K
-1k+kaGNdERFBlwKCAQEAwiPqDdVpHbe/LG7G2V/FPHXOC7YERdim9AmScm8Hcf4L
-UJUNI7WgfT72oiHmlzexsh0UrXa1oEIUzw5zol/GWUTRWH6Wvo5ExT5oESbtJWtV
-sml/HPWmys7pCq5hgwZj7Rhal5ooWpsZJ1mEEycCkXVdZqJMD0CfjQd5zMtK19L/
-tjkvZfr/FmTCgSswqYYJ6oh2T5ef+Gb+U3yCh09/KJlbN1Ebgc4uCourUJ9kwN//
-Fq0rUwU6rrbbgDsKBD5DaOu+vfSGVsqY63IeT4RzajD6ZiG3APtedPn/GODo4YfI
-ES0y1cqDyyJbmxfsHOKsIiH1bKPpKYRIsPuhAfKvwQKCAQBmlgIEUyqpjfF83xIm
-nPSM2I6R/Xgw1YGY+9G4+PZRG1LXZ7NgnEOYfbWvErcjhjOnu4xJc2FG7U1hxZ1q
-x5+HgJH+lTJW4SGxnRww6Nikc9kLojBKP2CguMju+0G1h5ZR0cFy0gQoYhqu5DV8
-V/9Hl1vjPr6Tpuu0BcP8qvcz0jKHuYFa57pzqjAeZy8dLAoPUxnTJyx8GONNU6Bw
-3TDSEpyVrqPqPbXI8GFJ9VS400vtw6CyX6jXItVmb8Dr8WWl3piWzDY6/nGpc12N
-lbd1MVjYaKPjAxtQvO5Ft9nSO4ThmI+gcqKjDiKKd4GiB7SqJmfmBs3epnW45g9X
-8t9xAoIBAQDBryDn0jy/qDyy8IW0Aib9ba414s6afE3787zGK9zqrf/N0hY8xQwr
-R/C4ykeKH8dJIlgpwt/q1WJ7PDjDCvgQwWZ1+j0cOUWE3wDl88bt6QqjJzrowm83
-sHuw605fcLWqqfxfeS2/TzMmHdl1Xhri0YtwRITLRram9YlfdoXhkiEJRD30aReq
-2LVwNo2i4xXrhV87gtLW+LHMytBSfE4pS+5D3sgplXA7lyJAGfVjs1WD4xnxBquH
-+Og+IyiYGSIZf/BZBKYt2ov7gWuZ+1NF4z09PW+dLCsNWwhUYrYToupHsKchwZwA
-wfNQZOpr2vzORMDcNR7+C3qWD0SPc/ZBAoIBAQDRnG1oseVuZvk2GkiaSYmF4DJi
-NUcHSuDmNV6wnczgn/csOXxE4ZCtnf6wT4G4yd+kHVEAEOEKF5EfdnrTGuBRpAdG
-LyzYoFc7HLo2aY+JyDo0FBNLj3w3dD0YI24xXst+d7fl3rCKF7ZdDNI2tqI89vgb
-71mz4LXOECIEDaww/8vmq24X+Mqh2QugpoHgRS+LNiZZozqRIZf2BY+gjEmCynWd
-G3gbuj6xm0nEmXxuyR8CAH/ZeFn63HQBHJLTVqId1GbD+u2JEkZEQYOyfCwfk/sG
-v92TIn3qDRUF12HYdSOOZNURXJBfiFta1gsmNePDr8KRnKAY35p0HlSY43Vo
------END RSA PRIVATE KEY-----
diff --git a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.pk8 b/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.pk8
deleted file mode 100644
index 318020b..0000000
--- a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.pk8
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.x509.pem b/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.x509.pem
deleted file mode 100644
index 048a4f8..0000000
--- a/tests/testdata/apkinapex/com.android.apex.vendor.test/com.android.apex.vendor.test.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF3TCCA8UCFF9h0n91axJ62gD/xssXeSrUmAvdMA0GCSqGSIb3DQEBCwUAMIGp
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTElMCMGA1UEAwwcY29t
-LmFuZHJvaWQuYXBleC52ZW5kb3IudGVzdDAgFw0yMTExMDQxNzQ2MjFaGA80NzU5
-MTAwMTE3NDYyMVowgakxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
-MSUwIwYDVQQDDBxjb20uYW5kcm9pZC5hcGV4LnZlbmRvci50ZXN0MIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAt7zWvwuFCqqc8C7aMlkJRHENiAm9E52I
-1xAtlmUWAgQkkubPp91oY2yWTE0CH5WELis7iaBeZVIhuoDv1IvYHmIU/Jjd2g55
-vFmAzgJQV6b8h6sifJWqj0dkxgEMUalqYzbpQTcqSalypTEzxBPRWk97qPcZUoUJ
-MLLeCJtXdCdfCFXdUV+k3caMfID3xxXWGwms4DYJFAAbHVdDtfJkQ7nnad4PFK0+
-96p8piYqxG9b76/r4XNmpBQn4Fg/2/BTG1LRBTinJkk4OeCdnaAzlBIgcH3FXT77
-Zg+vqTsbNCaC7CrOAFU7KT50+kCSm65+CUPv+se+yiBBf6b8h93nV4UubyCFNQtr
-9+6I3IQxZJ2ArjJzriBYmuDV6hAEDY6c95ItCveEd2tQlWhnYTpOGw7OAC9+A2m+
-CzSGBFdVbloIEWt2MZPChdquxMd1v6t6mJdcFCWa1Ls6khiHlMYpmywyPSVyC5RA
-q5eG24vXGP0M5PhECgHaWVevrKVYcUyzWj/CrVxpkMFmejE081OvI3jlDyZSDBHH
-5xwlySWbiR2xNyCri5W+A/4qF+MT4UsqREnajHteHXoD7E3BoLWAlkFHNiclVQmT
-onNjtWEf6+9G49TJJ7xYWFvXC83xGhsaM0C3dZ0z/O1r0deXScSH20CP2A+/J2YW
-ROgQ7NVbxP0CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAngWUpDnD9n2Az9V7kl21
-PhKvsQaqad8NDQTAXYFU9JgNmVWk+TBHu1cKD7y06s676Hj+8yxZmi4twNYzVSf+
-pBBNazhGDsCPLUfSMgj8pCoXYxnFok+DrixY7p1fce5s7YZeu4IPUmsidMLO3YhJ
-lit1PmH5sEsFeC5E8OKP++uvOnOjbw5RWZs1t+FFW1RbDXMGTn3fpah+mN/N5Ie0
-t8FA+nghgGwiAx5/mf/B32RHjK+7BeHZZJWj87j3uBXOAkgH7vmcuy1zvlH8huTD
-Xh+rYUZBj0Ik+8iqF9Zj5tQLTuSVtaEiSH4kIvnLeFUYmQZwnnLPhzHB6dcL+KRY
-A4Zztxq6m3/5lA+6i4nHF/woY0cBnCaIirDRqjSzx9zlgk7ko4ZJAbTbEV735AbU
-253C73isnx465/sdiq9bk9/vIi6mj0ZAlPXtGict6XAnmjIqQKMAtJQJ0xB187BT
-PHqbUthMA10N4jey2QkyKVERZP7KyZFiPF99bM6gYemnnpedEawMF3dPSIK0egki
-78/VQVTBC5Uelx8QrIuYzT6EZHuGHIuNlm42WuH8pEOl0oh/jsXWTSiRFE/kQ9Gk
-/7bFLsiRPGSxccKy7QpMYvs08hKgQz3S/n22Wr3zmopVdqKnZ5kLoqpfsE4Ve0ab
-H379betgKB8EGRPjQLdNeI8=
------END CERTIFICATE-----
diff --git a/tests/testdata/apkinapex/com.android.apex.vendor.test/manifest.json b/tests/testdata/apkinapex/com.android.apex.vendor.test/manifest.json
deleted file mode 100644
index 7cbe6f9..0000000
--- a/tests/testdata/apkinapex/com.android.apex.vendor.test/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.apex.vendor.test",
-  "version": 1
-}
diff --git a/tests/testdata/maxsdk/app/AndroidManifest_normalApp.xml b/tests/testdata/maxsdk/app/AndroidManifest_normalApp.xml
deleted file mode 100644
index 6b3ca97..0000000
--- a/tests/testdata/maxsdk/app/AndroidManifest_normalApp.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2022 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.
- -->
-<!-- Manifest for a regular app, not part of the apex -->
-<manifest
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.apex.maxsdk.regular.app.test">
-        <!-- because this app will be installed as a regular app (not as an apk-in-apex),
-             maxSdkVersion shouldn't prevent the app from being installed -->
-        <uses-sdk android:maxSdkVersion="31"/>
-</manifest>
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/Android.bp b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/Android.bp
deleted file mode 100644
index a54da03..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/Android.bp
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2022 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-apex_key {
-    name: "com.android.apex.maxsdk.test.key",
-    public_key: "com.android.apex.maxsdk.test.avbpubkey",
-    private_key: "com.android.apex.maxsdk.test.pem",
-}
-
-android_app_certificate {
-    name: "com.android.apex.maxsdk.test.certificate",
-    certificate: "com.android.apex.maxsdk.test",
-}
-
-apex_test {
-    name: "com.android.apex.maxsdk.test",
-    manifest: "manifest.json",
-    file_contexts: ":apex.test-file_contexts",  // Default, please edit, see go/android-apex-howto
-    key: "com.android.apex.maxsdk.test.key",
-    certificate: ":com.android.apex.maxsdk.test.certificate",
-    updatable: false,
-    installable: false,
-    apps: [
-        "com.android.apex.maxsdk.app.available.test",
-        "com.android.apex.maxsdk.app.unavailable.test",
-        "com.android.apex.maxsdk.app.available.target10k.test",
-    ],
-}
-
-android_app {
-    name: "com.android.apex.maxsdk.app.available.test",
-    manifest: "AndroidManifest.xml",
-    sdk_version: "31",
-    apex_available: [
-        "com.android.apex.maxsdk.test",
-    ]
-}
-
-android_app {
-    name: "com.android.apex.maxsdk.app.unavailable.test",
-    manifest: "AndroidManifest_withMaxSdk.xml",
-    sdk_version: "31",
-    apex_available: [
-        "com.android.apex.maxsdk.test",
-    ]
-}
-
-android_app {
-    name: "com.android.apex.maxsdk.app.available.target10k.test",
-    manifest: "AndroidManifest_withMaxSdk10k.xml",
-    sdk_version: "31",
-    apex_available: [
-        "com.android.apex.maxsdk.test",
-    ]
-}
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest.xml b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest.xml
deleted file mode 100644
index c7dade9..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2022 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.
- -->
-
-<manifest
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.apex.maxsdk.app.available.test">
-</manifest>
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest_withMaxSdk.xml b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest_withMaxSdk.xml
deleted file mode 100644
index 4439eaf..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest_withMaxSdk.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2022 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.
- -->
-
-<manifest
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.apex.maxsdk.app.unavailable.test">
-        <uses-sdk android:maxSdkVersion="31"/>
-</manifest>
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest_withMaxSdk10k.xml b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest_withMaxSdk10k.xml
deleted file mode 100644
index d22bf66..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/AndroidManifest_withMaxSdk10k.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2022 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.
- -->
-
-<manifest
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.apex.maxsdk.app.available.target10k.test">
-        <uses-sdk android:maxSdkVersion="10000"/>
-</manifest>
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.avbpubkey b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.avbpubkey
deleted file mode 100644
index f4af547..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.pem b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.pem
deleted file mode 100644
index dde5fd2..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJJwIBAAKCAgEAvFhH2F48NE3Cdh98JB/31VsCPF68d+2jHYAG6eqM0lDOOM9p
-nDJZ6EReAQZ7Es8HSnYUCSIfNGmZUvwWMjYLyrXpaBf4kmwiErkHXAh3dn4243Bo
-OtTBiLvvh2KFZjdRhJrnUQRfsFaIaFlr10eLYZv4lMSEPS+wpxJRsAWbHSpqzVis
-mFYPAB/HztmuRsHeWadQp0mwEZD3KYLI3g/q9DKEg+CqordzhOSh4kADgACZpRjf
-mIvqCgTo5c53sl1GoiIWly/LP+Z3QJtJFtNs2cKxAR9XadSXqgCaKReQnsD/dYf5
-PJWT0v21uma+N2bFu0kQEPPZOeJCPyOsbWLwZzQQToL3SRkUjteYfY36RUNHjM5L
-Pqa/wau0UvpCZPHVmg4fh26QPcVCnZpAhwjNnnsXArDjRUuXNPpPNnRaGGic/t5k
-oeHw2LVSw/UKLqzLx2+FtBiu2wiOzuByrlTqiu4fj7hd9B1cPR85VkFyq+kISGHT
-xEp6SDKRuoxGt43QHztocfsiVyZlvN6goOZkHl/Qpgxl8FZDESwA0VvH/5I+yVO7
-JYSKHJLDn01oX2O64G6uymjA/5nwDmjn+Hs5vemduNzjl+Qie0y3ezC+S2TEwRMs
-KIviz4KrcHKntwGk57y99FdBZumgYwBJCVjSt2D+S7Ba9OmhoTUcjKId9x8CAwEA
-AQKCAgBKn3enxH56Aq0ffA4Fihz5jZtvK+HkamUMVSNoHqQ42Ac8/wDLADAbFKti
-IJ02sIwk9m+txrUyYPx8oqBwuHUnlbeqpIS6DtnZLTI7Rqd+bTd2GZ1SYeVkNYIL
-0/8ippxHu9AWi3MWPNLC9VsC6rfQrqlo2AvE6lZFe76dzTrN7XZvccjAeqhq1iym
-Sh0Ar+NXBjGwdkOqUhN7gPPw98GRi0pxrdwtqB2+848oQ1CfsJ0vipFcsWLDIXrd
-QlaudsJ7jqIAuNEAumFZWa01vAMOrFLRLQfHSJHmq2JpEYsdOz575KndVS5ClH8i
-IX8QGEoTkDkrXlIc2waAWbQBiwfQTW/O5PRLd2xp3tFwR5W2or3xxaa6QzzLEd9c
-8cpaRwMwXpRxpXmNvKBoqDYdrKRgLS/vM7bfCFCk4i4poUpeyHHkfziWRs9ahaiT
-dMlrfm73ocqWCmhcHnb/tJAGzdJCkk8TEGd1aMC/CSz/mqr7ik57pxCt0L09lHRR
-IReNDkR189KoIdtnh6kphDZmAuswlkh0C1i4611j5pKH9KYghRHBJ/lnI1fXqnyw
-GcbI1iCSL9Ca+Xvb58HLxnXRqVuKslshXnoZt7SFLvgHvlMRIZwuGti9lb+OTl1c
-UT7So14sVj5z5w7ilV5OmmBNYwGuG25mEAhwSONenwDNLehYUQKCAQEA7yakhv0G
-GOSoRXSgsjfRTxXI1X/WyMIYIKOXjJtkvBTIZGWNyhmfr4jPs3bqi403e0Gc+G/h
-TioEyyOrZ5pcxQ56lqx/S6ybFxH1QEa1OJcBkB4gtw+JLgoGLEr+eO18c+9RJPTY
-Z9nuNJcGsRvJkaSshqgrabbQz27dcL52DWqOop7wc3aUHlK2t9igutyMtfx4cTN3
-wszgXPQiMmTgcKBsUwg3T9CUoEH+EtUnklUO9hs3ePjlpC4JXfjpvNJm8HWOA6vw
-Vy6DExoC870SiLapl3qwKXOEItUmH3r9OxK6gUAH+WhkSWpUzCXSfJ9hhLLdwVEt
-z+gYC1nJqN32XQKCAQEAyZ1K5WiKdj2SgB/jeT+AvxZ9hel6ByHSfbtOKLSBzbTB
-8zAkui5MoK2B3Mho3B1lCCdNbmiY8OiholA9ixo9AFLcNj0FMXiocNntWrPQxGAX
-yzsX5ZdycIDRqPo+NKuEs41H1CjeWB9ieketwqyEjKW+YxBqvk49OM1t50C8pJCC
-ODOwN6PINPcwsIheQHVVqpt3N0If4hgpjYqyhZaTBcEVqlQELyydmDGqyZn0oSI4
-tgy20pxBH7iPQ5aAn7XgWaixT1+Z93zN704tG97RxEglBPZXXyFtWXOiTRIRZqd5
-osmFYkG8kKAFUuOMAnuINabtJo80+fFNq4Lzur+TqwKCAQBOi/2bzHz1LhzKeyzQ
-fB7F/9yvqsZLt9we1DxRVTR3xcevmd9BErts9t1pD1SnsyEW3Y0F2BFDD+/1HGkO
-pRd1LXU8Cbnhi/aAVEid7NtWk9pSkGKkXXjr4yT15UfBRhcLKP4YykZNjbl8EmKD
-RyIkMNbtf0yK8x2QE9StVBEIBQiGBvfopHivoPEcXw0jco7QsvSIEaRzGcFTJmgY
-7yL8OuR5PQiVsWcvX51oaBQQLtm0IWpN1Enwa6Jt9/QlLWHb9nBHanCM4dzxKCjy
-DxaISp5W/1fetW8f1awoyMdlYJhbHUHBO/U8W60wQ/fnMJ3h7LGC7fvC/nLvP3VJ
-fmWNAoIBAAb0o0HY4nYD18sNzpY/R5zQFNKK5Ifcdduam66x04yaQNq3/Xxi3ofo
-lINecqetZ+/pEzXM7AHbtL/ZztW+uP4K3cgNQOGdDQqfqh2n+Hrd6dQ8HK3yFKOm
-/hS7VWwRwslDBYhfRJR7uLUJRghiVUxY54GZbmVUY65TAAirZhazWZrAxcKVpvGU
-2ZwtiDrnEWaKaImCgYEWXlCgyVnsgPQA3lN7BI3wFxvKEt9TrWnluVkmhSQs+d4z
-StYFGjjoWG4fcMaRQMmWB7DK3KmKfWgtKQHL0eXZTGF6qM3J4snM21hvZWenZu8C
-ZkyexxTK2D8pnCLpa+V3mrthEDGQLHMCggEAY3BzWH5dQloMYgExtvfifbNXFKzG
-RdQnmAvLT6Nlv7lKUKTD4O0Hrv0o9a/O+y2qTO7HMsnNNpR/Lq9F93Akt16ILC+9
-zqkM7BjVqAzCc48V/yMGtWPZwcR2he1n8HgbdZkU/93UJNQxtTAgEuEnazh4ZBQg
-jWyy6jyOMMXNsEdHUUmcyN7IdFHAAvzamxmIUImshavxXnGjAXZiLz2Ewg2xVKrl
-ZF4HHPfq/cn/4Ic6sQ8tmppuov5p56DpO6Dl5DFvbtciY+GbaO+Aq2tqT6mg0bjY
-H52Jf53T8TaJQg33+yb9Qu0i2X/2QPODm88O1PO8R2UDXIec6PIYymV0tA==
------END RSA PRIVATE KEY-----
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.pk8 b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.pk8
deleted file mode 100644
index 12d7966..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.pk8
+++ /dev/null
Binary files differ
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.x509.pem b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.x509.pem
deleted file mode 100644
index b5dae43..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/com.android.apex.maxsdk.test.x509.pem
+++ /dev/null
@@ -1,34 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIF3TCCA8UCFGPwQqpTEKgDNzlnGNkzYp1wSgKQMA0GCSqGSIb3DQEBCwUAMIGp
-MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
-bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
-MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTElMCMGA1UEAwwcY29t
-LmFuZHJvaWQuYXBleC5tYXhzZGsudGVzdDAgFw0yMjAyMjQxOTA1MzNaGA80NzYw
-MDEyMTE5MDUzM1owgakxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
-MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYD
-VQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJvaWQuY29t
-MSUwIwYDVQQDDBxjb20uYW5kcm9pZC5hcGV4Lm1heHNkay50ZXN0MIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApI7HwWXk3RelSA+I49f8vZSnpw6q9LYn
-NePbT884eBxK7xIkDDXsnxSMvzdh8uT3gt3j87QMzZsv8jpyAa5m5Y0bwCDRTFCw
-IFei4eHRLUZeuybR7l7TI6153OArIiUeDO0gZtxzRXN4t2fjU/qo7bTWjrgfOob9
-KW/TCQQFSAocqZK0x1l+FSs3+o6duMe/LwhT7r+LVLxNxXb7TUbb9TP/NrkN8gt9
-BKLrDUHawpA/S22ELspW/IqGAV689dw01CFSJDquqLnJRMHJ3B9367oBQZdHimue
-gQPOoWyMUxTNAeL3WCZ8Uado8/cuyR7oMaSnfdHaWeUMxsxqh40vu2yfSC3kdjYK
-TkQWOI/byK03jTbTERNjSseSmXZqKnwdIvy9F58XzfeqBPZQwzlGc/Eg/oHvvYGF
-VotRyWBO0nAN9/Bt0kgtg/37y93zemsZ6B6QI5dT4RdInC8b9jQkfw0bmN2VE2P0
-7zLXIBck6K59ZfaMi/4+duzrluxxb7X8FaFMmX3QTpbSnPDeuZij0B0KsLI4ul5u
-ItSMDsNQZiv4729OdiX/AGLD1qQLr0se4AL0jXouMgAKscX3MWxhYMM/QcoHR3Vl
-vLZzO+GaGqirElqPxSu/Cd6xrqN027xk9UHe2t5Hp3HXhEhMNY6AlvzRhHZeRqiv
-Ip4NdGNF7BECAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAljWrfEAnT/xLDBlIldFD
-mo/oY9CIXolc1SWZwf/yGUnaXm27hMUO4YYSSRVR3okV2HmDDM4RGzMNeZM6gCWR
-+Eeq8nRU2lv7OXxXYJDKE3q++4/KvvfDohZvJ5I8m9SH6jgmP63D9noaBMnp51XL
-92Zr/sQQngNfSjMTTdIqg+XviEsB+knyhDCK3qrVv9dWMIh2U2jQ6s0nAdv4KLJm
-AkfR0LmjdcZLHwCXpPW3Fr+13xK1wFqH9qrGw3NR2XpxHc6tZu6ZOWdrwQr9Zw+5
-+Dt6MC65VFLXC6qCvG+7NdspFVOBT3uxWIl3ow91TPgVeJgiYGQY/+nI8PtIHlCD
-3CF6eyB7necmc2ee2SQNPFGT0fGajprqYRzzHz3mz/9BsrRp7kMGEakG0dPZsWd7
-sLX5ihklLLdkTg3Fp0g0S0DsE44u6TXiJv4363xsGGTu4b438LZX+kQJ2fWpPFBX
-43CUWCk1zTCpwWwSHZxns1cnlwFnNxl7hnZ9WH7dhrRZXpkylsEyeATNTxBBfdlD
-ngCEbXdNyxs06iFrn+BC44vsJKyZCmnBC03AJMyfaxNutqnFwBwToA9F7d61UzqA
-LeKlnRdt3JI5WdREqHCsbpyv7tgykKlf3vYqjqHKca3gcsCOJFCzAxaz5voA3J+p
-LWUarJ6nfdZVIFm4M6DNUKU=
------END CERTIFICATE-----
diff --git a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/manifest.json b/tests/testdata/maxsdk/com.android.apex.maxsdk.test/manifest.json
deleted file mode 100644
index 25e51f0..0000000
--- a/tests/testdata/maxsdk/com.android.apex.maxsdk.test/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.apex.maxsdk.test",
-  "version": 1
-}
diff --git a/tests/testdata/sharedlibs/build/shared_libs_repack.py b/tests/testdata/sharedlibs/build/shared_libs_repack.py
index 022d932..31b9a6b 100644
--- a/tests/testdata/sharedlibs/build/shared_libs_repack.py
+++ b/tests/testdata/sharedlibs/build/shared_libs_repack.py
@@ -212,7 +212,7 @@
 
 def _get_host_tools_path(tool_name=None):
   # This script is located at e.g.
-  # out/host/linux-x86/bin/shared_libs_repack/shared_libs_repack.py.
+  # out/soong/host/linux-x86/bin/shared_libs_repack/shared_libs_repack.py.
   # Find the host tools dir by going up two directories.
   dirname = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
   if tool_name:
diff --git a/tools/.clang-format b/tools/.clang-format
deleted file mode 100644
index f6cb8ad..0000000
--- a/tools/.clang-format
+++ /dev/null
@@ -1 +0,0 @@
-BasedOnStyle: Google
diff --git a/tools/Android.bp b/tools/Android.bp
index bdcc289..6b4427b 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -91,46 +91,3 @@
         unit_test: true,
     },
 }
-
-cc_binary_host {
-    name: "host_apex_verifier",
-    srcs: ["host_apex_verifier.cc"],
-    defaults: [
-        "libapex-deps",
-    ],
-    shared_libs: [
-        "libhidl-gen-utils",
-        "libprocessgroup",
-    ],
-    static_libs: [
-        "libapex",
-        "libinit_host",
-    ],
-}
-
-sh_test_host {
-    name: "host-apex-verifier",
-    src: "host-apex-verifier.sh",
-    test_suites: ["device-tests"],
-    test_config: "host-apex-verifier.xml",
-    test_options: {
-        unit_test: false,
-    },
-    data_bins: [
-        "deapexer",
-        "debugfs_static",
-        "host_apex_verifier",
-    ],
-    data_libs: [
-        "libbase",
-        "libc++",
-        "libcgrouprc",
-        "libcrypto",
-        "libcutils",
-        "liblog",
-        "libprocessgroup",
-        "libprotobuf-cpp-full",
-        "libz",
-        "libziparchive",
-    ],
-}
diff --git a/tools/apex_compression_test.py b/tools/apex_compression_test.py
index 2a30007..018fc56 100644
--- a/tools/apex_compression_test.py
+++ b/tools/apex_compression_test.py
@@ -74,7 +74,7 @@
   host_build_top = os.environ.get('ANDROID_BUILD_TOP')
   if host_build_top:
     host_command_dir = os.path.join(host_build_top,
-                                    'out/host/linux-x86/bin')
+                                    'out/soong/host/linux-x86/bin')
     args[0] = os.path.join(host_command_dir, args[0])
   return run_and_check_output(args, verbose, **kwargs)
 
@@ -152,7 +152,7 @@
     host_build_top = os.environ.get('ANDROID_BUILD_TOP')
     if host_build_top:
       os.environ['APEX_COMPRESSION_TOOL_PATH'] = (
-          os.path.join(host_build_top, 'out/host/linux-x86/bin')
+          os.path.join(host_build_top, 'out/soong/host/linux-x86/bin')
           + ':' + os.path.join(host_build_top, 'prebuilts/sdk/tools/linux/bin'))
     else:
       os.environ['APEX_COMPRESSION_TOOL_PATH'] = os.path.dirname(
diff --git a/tools/apex_compression_tool.py b/tools/apex_compression_tool.py
index a5545f5..3c0f16d 100644
--- a/tools/apex_compression_tool.py
+++ b/tools/apex_compression_tool.py
@@ -89,13 +89,10 @@
   cmd.extend(['-o', args.output])
 
   # We want to put the input apex inside the compressed APEX with name
-  # "original_apex". Originally this was done by creating a hard link
-  # in order to put the renamed file inside the zip, but it causes some issue
-  # when running this tool with Bazel in a sandbox which restricts the function
-  # of creating cross-device links. So instead of creating hard links, we make a
-  # copy of the original_apex here.
+  # "original_apex". So we create a hard link and put the renamed file inside
+  # the zip
   original_apex = os.path.join(work_dir, 'original_apex')
-  shutil.copy2(args.input, original_apex)
+  os.link(args.input, original_apex)
   cmd.extend(['-C', work_dir])
   cmd.extend(['-f', original_apex])
 
@@ -118,24 +115,24 @@
 
   # Set digest of original_apex to apex_manifest.pb
   apex_manifest_path = os.path.join(extract_dir, 'apex_manifest.pb')
-  assert AddOriginalApexDigestToManifest(apex_manifest_path, image_path, args.verbose)
+  assert AddOriginalApexDigestToManifest(apex_manifest_path, image_path)
 
   # Don't forget to compress
   cmd.extend(['-L', '9'])
 
-  RunCommand(cmd, verbose=args.verbose)
+  RunCommand(cmd, verbose=True)
 
   return True
 
 
-def AddOriginalApexDigestToManifest(capex_manifest_path, apex_image_path, verbose=False):
+def AddOriginalApexDigestToManifest(capex_manifest_path, apex_image_path):
   # Retrieve the root digest of the image
   avbtool_cmd = [
         'avbtool',
         'print_partition_digests', '--image',
         apex_image_path]
   # avbtool_cmd output has format "<name>: <value>"
-  root_digest = RunCommand(avbtool_cmd, verbose=verbose)[0].decode().split(': ')[1].strip()
+  root_digest = RunCommand(avbtool_cmd, True)[0].decode().split(': ')[1].strip()
   # Update the manifest proto file
   with open(capex_manifest_path, 'rb') as f:
     pb = apex_manifest_pb2.ApexManifest()
@@ -157,8 +154,6 @@
   # Handle sub-command "compress"
   parser_compress = subparsers.add_parser('compress',
                                           help='compresses an APEX')
-  parser_compress.add_argument('-v', '--verbose', action='store_true',
-                               help='verbose execution')
   parser_compress.add_argument('--input', type=str, required=True,
                                help='path to input APEX file that will be '
                                     'compressed')
diff --git a/tools/create_apex_skeleton.sh b/tools/create_apex_skeleton.sh
old mode 100755
new mode 100644
index 60a83df..818e119
--- a/tools/create_apex_skeleton.sh
+++ b/tools/create_apex_skeleton.sh
@@ -1,28 +1,15 @@
 #!/bin/sh
 
-# Creates an apex stub in a subdirectory named after the input package name.
+# Creates an apex stub in a subdirectory named after the package name. Edit the APEX_NAME variable
+# before running.
 
-# Exit early if any subcommands fail.
-set -e
+APEX_NAME=com.android.yourpackagenamehere
 
-APEX_NAME=$1
-if [ -z ${APEX_NAME} ]
-then
-   echo "Missing apex package name"
-   echo "Usage $0 apex_package_name [existing_apex_key_name]"
-   exit -1
-fi
-
-# Optional. If provided, uses existing key files and module name.
-# Otherwise, generates new key files using the APEX_NAME.
-APEX_KEY=$2
-
-YEAR=$(date +%Y)
-mkdir -p ${APEX_NAME}
+mkdir ${APEX_NAME}
 cd ${APEX_NAME}
 
 cat > Android.bp <<EOF
-// Copyright (C) ${YEAR} The Android Open Source Project
+// Copyright (C) 2020 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.
@@ -35,19 +22,27 @@
 // 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 {
-    default_applicable_licenses: ["Android-Apache-2.0"],
+apex_key {
+    name: "${APEX_NAME}.key",
+    public_key: "${APEX_NAME}.avbpubkey",
+    private_key: "${APEX_NAME}.pem",
 }
 
+android_app_certificate {
+    name: "${APEX_NAME}.certificate",
+    certificate: "${APEX_NAME}",
+}
+
+apex {
+    name: "${APEX_NAME}",
+    manifest: "manifest.json",
+    file_contexts: ":apex.test-file_contexts",  // Default, please edit, see go/android-apex-howto
+    key: "${APEX_NAME}.key",
+}
 EOF
 
-if [ -z ${APEX_KEY} ]
-then
-APEX_KEY=${APEX_NAME}
-
-openssl genrsa -out ${APEX_KEY}.pem 4096
-avbtool extract_public_key --key ${APEX_KEY}.pem --output ${APEX_KEY}.avbpubkey
+openssl genrsa -out ${APEX_NAME}.pem 4096
+avbtool extract_public_key --key ${APEX_NAME}.pem --output ${APEX_NAME}.avbpubkey
 
 cat > csr.conf <<EOF
 [req]
@@ -62,41 +57,14 @@
 O="Android"
 OU="Android"
 emailAddress="android@android.com"
-CN="${APEX_KEY}"
+CN="${APEX_NAME}"
 EOF
 
-openssl req -x509 -config csr.conf -newkey rsa:4096 -nodes -days 999999 -keyout key.pem -out ${APEX_KEY}.x509.pem
+openssl req -x509 -config csr.conf -newkey rsa:4096 -nodes -days 999999 -keyout key.pem -out ${APEX_NAME}.x509.pem
 rm csr.conf
-openssl pkcs8 -topk8 -inform PEM -outform DER -in key.pem -out ${APEX_KEY}.pk8 -nocrypt
+openssl pkcs8 -topk8 -inform PEM -outform DER -in key.pem -out ${APEX_NAME}.pk8 -nocrypt
 rm key.pem
 
-cat >> Android.bp <<EOF
-apex_key {
-    name: "${APEX_KEY}.key",
-    public_key: "${APEX_KEY}.avbpubkey",
-    private_key: "${APEX_KEY}.pem",
-}
-
-android_app_certificate {
-    name: "${APEX_KEY}.certificate",
-    certificate: "${APEX_KEY}",
-}
-
-EOF
-
-fi
-
-cat >> Android.bp <<EOF
-apex {
-    name: "${APEX_NAME}",
-    manifest: "manifest.json",
-    file_contexts: ":apex.test-file_contexts",  // Default, please edit, see go/android-apex-howto
-    key: "${APEX_KEY}.key",
-    certificate: ":${APEX_KEY}.certificate",
-    updatable: false,
-}
-EOF
-
 cat > manifest.json << EOF
 {
   "name": "${APEX_NAME}",
diff --git a/tools/host-apex-verifier.sh b/tools/host-apex-verifier.sh
deleted file mode 100644
index e732758..0000000
--- a/tools/host-apex-verifier.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-set -x
-
-APEX_UPDATABLE="`adb shell getprop ro.apex.updatable`"
-if [[ $APEX_UPDATABLE != "true" ]]; then
-  echo "Skipping this test: device uses flattened APEXes."
-  exit 0;
-fi
-
-echo "Pulling APEXes from the device factory APEX directories."
-TEMP_DIR="`mktemp -d`"
-adb pull /system/apex/ $TEMP_DIR/system
-adb pull /system_ext/apex/ $TEMP_DIR/system_ext
-adb pull /product/apex/ $TEMP_DIR/product
-adb pull /vendor/apex/ $TEMP_DIR/vendor
-adb pull /odm/apex/ $TEMP_DIR/odm
-
-set -e
-
-echo "Running host_apex_verifier."
-SDK_VERSION="`adb shell getprop ro.build.version.sdk`"
-TEST_DIR=$(dirname $0)
-HOST_APEX_VERIFIER=$TEST_DIR/host_apex_verifier
-DEBUGFS=$TEST_DIR/debugfs_static
-DEAPEXER=$TEST_DIR/deapexer
-$HOST_APEX_VERIFIER \
-  --deapexer $DEAPEXER \
-  --debugfs $DEBUGFS \
-  --sdk_version $SDK_VERSION \
-  --out_system $TEMP_DIR/system \
-  --out_system_ext $TEMP_DIR/system_ext \
-  --out_product $TEMP_DIR/product \
-  --out_vendor $TEMP_DIR/vendor \
-  --out_odm $TEMP_DIR/odm
-
-rm -rf $TEMP_DIR
diff --git a/tools/host-apex-verifier.xml b/tools/host-apex-verifier.xml
deleted file mode 100644
index 46ac96c..0000000
--- a/tools/host-apex-verifier.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<configuration description="Config for host_apex_verifier test">
-    <option name="test-suite-tag" value="host-apex-verifier" />
-    <!-- This test requires a device, so it's not annotated with a null-device -->
-    <test class="com.android.tradefed.testtype.binary.ExecutableHostTest" >
-        <option name="binary" value="host-apex-verifier" />
-    </test>
-</configuration>
diff --git a/tools/host_apex_verifier.cc b/tools/host_apex_verifier.cc
deleted file mode 100644
index 6afce92..0000000
--- a/tools/host_apex_verifier.cc
+++ /dev/null
@@ -1,262 +0,0 @@
-//
-// Copyright (C) 2022 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.
-//
-
-#include <action.h>
-#include <action_manager.h>
-#include <action_parser.h>
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/result.h>
-#include <android-base/strings.h>
-#include <apex_file.h>
-#include <builtins.h>
-#include <getopt.h>
-#include <parser.h>
-#include <pwd.h>
-#include <service_list.h>
-#include <service_parser.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <iostream>
-
-using ::apex::proto::ApexManifest;
-
-// Fake getpwnam for host execution, used by the init::ServiceParser.
-passwd* getpwnam(const char*) {
-  static char fake_buf[] = "fake";
-  static passwd fake_passwd = {
-      .pw_name = fake_buf,
-      .pw_dir = fake_buf,
-      .pw_shell = fake_buf,
-      .pw_uid = 123,
-      .pw_gid = 123,
-  };
-  return &fake_passwd;
-}
-
-namespace android {
-namespace apex {
-namespace {
-
-static const std::vector<std::string> partitions = {"system", "system_ext",
-                                                    "product", "vendor", "odm"};
-
-void PrintUsage() {
-  printf(R"(usage: host_apex_verifier [options]
-
-Tests APEX file(s) for correctness.
-
-Options:
-  --deapexer=PATH             Use the deapexer binary at this path when extracting APEXes.
-  --debugfs=PATH              Use the debugfs binary at this path when extracting APEXes.
-  --sdk_version=INT           The active system SDK version used when filtering versioned
-                              init.rc files.
-  --out_system=DIR            Path to the factory APEX directory for the system partition.
-  --out_system_ext=DIR        Path to the factory APEX directory for the system_ext partition.
-  --out_product=DIR           Path to the factory APEX directory for the product partition.
-  --out_vendor=DIR            Path to the factory APEX directory for the vendor partition.
-  --out_odm=DIR               Path to the factory APEX directory for the odm partition.
-)");
-}
-
-const android::init::BuiltinFunctionMap& ApexInitRcSupportedActionMap() {
-  static const android::init::BuiltinFunctionMap functions = {
-      // Add any init actions supported inside APEXes here.
-      // See system/core/init/builtins.cpp for expected syntax.
-  };
-  return functions;
-}
-
-// Validate any init rc files inside the APEX.
-void CheckInitRc(const std::string& apex_dir, const ApexManifest& manifest,
-                 int sdk_version) {
-  init::Parser parser;
-  init::ServiceList service_list = init::ServiceList();
-  parser.AddSectionParser("service", std::make_unique<init::ServiceParser>(
-                                         &service_list, nullptr, std::nullopt));
-  const init::BuiltinFunctionMap& function_map = ApexInitRcSupportedActionMap();
-  init::Action::set_function_map(&function_map);
-  init::ActionManager action_manager = init::ActionManager();
-  parser.AddSectionParser(
-      "on", std::make_unique<init::ActionParser>(&action_manager, nullptr));
-  std::string init_dir_path = apex_dir + "/etc";
-  std::vector<std::string> init_configs;
-  std::unique_ptr<DIR, decltype(&closedir)> init_dir(
-      opendir(init_dir_path.c_str()), closedir);
-  if (init_dir) {
-    dirent* entry;
-    while ((entry = readdir(init_dir.get()))) {
-      if (base::EndsWith(entry->d_name, "rc")) {
-        init_configs.push_back(init_dir_path + "/" + entry->d_name);
-      }
-    }
-  }
-  // TODO(b/225380016): Extend this tool to check all init.rc files
-  // in the APEX, possibly including different requirements depending
-  // on the SDK version.
-  for (const auto& c :
-       parser.FilterVersionedConfigs(init_configs, sdk_version)) {
-    parser.ParseConfigFile(c);
-  }
-
-  for (const auto& service : service_list) {
-    // Ensure the service path points inside this APEX.
-    auto service_path = service->args()[0];
-    if (!base::StartsWith(service_path, "/apex/" + manifest.name())) {
-      LOG(FATAL) << "Service " << service->name()
-                 << " has path outside of the APEX: " << service_path;
-    }
-    LOG(INFO) << service->name() << ": " << service_path;
-  }
-
-  // The parser will fail if there are any unsupported actions.
-  if (parser.parse_error_count() > 0) {
-    LOG(FATAL) << "Failed to parse APEX init rc file(s)";
-  }
-}
-
-// Extract and validate a single APEX.
-void ScanApex(const std::string& deapexer, const std::string& debugfs,
-              int sdk_version, const std::string& apex_path) {
-  LOG(INFO) << "Checking APEX " << apex_path;
-
-  auto apex = OR_FATAL(ApexFile::Open(apex_path));
-  ApexManifest manifest = apex.GetManifest();
-
-  auto extracted_apex = TemporaryDir();
-  std::string extracted_apex_dir = extracted_apex.path;
-  std::string deapexer_command = deapexer + " --debugfs_path " + debugfs +
-                                 " extract " + apex_path + " " +
-                                 extracted_apex_dir;
-  auto code = system(deapexer_command.c_str());
-  if (code != 0) {
-    LOG(FATAL) << "Error running deapexer command \"" << deapexer_command
-               << "\": " << code;
-  }
-
-  CheckInitRc(extracted_apex_dir, manifest, sdk_version);
-}
-
-// Scan the factory APEX files in the partition apex dir.
-// Scans APEX files directly, rather than flattened ${PRODUCT_OUT}/apex/
-// directories. This allows us to check:
-//   - Prebuilt APEXes which do not flatten to that path.
-//   - Multi-installed APEXes, where only the default
-//     APEX may flatten to that path.
-//   - Extracted target_files archives which may not contain
-//     flattened <PARTITON>/apex/ directories.
-void ScanPartitionApexes(const std::string& deapexer,
-                         const std::string& debugfs, int sdk_version,
-                         const std::string& partition_dir) {
-  LOG(INFO) << "Scanning partition factory APEX dir " << partition_dir;
-
-  std::unique_ptr<DIR, decltype(&closedir)> apex_dir(
-      opendir(partition_dir.c_str()), closedir);
-  if (!apex_dir) {
-    LOG(WARNING) << "Unable to open dir " << partition_dir;
-    return;
-  }
-
-  dirent* entry;
-  while ((entry = readdir(apex_dir.get()))) {
-    if (base::EndsWith(entry->d_name, ".apex") ||
-        base::EndsWith(entry->d_name, ".capex")) {
-      ScanApex(deapexer, debugfs, sdk_version,
-               partition_dir + "/" + entry->d_name);
-    }
-  }
-}
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  android::base::InitLogging(argv, &android::base::StdioLogger);
-
-  std::string deapexer, debugfs;
-  int sdk_version = INT_MAX;
-  std::map<std::string, std::string> partition_map;
-
-  while (true) {
-    static const struct option long_options[] = {
-        {"help", no_argument, nullptr, 'h'},
-        {"deapexer", required_argument, nullptr, 0},
-        {"debugfs", required_argument, nullptr, 0},
-        {"sdk_version", required_argument, nullptr, 0},
-        {"out_system", required_argument, nullptr, 0},
-        {"out_system_ext", required_argument, nullptr, 0},
-        {"out_product", required_argument, nullptr, 0},
-        {"out_vendor", required_argument, nullptr, 0},
-        {"out_odm", required_argument, nullptr, 0},
-        {nullptr, 0, nullptr, 0},
-    };
-
-    int option_index;
-    int arg = getopt_long(argc, argv, "h", long_options, &option_index);
-
-    if (arg == -1) {
-      break;
-    }
-
-    switch (arg) {
-      case 0:
-        if (long_options[option_index].name == "deapexer") {
-          deapexer = optarg;
-        }
-        if (long_options[option_index].name == "debugfs") {
-          debugfs = optarg;
-        }
-        if (long_options[option_index].name == "sdk_version") {
-          if (!base::ParseInt(optarg, &sdk_version)) {
-            PrintUsage();
-            return EXIT_FAILURE;
-          }
-        }
-        for (const auto& p : partitions) {
-          if (long_options[option_index].name == "out_" + p) {
-            partition_map[p] = optarg;
-          }
-        }
-        break;
-      case 'h':
-        PrintUsage();
-        return EXIT_SUCCESS;
-      default:
-        LOG(ERROR) << "getopt returned invalid result: " << arg;
-        return EXIT_FAILURE;
-    }
-  }
-
-  argc -= optind;
-  argv += optind;
-
-  if (argc != 0 || deapexer.empty() || debugfs.empty()) {
-    PrintUsage();
-    return EXIT_FAILURE;
-  }
-
-  for (const auto& p : partition_map) {
-    ScanPartitionApexes(deapexer, debugfs, sdk_version, p.second);
-  }
-
-  return EXIT_SUCCESS;
-}
-
-}  // namespace apex
-}  // namespace android
-
-int main(int argc, char** argv) { return android::apex::main(argc, argv); }