Merge "Add comments to bpf properties"
diff --git a/android/Android.bp b/android/Android.bp
index f58a472..e0ad58f 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -38,7 +38,9 @@
         "bazel_paths.go",
         "buildinfo_prop.go",
         "config.go",
+        "test_config.go",
         "config_bp2build.go",
+        "configured_jars.go",
         "csuite_config.go",
         "deapexer.go",
         "defaults.go",
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index fd8f403..0721953 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -37,155 +37,162 @@
 
 var (
 	Bp2buildDefaultConfig = Bp2BuildConfig{
-		"prebuilts/runtime/mainline/platform/sdk":                Bp2BuildDefaultTrueRecursively,
-		"art/libartpalette":                                      Bp2BuildDefaultTrueRecursively,
-		"art/libartbase":                                         Bp2BuildDefaultTrueRecursively,
-		"art/libdexfile":                                         Bp2BuildDefaultTrueRecursively,
-		"art/libnativebridge":                                    Bp2BuildDefaultTrueRecursively,
-		"art/runtime":                                            Bp2BuildDefaultTrueRecursively,
-		"art/tools":                                              Bp2BuildDefaultTrue,
-		"bionic":                                                 Bp2BuildDefaultTrueRecursively,
-		"bootable/recovery/tools/recovery_l10n":                  Bp2BuildDefaultTrue,
-		"build/bazel/examples/apex/minimal":                      Bp2BuildDefaultTrueRecursively,
-		"build/bazel/examples/soong_config_variables":            Bp2BuildDefaultTrueRecursively,
-		"build/bazel/examples/python":                            Bp2BuildDefaultTrueRecursively,
-		"build/bazel/examples/gensrcs":                           Bp2BuildDefaultTrueRecursively,
-		"build/make/target/product/security":                     Bp2BuildDefaultTrue,
-		"build/make/tools/signapk":                               Bp2BuildDefaultTrue,
-		"build/make/tools/zipalign":                              Bp2BuildDefaultTrueRecursively,
-		"build/soong":                                            Bp2BuildDefaultTrue,
-		"build/soong/cc/libbuildversion":                         Bp2BuildDefaultTrue, // Skip tests subdir
-		"build/soong/cc/ndkstubgen":                              Bp2BuildDefaultTrue,
-		"build/soong/cc/symbolfile":                              Bp2BuildDefaultTrue,
-		"build/soong/linkerconfig":                               Bp2BuildDefaultTrueRecursively,
-		"build/soong/scripts":                                    Bp2BuildDefaultTrueRecursively,
-		"cts/common/device-side/nativetesthelper/jni":            Bp2BuildDefaultTrueRecursively,
-		"development/apps/DevelopmentSettings":                   Bp2BuildDefaultTrue,
-		"development/apps/Fallback":                              Bp2BuildDefaultTrue,
-		"development/apps/WidgetPreview":                         Bp2BuildDefaultTrue,
-		"development/samples/BasicGLSurfaceView":                 Bp2BuildDefaultTrue,
-		"development/samples/BluetoothChat":                      Bp2BuildDefaultTrue,
-		"development/samples/BrokenKeyDerivation":                Bp2BuildDefaultTrue,
-		"development/samples/Compass":                            Bp2BuildDefaultTrue,
-		"development/samples/ContactManager":                     Bp2BuildDefaultTrue,
-		"development/samples/FixedGridLayout":                    Bp2BuildDefaultTrue,
-		"development/samples/HelloEffects":                       Bp2BuildDefaultTrue,
-		"development/samples/Home":                               Bp2BuildDefaultTrue,
-		"development/samples/HoneycombGallery":                   Bp2BuildDefaultTrue,
-		"development/samples/JetBoy":                             Bp2BuildDefaultTrue,
-		"development/samples/KeyChainDemo":                       Bp2BuildDefaultTrue,
-		"development/samples/LceDemo":                            Bp2BuildDefaultTrue,
-		"development/samples/LunarLander":                        Bp2BuildDefaultTrue,
-		"development/samples/MultiResolution":                    Bp2BuildDefaultTrue,
-		"development/samples/MultiWindow":                        Bp2BuildDefaultTrue,
-		"development/samples/NotePad":                            Bp2BuildDefaultTrue,
-		"development/samples/Obb":                                Bp2BuildDefaultTrue,
-		"development/samples/RSSReader":                          Bp2BuildDefaultTrue,
-		"development/samples/ReceiveShareDemo":                   Bp2BuildDefaultTrue,
-		"development/samples/SearchableDictionary":               Bp2BuildDefaultTrue,
-		"development/samples/SipDemo":                            Bp2BuildDefaultTrue,
-		"development/samples/SkeletonApp":                        Bp2BuildDefaultTrue,
-		"development/samples/Snake":                              Bp2BuildDefaultTrue,
-		"development/samples/SpellChecker/":                      Bp2BuildDefaultTrueRecursively,
-		"development/samples/ThemedNavBarKeyboard":               Bp2BuildDefaultTrue,
-		"development/samples/ToyVpn":                             Bp2BuildDefaultTrue,
-		"development/samples/TtsEngine":                          Bp2BuildDefaultTrue,
-		"development/samples/USB/AdbTest":                        Bp2BuildDefaultTrue,
-		"development/samples/USB/MissileLauncher":                Bp2BuildDefaultTrue,
-		"development/samples/VoiceRecognitionService":            Bp2BuildDefaultTrue,
-		"development/samples/VoicemailProviderDemo":              Bp2BuildDefaultTrue,
-		"development/samples/WiFiDirectDemo":                     Bp2BuildDefaultTrue,
-		"development/sdk":                                        Bp2BuildDefaultTrueRecursively,
-		"external/aac":                                           Bp2BuildDefaultTrueRecursively,
-		"external/arm-optimized-routines":                        Bp2BuildDefaultTrueRecursively,
-		"external/auto/android-annotation-stubs":                 Bp2BuildDefaultTrueRecursively,
-		"external/auto/common":                                   Bp2BuildDefaultTrueRecursively,
-		"external/auto/service":                                  Bp2BuildDefaultTrueRecursively,
-		"external/boringssl":                                     Bp2BuildDefaultTrueRecursively,
-		"external/bouncycastle":                                  Bp2BuildDefaultTrue,
-		"external/brotli":                                        Bp2BuildDefaultTrue,
-		"external/conscrypt":                                     Bp2BuildDefaultTrue,
-		"external/e2fsprogs":                                     Bp2BuildDefaultTrueRecursively,
-		"external/eigen":                                         Bp2BuildDefaultTrueRecursively,
-		"external/erofs-utils":                                   Bp2BuildDefaultTrueRecursively,
-		"external/error_prone":                                   Bp2BuildDefaultTrueRecursively,
-		"external/expat":                                         Bp2BuildDefaultTrueRecursively,
-		"external/f2fs-tools":                                    Bp2BuildDefaultTrue,
-		"external/flac":                                          Bp2BuildDefaultTrueRecursively,
-		"external/fmtlib":                                        Bp2BuildDefaultTrueRecursively,
-		"external/google-benchmark":                              Bp2BuildDefaultTrueRecursively,
-		"external/googletest":                                    Bp2BuildDefaultTrueRecursively,
-		"external/gwp_asan":                                      Bp2BuildDefaultTrueRecursively,
-		"external/hamcrest":                                      Bp2BuildDefaultTrueRecursively,
-		"external/icu":                                           Bp2BuildDefaultTrueRecursively,
-		"external/icu/android_icu4j":                             Bp2BuildDefaultFalse, // java rules incomplete
-		"external/icu/icu4j":                                     Bp2BuildDefaultFalse, // java rules incomplete
-		"external/jarjar":                                        Bp2BuildDefaultTrueRecursively,
-		"external/javapoet":                                      Bp2BuildDefaultTrueRecursively,
-		"external/jemalloc_new":                                  Bp2BuildDefaultTrueRecursively,
-		"external/jsoncpp":                                       Bp2BuildDefaultTrueRecursively,
-		"external/junit":                                         Bp2BuildDefaultTrueRecursively,
-		"external/libavc":                                        Bp2BuildDefaultTrueRecursively,
-		"external/libcap":                                        Bp2BuildDefaultTrueRecursively,
-		"external/libcxx":                                        Bp2BuildDefaultTrueRecursively,
-		"external/libcxxabi":                                     Bp2BuildDefaultTrueRecursively,
-		"external/libevent":                                      Bp2BuildDefaultTrueRecursively,
-		"external/libgav1":                                       Bp2BuildDefaultTrueRecursively,
-		"external/libhevc":                                       Bp2BuildDefaultTrueRecursively,
-		"external/libjpeg-turbo":                                 Bp2BuildDefaultTrueRecursively,
-		"external/libmpeg2":                                      Bp2BuildDefaultTrueRecursively,
-		"external/libpng":                                        Bp2BuildDefaultTrueRecursively,
-		"external/lz4/lib":                                       Bp2BuildDefaultTrue,
-		"external/lzma/C":                                        Bp2BuildDefaultTrueRecursively,
-		"external/mdnsresponder":                                 Bp2BuildDefaultTrueRecursively,
-		"external/minijail":                                      Bp2BuildDefaultTrueRecursively,
-		"external/pcre":                                          Bp2BuildDefaultTrueRecursively,
-		"external/protobuf":                                      Bp2BuildDefaultTrueRecursively,
-		"external/python/six":                                    Bp2BuildDefaultTrueRecursively,
-		"external/rappor":                                        Bp2BuildDefaultTrueRecursively,
-		"external/scudo":                                         Bp2BuildDefaultTrueRecursively,
-		"external/selinux/libselinux":                            Bp2BuildDefaultTrueRecursively,
-		"external/selinux/libsepol":                              Bp2BuildDefaultTrueRecursively,
-		"external/toybox":                                        Bp2BuildDefaultTrueRecursively,
-		"external/zlib":                                          Bp2BuildDefaultTrueRecursively,
-		"external/zopfli":                                        Bp2BuildDefaultTrueRecursively,
-		"external/zstd":                                          Bp2BuildDefaultTrueRecursively,
-		"frameworks/av/media/codecs":                             Bp2BuildDefaultTrueRecursively,
-		"frameworks/av/services/minijail":                        Bp2BuildDefaultTrueRecursively,
-		"frameworks/base/media/tests/MediaDump":                  Bp2BuildDefaultTrue,
-		"frameworks/base/startop/apps/test":                      Bp2BuildDefaultTrue,
-		"frameworks/base/tests/appwidgets/AppWidgetHostTest":     Bp2BuildDefaultTrueRecursively,
-		"frameworks/native/libs/adbd_auth":                       Bp2BuildDefaultTrueRecursively,
-		"frameworks/native/libs/arect":                           Bp2BuildDefaultTrueRecursively,
-		"frameworks/native/libs/math":                            Bp2BuildDefaultTrueRecursively,
-		"frameworks/native/libs/nativebase":                      Bp2BuildDefaultTrueRecursively,
-		"frameworks/native/opengl/tests/gl2_cameraeye":           Bp2BuildDefaultTrue,
-		"frameworks/native/opengl/tests/gl2_java":                Bp2BuildDefaultTrue,
-		"frameworks/native/opengl/tests/testLatency":             Bp2BuildDefaultTrue,
-		"frameworks/native/opengl/tests/testPauseResume":         Bp2BuildDefaultTrue,
-		"frameworks/native/opengl/tests/testViewport":            Bp2BuildDefaultTrue,
-		"frameworks/proto_logging/stats/stats_log_api_gen":       Bp2BuildDefaultTrueRecursively,
-		"libnativehelper":                                        Bp2BuildDefaultTrueRecursively,
-		"packages/apps/DevCamera":                                Bp2BuildDefaultTrue,
-		"packages/apps/HTMLViewer":                               Bp2BuildDefaultTrue,
-		"packages/apps/Protips":                                  Bp2BuildDefaultTrue,
-		"packages/apps/WallpaperPicker":                          Bp2BuildDefaultTrue,
-		"packages/modules/StatsD/lib/libstatssocket":             Bp2BuildDefaultTrueRecursively,
-		"packages/modules/adb":                                   Bp2BuildDefaultTrue,
-		"packages/modules/adb/apex":                              Bp2BuildDefaultTrue,
-		"packages/modules/adb/crypto":                            Bp2BuildDefaultTrueRecursively,
-		"packages/modules/adb/libs":                              Bp2BuildDefaultTrueRecursively,
-		"packages/modules/adb/pairing_auth":                      Bp2BuildDefaultTrueRecursively,
-		"packages/modules/adb/pairing_connection":                Bp2BuildDefaultTrueRecursively,
-		"packages/modules/adb/proto":                             Bp2BuildDefaultTrueRecursively,
-		"packages/modules/adb/tls":                               Bp2BuildDefaultTrueRecursively,
-		"packages/providers/MediaProvider/tools/dialogs":         Bp2BuildDefaultTrue,
-		"packages/screensavers/Basic":                            Bp2BuildDefaultTrue,
-		"packages/services/Car/tests/SampleRearViewCamera":       Bp2BuildDefaultTrue,
-		"prebuilts/clang/host/linux-x86":                         Bp2BuildDefaultTrueRecursively,
-		"prebuilts/sdk/current/extras/app-toolkit":               Bp2BuildDefaultTrue,
-		"prebuilts/sdk/current/support":                          Bp2BuildDefaultTrue,
-		"prebuilts/tools/common/m2":                              Bp2BuildDefaultTrue,
+		"art/libartpalette":                     Bp2BuildDefaultTrueRecursively,
+		"art/libartbase":                        Bp2BuildDefaultTrueRecursively,
+		"art/libdexfile":                        Bp2BuildDefaultTrueRecursively,
+		"art/libnativebridge":                   Bp2BuildDefaultTrueRecursively,
+		"art/runtime":                           Bp2BuildDefaultTrueRecursively,
+		"art/tools":                             Bp2BuildDefaultTrue,
+		"bionic":                                Bp2BuildDefaultTrueRecursively,
+		"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
+
+		"build/bazel/examples/apex/minimal":           Bp2BuildDefaultTrueRecursively,
+		"build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively,
+		"build/bazel/examples/python":                 Bp2BuildDefaultTrueRecursively,
+		"build/bazel/examples/gensrcs":                Bp2BuildDefaultTrueRecursively,
+		"build/make/target/product/security":          Bp2BuildDefaultTrue,
+		"build/make/tools/signapk":                    Bp2BuildDefaultTrue,
+		"build/make/tools/zipalign":                   Bp2BuildDefaultTrueRecursively,
+		"build/soong":                                 Bp2BuildDefaultTrue,
+		"build/soong/cc/libbuildversion":              Bp2BuildDefaultTrue, // Skip tests subdir
+		"build/soong/cc/ndkstubgen":                   Bp2BuildDefaultTrue,
+		"build/soong/cc/symbolfile":                   Bp2BuildDefaultTrue,
+		"build/soong/linkerconfig":                    Bp2BuildDefaultTrueRecursively,
+		"build/soong/scripts":                         Bp2BuildDefaultTrueRecursively,
+
+		"cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively,
+		"development/apps/DevelopmentSettings":        Bp2BuildDefaultTrue,
+		"development/apps/Fallback":                   Bp2BuildDefaultTrue,
+		"development/apps/WidgetPreview":              Bp2BuildDefaultTrue,
+		"development/samples/BasicGLSurfaceView":      Bp2BuildDefaultTrue,
+		"development/samples/BluetoothChat":           Bp2BuildDefaultTrue,
+		"development/samples/BrokenKeyDerivation":     Bp2BuildDefaultTrue,
+		"development/samples/Compass":                 Bp2BuildDefaultTrue,
+		"development/samples/ContactManager":          Bp2BuildDefaultTrue,
+		"development/samples/FixedGridLayout":         Bp2BuildDefaultTrue,
+		"development/samples/HelloEffects":            Bp2BuildDefaultTrue,
+		"development/samples/Home":                    Bp2BuildDefaultTrue,
+		"development/samples/HoneycombGallery":        Bp2BuildDefaultTrue,
+		"development/samples/JetBoy":                  Bp2BuildDefaultTrue,
+		"development/samples/KeyChainDemo":            Bp2BuildDefaultTrue,
+		"development/samples/LceDemo":                 Bp2BuildDefaultTrue,
+		"development/samples/LunarLander":             Bp2BuildDefaultTrue,
+		"development/samples/MultiResolution":         Bp2BuildDefaultTrue,
+		"development/samples/MultiWindow":             Bp2BuildDefaultTrue,
+		"development/samples/NotePad":                 Bp2BuildDefaultTrue,
+		"development/samples/Obb":                     Bp2BuildDefaultTrue,
+		"development/samples/RSSReader":               Bp2BuildDefaultTrue,
+		"development/samples/ReceiveShareDemo":        Bp2BuildDefaultTrue,
+		"development/samples/SearchableDictionary":    Bp2BuildDefaultTrue,
+		"development/samples/SipDemo":                 Bp2BuildDefaultTrue,
+		"development/samples/SkeletonApp":             Bp2BuildDefaultTrue,
+		"development/samples/Snake":                   Bp2BuildDefaultTrue,
+		"development/samples/SpellChecker/":           Bp2BuildDefaultTrueRecursively,
+		"development/samples/ThemedNavBarKeyboard":    Bp2BuildDefaultTrue,
+		"development/samples/ToyVpn":                  Bp2BuildDefaultTrue,
+		"development/samples/TtsEngine":               Bp2BuildDefaultTrue,
+		"development/samples/USB/AdbTest":             Bp2BuildDefaultTrue,
+		"development/samples/USB/MissileLauncher":     Bp2BuildDefaultTrue,
+		"development/samples/VoiceRecognitionService": Bp2BuildDefaultTrue,
+		"development/samples/VoicemailProviderDemo":   Bp2BuildDefaultTrue,
+		"development/samples/WiFiDirectDemo":          Bp2BuildDefaultTrue,
+		"development/sdk":                             Bp2BuildDefaultTrueRecursively,
+
+		"external/aac":                           Bp2BuildDefaultTrueRecursively,
+		"external/arm-optimized-routines":        Bp2BuildDefaultTrueRecursively,
+		"external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively,
+		"external/auto/common":                   Bp2BuildDefaultTrueRecursively,
+		"external/auto/service":                  Bp2BuildDefaultTrueRecursively,
+		"external/boringssl":                     Bp2BuildDefaultTrueRecursively,
+		"external/bouncycastle":                  Bp2BuildDefaultTrue,
+		"external/brotli":                        Bp2BuildDefaultTrue,
+		"external/conscrypt":                     Bp2BuildDefaultTrue,
+		"external/e2fsprogs":                     Bp2BuildDefaultTrueRecursively,
+		"external/eigen":                         Bp2BuildDefaultTrueRecursively,
+		"external/erofs-utils":                   Bp2BuildDefaultTrueRecursively,
+		"external/error_prone":                   Bp2BuildDefaultTrueRecursively,
+		"external/expat":                         Bp2BuildDefaultTrueRecursively,
+		"external/f2fs-tools":                    Bp2BuildDefaultTrue,
+		"external/flac":                          Bp2BuildDefaultTrueRecursively,
+		"external/fmtlib":                        Bp2BuildDefaultTrueRecursively,
+		"external/google-benchmark":              Bp2BuildDefaultTrueRecursively,
+		"external/googletest":                    Bp2BuildDefaultTrueRecursively,
+		"external/gwp_asan":                      Bp2BuildDefaultTrueRecursively,
+		"external/hamcrest":                      Bp2BuildDefaultTrueRecursively,
+		"external/icu":                           Bp2BuildDefaultTrueRecursively,
+		"external/icu/android_icu4j":             Bp2BuildDefaultFalse, // java rules incomplete
+		"external/icu/icu4j":                     Bp2BuildDefaultFalse, // java rules incomplete
+		"external/jarjar":                        Bp2BuildDefaultTrueRecursively,
+		"external/javapoet":                      Bp2BuildDefaultTrueRecursively,
+		"external/jemalloc_new":                  Bp2BuildDefaultTrueRecursively,
+		"external/jsoncpp":                       Bp2BuildDefaultTrueRecursively,
+		"external/junit":                         Bp2BuildDefaultTrueRecursively,
+		"external/libavc":                        Bp2BuildDefaultTrueRecursively,
+		"external/libcap":                        Bp2BuildDefaultTrueRecursively,
+		"external/libcxx":                        Bp2BuildDefaultTrueRecursively,
+		"external/libcxxabi":                     Bp2BuildDefaultTrueRecursively,
+		"external/libevent":                      Bp2BuildDefaultTrueRecursively,
+		"external/libgav1":                       Bp2BuildDefaultTrueRecursively,
+		"external/libhevc":                       Bp2BuildDefaultTrueRecursively,
+		"external/libjpeg-turbo":                 Bp2BuildDefaultTrueRecursively,
+		"external/libmpeg2":                      Bp2BuildDefaultTrueRecursively,
+		"external/libpng":                        Bp2BuildDefaultTrueRecursively,
+		"external/lz4/lib":                       Bp2BuildDefaultTrue,
+		"external/lzma/C":                        Bp2BuildDefaultTrueRecursively,
+		"external/mdnsresponder":                 Bp2BuildDefaultTrueRecursively,
+		"external/minijail":                      Bp2BuildDefaultTrueRecursively,
+		"external/pcre":                          Bp2BuildDefaultTrueRecursively,
+		"external/protobuf":                      Bp2BuildDefaultTrueRecursively,
+		"external/python/six":                    Bp2BuildDefaultTrueRecursively,
+		"external/rappor":                        Bp2BuildDefaultTrueRecursively,
+		"external/scudo":                         Bp2BuildDefaultTrueRecursively,
+		"external/selinux/libselinux":            Bp2BuildDefaultTrueRecursively,
+		"external/selinux/libsepol":              Bp2BuildDefaultTrueRecursively,
+		"external/toybox":                        Bp2BuildDefaultTrueRecursively,
+		"external/zlib":                          Bp2BuildDefaultTrueRecursively,
+		"external/zopfli":                        Bp2BuildDefaultTrueRecursively,
+		"external/zstd":                          Bp2BuildDefaultTrueRecursively,
+
+		"frameworks/av/media/codecs":                         Bp2BuildDefaultTrueRecursively,
+		"frameworks/av/services/minijail":                    Bp2BuildDefaultTrueRecursively,
+		"frameworks/base/media/tests/MediaDump":              Bp2BuildDefaultTrue,
+		"frameworks/base/startop/apps/test":                  Bp2BuildDefaultTrue,
+		"frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
+		"frameworks/native/libs/adbd_auth":                   Bp2BuildDefaultTrueRecursively,
+		"frameworks/native/libs/arect":                       Bp2BuildDefaultTrueRecursively,
+		"frameworks/native/libs/math":                        Bp2BuildDefaultTrueRecursively,
+		"frameworks/native/libs/nativebase":                  Bp2BuildDefaultTrueRecursively,
+		"frameworks/native/opengl/tests/gl2_cameraeye":       Bp2BuildDefaultTrue,
+		"frameworks/native/opengl/tests/gl2_java":            Bp2BuildDefaultTrue,
+		"frameworks/native/opengl/tests/testLatency":         Bp2BuildDefaultTrue,
+		"frameworks/native/opengl/tests/testPauseResume":     Bp2BuildDefaultTrue,
+		"frameworks/native/opengl/tests/testViewport":        Bp2BuildDefaultTrue,
+		"frameworks/proto_logging/stats/stats_log_api_gen":   Bp2BuildDefaultTrueRecursively,
+
+		"libnativehelper":                                  Bp2BuildDefaultTrueRecursively,
+		"packages/apps/DevCamera":                          Bp2BuildDefaultTrue,
+		"packages/apps/HTMLViewer":                         Bp2BuildDefaultTrue,
+		"packages/apps/Protips":                            Bp2BuildDefaultTrue,
+		"packages/apps/WallpaperPicker":                    Bp2BuildDefaultTrue,
+		"packages/modules/StatsD/lib/libstatssocket":       Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb":                             Bp2BuildDefaultTrue,
+		"packages/modules/adb/apex":                        Bp2BuildDefaultTrue,
+		"packages/modules/adb/crypto":                      Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/libs":                        Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/pairing_auth":                Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/pairing_connection":          Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/proto":                       Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/tls":                         Bp2BuildDefaultTrueRecursively,
+		"packages/providers/MediaProvider/tools/dialogs":   Bp2BuildDefaultTrue,
+		"packages/screensavers/Basic":                      Bp2BuildDefaultTrue,
+		"packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultTrue,
+
+		"prebuilts/clang/host/linux-x86":           Bp2BuildDefaultTrueRecursively,
+		"prebuilts/runtime/mainline/platform/sdk":  Bp2BuildDefaultTrueRecursively,
+		"prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue,
+		"prebuilts/sdk/current/support":            Bp2BuildDefaultTrue,
+		"prebuilts/tools/common/m2":                Bp2BuildDefaultTrue,
+
 		"system/apex":                                            Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures
 		"system/apex/apexer":                                     Bp2BuildDefaultTrue,
 		"system/apex/libs":                                       Bp2BuildDefaultTrueRecursively,
@@ -208,6 +215,10 @@
 		"system/libartpalette":                                   Bp2BuildDefaultTrueRecursively,
 		"system/libbase":                                         Bp2BuildDefaultTrueRecursively,
 		"system/libfmq":                                          Bp2BuildDefaultTrue,
+		"system/libhidl/transport/base/1.0":                      Bp2BuildDefaultTrue,
+		"system/libhidl/transport/manager/1.0":                   Bp2BuildDefaultTrue,
+		"system/libhidl/transport/manager/1.1":                   Bp2BuildDefaultTrue,
+		"system/libhidl/transport/manager/1.2":                   Bp2BuildDefaultTrue,
 		"system/libhwbinder":                                     Bp2BuildDefaultTrueRecursively,
 		"system/libprocinfo":                                     Bp2BuildDefaultTrue,
 		"system/libziparchive":                                   Bp2BuildDefaultTrueRecursively,
@@ -220,9 +231,10 @@
 		"system/timezone/output_data":                            Bp2BuildDefaultTrueRecursively,
 		"system/tools/sysprop":                                   Bp2BuildDefaultTrue,
 		"system/unwinding/libunwindstack":                        Bp2BuildDefaultTrueRecursively,
-		"tools/apksig":                                           Bp2BuildDefaultTrue,
-		"tools/platform-compat/java/android/compat":              Bp2BuildDefaultTrueRecursively,
-		"tools/tradefederation/prebuilts/filegroups":             Bp2BuildDefaultTrueRecursively,
+
+		"tools/apksig": Bp2BuildDefaultTrue,
+		"tools/platform-compat/java/android/compat":  Bp2BuildDefaultTrueRecursively,
+		"tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively,
 	}
 
 	Bp2buildKeepExistingBuildFile = map[string]bool{
@@ -374,6 +386,10 @@
 		"car-ui-androidx-core-common-nodeps",
 		"car-ui-androidx-lifecycle-common-nodeps",
 		"car-ui-androidx-constraintlayout-solver-nodeps",
+
+		//system/libhidl
+		// needed by cc_hidl_library
+		"libhidlbase",
 	}
 
 	Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -558,5 +574,12 @@
 		"prebuilt_android-support-annotations-nodeps",
 		"prebuilt_android-arch-paging-common-nodeps",
 		"prebuilt_android-arch-room-common-nodeps",
+
+		// Disabled pending the investigation of b/242220039
+		"libhidlbase",
+		"android.hidl.base@1.0",
+		"android.hidl.manager@1.0",
+		"android.hidl.manager@1.1",
+		"android.hidl.manager@1.2",
 	}
 )
diff --git a/android/arch.go b/android/arch.go
index 6acc8ad..b5bd2f0 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -393,54 +393,6 @@
 	}
 }
 
-func registerBp2buildArchPathDepsMutator(ctx RegisterMutatorsContext) {
-	ctx.BottomUp("bp2build-arch-pathdeps", bp2buildArchPathDepsMutator).Parallel()
-}
-
-// add dependencies for architecture specific properties tagged with `android:"path"`
-func bp2buildArchPathDepsMutator(ctx BottomUpMutatorContext) {
-	var module Module
-	module = ctx.Module()
-
-	m := module.base()
-	if !m.ArchSpecific() {
-		return
-	}
-
-	// addPathDepsForProps does not descend into sub structs, so we need to descend into the
-	// arch-specific properties ourselves
-	var properties []interface{}
-	for _, archProperties := range m.archProperties {
-		for _, archProps := range archProperties {
-			archPropValues := reflect.ValueOf(archProps).Elem()
-			// there are three "arch" variations, descend into each
-			for _, variant := range []string{"Arch", "Multilib", "Target"} {
-				// The properties are an interface, get the value (a pointer) that it points to
-				archProps := archPropValues.FieldByName(variant).Elem()
-				if archProps.IsNil() {
-					continue
-				}
-				// And then a pointer to a struct
-				archProps = archProps.Elem()
-				for i := 0; i < archProps.NumField(); i += 1 {
-					f := archProps.Field(i)
-					// If the value of the field is a struct (as opposed to a pointer to a struct) then step
-					// into the BlueprintEmbed field.
-					if f.Kind() == reflect.Struct {
-						f = f.FieldByName("BlueprintEmbed")
-					}
-					if f.IsZero() {
-						continue
-					}
-					props := f.Interface().(interface{})
-					properties = append(properties, props)
-				}
-			}
-		}
-	}
-	addPathDepsForProps(ctx, properties)
-}
-
 // osMutator splits an arch-specific module into a variant for each OS that is enabled for the
 // module.  It uses the HostOrDevice value passed to InitAndroidArchModule and the
 // device_supported and host_supported properties to determine which OsTypes are enabled for this
@@ -998,19 +950,13 @@
 		if string(field.Tag) != `android:"`+strings.Join(values, ",")+`"` {
 			panic(fmt.Errorf("unexpected tag format %q", field.Tag))
 		}
-		// don't delete path tag as it is needed for bp2build
 		// these tags don't need to be present in the runtime generated struct type.
-		values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend"})
-		if len(values) > 0 && values[0] != "path" {
+		values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend", "path"})
+		if len(values) > 0 {
 			panic(fmt.Errorf("unknown tags %q in field %q", values, prefix+field.Name))
-		} else if len(values) == 1 {
-			// FIXME(b/200678898): This assumes that the only tag type when there's
-			// `android:"arch_variant"` is `android` itself and thus clobbers others
-			field.Tag = reflect.StructTag(`android:"` + strings.Join(values, ",") + `"`)
-		} else {
-			field.Tag = ``
 		}
 
+		field.Tag = ``
 		return true, field
 	}
 	return false, field
diff --git a/android/arch_test.go b/android/arch_test.go
index dd0b115..ad2076d 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -66,9 +66,9 @@
 			}{},
 			out: &struct {
 				A *string
-				B *string `android:"path"`
-				C *string `android:"path"`
-				D *string `android:"path"`
+				B *string
+				C *string
+				D *string
 			}{},
 			filtered: true,
 		},
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 5804a46..a5fa043 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -29,6 +29,7 @@
 
 	"android/soong/bazel/cquery"
 	"android/soong/shared"
+
 	"github.com/google/blueprint"
 
 	"android/soong/bazel"
@@ -54,7 +55,7 @@
 }
 
 func RegisterMixedBuildsMutator(ctx RegistrationContext) {
-	ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
+	ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
 		ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
 	})
 }
@@ -766,9 +767,9 @@
 	cqueryOutput, cqueryErr, err := context.issueBazelCommand(context.paths, bazel.CqueryBuildRootRunName, cqueryCmd,
 		"--output=starlark", "--starlark:file="+absolutePath(cqueryFileRelpath))
 	if err != nil {
-		_ = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"), []byte(cqueryOutput), 0666)
+		return err
 	}
-	if err != nil {
+	if err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"), []byte(cqueryOutput), 0666); err != nil {
 		return err
 	}
 
diff --git a/android/config.go b/android/config.go
index 84c17de..d3f8ab4 100644
--- a/android/config.go
+++ b/android/config.go
@@ -20,7 +20,6 @@
 import (
 	"bytes"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io/ioutil"
 	"os"
@@ -345,123 +344,6 @@
 	}
 }
 
-// TestConfig returns a Config object for testing.
-func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
-	envCopy := make(map[string]string)
-	for k, v := range env {
-		envCopy[k] = v
-	}
-
-	// Copy the real PATH value to the test environment, it's needed by
-	// NonHermeticHostSystemTool() used in x86_darwin_host.go
-	envCopy["PATH"] = os.Getenv("PATH")
-
-	config := &config{
-		productVariables: productVariables{
-			DeviceName:                          stringPtr("test_device"),
-			DeviceProduct:                       stringPtr("test_product"),
-			Platform_sdk_version:                intPtr(30),
-			Platform_sdk_codename:               stringPtr("S"),
-			Platform_base_sdk_extension_version: intPtr(1),
-			Platform_version_active_codenames:   []string{"S", "Tiramisu"},
-			DeviceSystemSdkVersions:             []string{"14", "15"},
-			Platform_systemsdk_versions:         []string{"29", "30"},
-			AAPTConfig:                          []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
-			AAPTPreferredConfig:                 stringPtr("xhdpi"),
-			AAPTCharacteristics:                 stringPtr("nosdcard"),
-			AAPTPrebuiltDPI:                     []string{"xhdpi", "xxhdpi"},
-			UncompressPrivAppDex:                boolPtr(true),
-			ShippingApiLevel:                    stringPtr("30"),
-		},
-
-		outDir:       buildDir,
-		soongOutDir:  filepath.Join(buildDir, "soong"),
-		captureBuild: true,
-		env:          envCopy,
-
-		// Set testAllowNonExistentPaths so that test contexts don't need to specify every path
-		// passed to PathForSource or PathForModuleSrc.
-		TestAllowNonExistentPaths: true,
-
-		BazelContext:              noopBazelContext{},
-		mixedBuildDisabledModules: make(map[string]struct{}),
-		mixedBuildEnabledModules:  make(map[string]struct{}),
-	}
-	config.deviceConfig = &deviceConfig{
-		config: config,
-	}
-	config.TestProductVariables = &config.productVariables
-
-	config.mockFileSystem(bp, fs)
-
-	determineBuildOS(config)
-
-	return Config{config}
-}
-
-func modifyTestConfigToSupportArchMutator(testConfig Config) {
-	config := testConfig.config
-
-	config.Targets = map[OsType][]Target{
-		Android: []Target{
-			{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
-			{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false},
-		},
-		config.BuildOS: []Target{
-			{config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
-			{config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
-		},
-	}
-
-	if runtime.GOOS == "darwin" {
-		config.Targets[config.BuildOS] = config.Targets[config.BuildOS][:1]
-	}
-
-	config.BuildOSTarget = config.Targets[config.BuildOS][0]
-	config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
-	config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
-	config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
-	config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
-	config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a")
-	config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm")
-	config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon")
-}
-
-func modifyTestConfigForMusl(config Config) {
-	delete(config.Targets, config.BuildOS)
-	config.productVariables.HostMusl = boolPtr(true)
-	determineBuildOS(config.config)
-	config.Targets[config.BuildOS] = []Target{
-		{config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
-		{config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
-	}
-
-	config.BuildOSTarget = config.Targets[config.BuildOS][0]
-	config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
-}
-
-// TestArchConfig returns a Config object suitable for using for tests that
-// need to run the arch mutator.
-func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
-	testConfig := TestConfig(buildDir, env, bp, fs)
-	modifyTestConfigToSupportArchMutator(testConfig)
-	return testConfig
-}
-
-// ConfigForAdditionalRun is a config object which is "reset" for another
-// bootstrap run. Only per-run data is reset. Data which needs to persist across
-// multiple runs in the same program execution is carried over (such as Bazel
-// context or environment deps).
-func ConfigForAdditionalRun(c Config) (Config, error) {
-	newConfig, err := NewConfig(c.moduleListFile, c.runGoTests, c.outDir, c.soongOutDir, c.env)
-	if err != nil {
-		return Config{}, err
-	}
-	newConfig.BazelContext = c.BazelContext
-	newConfig.envDeps = c.envDeps
-	return newConfig, nil
-}
-
 // NewConfig creates a new Config object. The srcDir argument specifies the path
 // to the root source directory. It also loads the config file, if found.
 func NewConfig(moduleListFile string, runGoTests bool, outDir, soongOutDir string, availableEnv map[string]string) (Config, error) {
@@ -744,7 +626,8 @@
 // these per device type.
 //
 // NOTE: Do not base conditional logic on this value. It may break product
-//       inheritance.
+//
+//	inheritance.
 func (c *config) DeviceProduct() string {
 	return *c.productVariables.DeviceProduct
 }
@@ -915,6 +798,15 @@
 	return PathForSource(ctx, filepath.Dir(defaultCert))
 }
 
+// Certificate for the NetworkStack sepolicy context
+func (c *config) MainlineSepolicyDevCertificatesDir(ctx ModuleContext) SourcePath {
+	cert := String(c.productVariables.MainlineSepolicyDevCertificates)
+	if cert != "" {
+		return PathForSource(ctx, cert)
+	}
+	return c.DefaultAppCertificateDir(ctx)
+}
+
 // AllowMissingDependencies configures Blueprint/Soong to not fail when modules
 // are configured to depend on non-existent modules. Note that this does not
 // affect missing input dependencies at the Ninja level.
@@ -1737,316 +1629,6 @@
 	return c.productVariables.IgnorePrefer32OnDevice
 }
 
-// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
-// Such lists are used in the build system for things like bootclasspath jars or system server jars.
-// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
-// module name. The pairs come from Make product variables as a list of colon-separated strings.
-//
-// Examples:
-//   - "com.android.art:core-oj"
-//   - "platform:framework"
-//   - "system_ext:foo"
-//
-type ConfiguredJarList struct {
-	// A list of apex components, which can be an apex name,
-	// or special names like "platform" or "system_ext".
-	apexes []string
-
-	// A list of jar module name components.
-	jars []string
-}
-
-// Len returns the length of the list of jars.
-func (l *ConfiguredJarList) Len() int {
-	return len(l.jars)
-}
-
-// Jar returns the idx-th jar component of (apex, jar) pairs.
-func (l *ConfiguredJarList) Jar(idx int) string {
-	return l.jars[idx]
-}
-
-// Apex returns the idx-th apex component of (apex, jar) pairs.
-func (l *ConfiguredJarList) Apex(idx int) string {
-	return l.apexes[idx]
-}
-
-// ContainsJar returns true if the (apex, jar) pairs contains a pair with the
-// given jar module name.
-func (l *ConfiguredJarList) ContainsJar(jar string) bool {
-	return InList(jar, l.jars)
-}
-
-// If the list contains the given (apex, jar) pair.
-func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool {
-	for i := 0; i < l.Len(); i++ {
-		if apex == l.apexes[i] && jar == l.jars[i] {
-			return true
-		}
-	}
-	return false
-}
-
-// ApexOfJar returns the apex component of the first pair with the given jar name on the list, or
-// an empty string if not found.
-func (l *ConfiguredJarList) ApexOfJar(jar string) string {
-	if idx := IndexList(jar, l.jars); idx != -1 {
-		return l.Apex(IndexList(jar, l.jars))
-	}
-	return ""
-}
-
-// IndexOfJar returns the first pair with the given jar name on the list, or -1
-// if not found.
-func (l *ConfiguredJarList) IndexOfJar(jar string) int {
-	return IndexList(jar, l.jars)
-}
-
-func copyAndAppend(list []string, item string) []string {
-	// Create the result list to be 1 longer than the input.
-	result := make([]string, len(list)+1)
-
-	// Copy the whole input list into the result.
-	count := copy(result, list)
-
-	// Insert the extra item at the end.
-	result[count] = item
-
-	return result
-}
-
-// Append an (apex, jar) pair to the list.
-func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
-	// Create a copy of the backing arrays before appending to avoid sharing backing
-	// arrays that are mutated across instances.
-	apexes := copyAndAppend(l.apexes, apex)
-	jars := copyAndAppend(l.jars, jar)
-
-	return ConfiguredJarList{apexes, jars}
-}
-
-// Append a list of (apex, jar) pairs to the list.
-func (l *ConfiguredJarList) AppendList(other *ConfiguredJarList) ConfiguredJarList {
-	apexes := make([]string, 0, l.Len()+other.Len())
-	jars := make([]string, 0, l.Len()+other.Len())
-
-	apexes = append(apexes, l.apexes...)
-	jars = append(jars, l.jars...)
-
-	apexes = append(apexes, other.apexes...)
-	jars = append(jars, other.jars...)
-
-	return ConfiguredJarList{apexes, jars}
-}
-
-// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs.
-func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
-	apexes := make([]string, 0, l.Len())
-	jars := make([]string, 0, l.Len())
-
-	for i, jar := range l.jars {
-		apex := l.apexes[i]
-		if !list.containsApexJarPair(apex, jar) {
-			apexes = append(apexes, apex)
-			jars = append(jars, jar)
-		}
-	}
-
-	return ConfiguredJarList{apexes, jars}
-}
-
-// Filter keeps the entries if a jar appears in the given list of jars to keep. Returns a new list
-// and any remaining jars that are not on this list.
-func (l *ConfiguredJarList) Filter(jarsToKeep []string) (ConfiguredJarList, []string) {
-	var apexes []string
-	var jars []string
-
-	for i, jar := range l.jars {
-		if InList(jar, jarsToKeep) {
-			apexes = append(apexes, l.apexes[i])
-			jars = append(jars, jar)
-		}
-	}
-
-	return ConfiguredJarList{apexes, jars}, RemoveListFromList(jarsToKeep, jars)
-}
-
-// CopyOfJars returns a copy of the list of strings containing jar module name
-// components.
-func (l *ConfiguredJarList) CopyOfJars() []string {
-	return CopyOf(l.jars)
-}
-
-// CopyOfApexJarPairs returns a copy of the list of strings with colon-separated
-// (apex, jar) pairs.
-func (l *ConfiguredJarList) CopyOfApexJarPairs() []string {
-	pairs := make([]string, 0, l.Len())
-
-	for i, jar := range l.jars {
-		apex := l.apexes[i]
-		pairs = append(pairs, apex+":"+jar)
-	}
-
-	return pairs
-}
-
-// BuildPaths returns a list of build paths based on the given directory prefix.
-func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths {
-	paths := make(WritablePaths, l.Len())
-	for i, jar := range l.jars {
-		paths[i] = dir.Join(ctx, ModuleStem(jar)+".jar")
-	}
-	return paths
-}
-
-// BuildPathsByModule returns a map from module name to build paths based on the given directory
-// prefix.
-func (l *ConfiguredJarList) BuildPathsByModule(ctx PathContext, dir OutputPath) map[string]WritablePath {
-	paths := map[string]WritablePath{}
-	for _, jar := range l.jars {
-		paths[jar] = dir.Join(ctx, ModuleStem(jar)+".jar")
-	}
-	return paths
-}
-
-// UnmarshalJSON converts JSON configuration from raw bytes into a
-// ConfiguredJarList structure.
-func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error {
-	// Try and unmarshal into a []string each item of which contains a pair
-	// <apex>:<jar>.
-	var list []string
-	err := json.Unmarshal(b, &list)
-	if err != nil {
-		// Did not work so return
-		return err
-	}
-
-	apexes, jars, err := splitListOfPairsIntoPairOfLists(list)
-	if err != nil {
-		return err
-	}
-	l.apexes = apexes
-	l.jars = jars
-	return nil
-}
-
-func (l *ConfiguredJarList) MarshalJSON() ([]byte, error) {
-	if len(l.apexes) != len(l.jars) {
-		return nil, errors.New(fmt.Sprintf("Inconsistent ConfiguredJarList: apexes: %q, jars: %q", l.apexes, l.jars))
-	}
-
-	list := make([]string, 0, len(l.apexes))
-
-	for i := 0; i < len(l.apexes); i++ {
-		list = append(list, l.apexes[i]+":"+l.jars[i])
-	}
-
-	return json.Marshal(list)
-}
-
-// ModuleStem hardcodes the stem of framework-minus-apex to return "framework".
-//
-// TODO(b/139391334): hard coded until we find a good way to query the stem of a
-// module before any other mutators are run.
-func ModuleStem(module string) string {
-	if module == "framework-minus-apex" {
-		return "framework"
-	}
-	return module
-}
-
-// DevicePaths computes the on-device paths for the list of (apex, jar) pairs,
-// based on the operating system.
-func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string {
-	paths := make([]string, l.Len())
-	for i, jar := range l.jars {
-		apex := l.apexes[i]
-		name := ModuleStem(jar) + ".jar"
-
-		var subdir string
-		if apex == "platform" {
-			subdir = "system/framework"
-		} else if apex == "system_ext" {
-			subdir = "system_ext/framework"
-		} else {
-			subdir = filepath.Join("apex", apex, "javalib")
-		}
-
-		if ostype.Class == Host {
-			paths[i] = filepath.Join(cfg.Getenv("OUT_DIR"), "host", cfg.PrebuiltOS(), subdir, name)
-		} else {
-			paths[i] = filepath.Join("/", subdir, name)
-		}
-	}
-	return paths
-}
-
-func (l *ConfiguredJarList) String() string {
-	var pairs []string
-	for i := 0; i < l.Len(); i++ {
-		pairs = append(pairs, l.apexes[i]+":"+l.jars[i])
-	}
-	return strings.Join(pairs, ",")
-}
-
-func splitListOfPairsIntoPairOfLists(list []string) ([]string, []string, error) {
-	// Now we need to populate this list by splitting each item in the slice of
-	// pairs and appending them to the appropriate list of apexes or jars.
-	apexes := make([]string, len(list))
-	jars := make([]string, len(list))
-
-	for i, apexjar := range list {
-		apex, jar, err := splitConfiguredJarPair(apexjar)
-		if err != nil {
-			return nil, nil, err
-		}
-		apexes[i] = apex
-		jars[i] = jar
-	}
-
-	return apexes, jars, nil
-}
-
-// Expected format for apexJarValue = <apex name>:<jar name>
-func splitConfiguredJarPair(str string) (string, string, error) {
-	pair := strings.SplitN(str, ":", 2)
-	if len(pair) == 2 {
-		apex := pair[0]
-		jar := pair[1]
-		if apex == "" {
-			return apex, jar, fmt.Errorf("invalid apex '%s' in <apex>:<jar> pair '%s', expected format: <apex>:<jar>", apex, str)
-		}
-		return apex, jar, nil
-	} else {
-		return "error-apex", "error-jar", fmt.Errorf("malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
-	}
-}
-
-// CreateTestConfiguredJarList is a function to create ConfiguredJarList for tests.
-func CreateTestConfiguredJarList(list []string) ConfiguredJarList {
-	// Create the ConfiguredJarList in as similar way as it is created at runtime by marshalling to
-	// a json list of strings and then unmarshalling into a ConfiguredJarList instance.
-	b, err := json.Marshal(list)
-	if err != nil {
-		panic(err)
-	}
-
-	var jarList ConfiguredJarList
-	err = json.Unmarshal(b, &jarList)
-	if err != nil {
-		panic(err)
-	}
-
-	return jarList
-}
-
-// EmptyConfiguredJarList returns an empty jar list.
-func EmptyConfiguredJarList() ConfiguredJarList {
-	return ConfiguredJarList{}
-}
-
-var earlyBootJarsKey = NewOnceKey("earlyBootJars")
-
 func (c *config) BootJars() []string {
 	return c.Once(earlyBootJarsKey, func() interface{} {
 		list := c.productVariables.BootJars.CopyOfJars()
diff --git a/android/configured_jars.go b/android/configured_jars.go
new file mode 100644
index 0000000..53fef05
--- /dev/null
+++ b/android/configured_jars.go
@@ -0,0 +1,314 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// 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 android
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"path/filepath"
+	"strings"
+)
+
+// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
+// Such lists are used in the build system for things like bootclasspath jars or system server jars.
+// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
+// module name. The pairs come from Make product variables as a list of colon-separated strings.
+//
+// Examples:
+//   - "com.android.art:core-oj"
+//   - "platform:framework"
+//   - "system_ext:foo"
+type ConfiguredJarList struct {
+	// A list of apex components, which can be an apex name,
+	// or special names like "platform" or "system_ext".
+	apexes []string
+
+	// A list of jar module name components.
+	jars []string
+}
+
+// Len returns the length of the list of jars.
+func (l *ConfiguredJarList) Len() int {
+	return len(l.jars)
+}
+
+// Jar returns the idx-th jar component of (apex, jar) pairs.
+func (l *ConfiguredJarList) Jar(idx int) string {
+	return l.jars[idx]
+}
+
+// Apex returns the idx-th apex component of (apex, jar) pairs.
+func (l *ConfiguredJarList) Apex(idx int) string {
+	return l.apexes[idx]
+}
+
+// ContainsJar returns true if the (apex, jar) pairs contains a pair with the
+// given jar module name.
+func (l *ConfiguredJarList) ContainsJar(jar string) bool {
+	return InList(jar, l.jars)
+}
+
+// If the list contains the given (apex, jar) pair.
+func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool {
+	for i := 0; i < l.Len(); i++ {
+		if apex == l.apexes[i] && jar == l.jars[i] {
+			return true
+		}
+	}
+	return false
+}
+
+// ApexOfJar returns the apex component of the first pair with the given jar name on the list, or
+// an empty string if not found.
+func (l *ConfiguredJarList) ApexOfJar(jar string) string {
+	if idx := IndexList(jar, l.jars); idx != -1 {
+		return l.Apex(IndexList(jar, l.jars))
+	}
+	return ""
+}
+
+// IndexOfJar returns the first pair with the given jar name on the list, or -1
+// if not found.
+func (l *ConfiguredJarList) IndexOfJar(jar string) int {
+	return IndexList(jar, l.jars)
+}
+
+func copyAndAppend(list []string, item string) []string {
+	// Create the result list to be 1 longer than the input.
+	result := make([]string, len(list)+1)
+
+	// Copy the whole input list into the result.
+	count := copy(result, list)
+
+	// Insert the extra item at the end.
+	result[count] = item
+
+	return result
+}
+
+// Append an (apex, jar) pair to the list.
+func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
+	// Create a copy of the backing arrays before appending to avoid sharing backing
+	// arrays that are mutated across instances.
+	apexes := copyAndAppend(l.apexes, apex)
+	jars := copyAndAppend(l.jars, jar)
+
+	return ConfiguredJarList{apexes, jars}
+}
+
+// Append a list of (apex, jar) pairs to the list.
+func (l *ConfiguredJarList) AppendList(other *ConfiguredJarList) ConfiguredJarList {
+	apexes := make([]string, 0, l.Len()+other.Len())
+	jars := make([]string, 0, l.Len()+other.Len())
+
+	apexes = append(apexes, l.apexes...)
+	jars = append(jars, l.jars...)
+
+	apexes = append(apexes, other.apexes...)
+	jars = append(jars, other.jars...)
+
+	return ConfiguredJarList{apexes, jars}
+}
+
+// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs.
+func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
+	apexes := make([]string, 0, l.Len())
+	jars := make([]string, 0, l.Len())
+
+	for i, jar := range l.jars {
+		apex := l.apexes[i]
+		if !list.containsApexJarPair(apex, jar) {
+			apexes = append(apexes, apex)
+			jars = append(jars, jar)
+		}
+	}
+
+	return ConfiguredJarList{apexes, jars}
+}
+
+// Filter keeps the entries if a jar appears in the given list of jars to keep. Returns a new list
+// and any remaining jars that are not on this list.
+func (l *ConfiguredJarList) Filter(jarsToKeep []string) (ConfiguredJarList, []string) {
+	var apexes []string
+	var jars []string
+
+	for i, jar := range l.jars {
+		if InList(jar, jarsToKeep) {
+			apexes = append(apexes, l.apexes[i])
+			jars = append(jars, jar)
+		}
+	}
+
+	return ConfiguredJarList{apexes, jars}, RemoveListFromList(jarsToKeep, jars)
+}
+
+// CopyOfJars returns a copy of the list of strings containing jar module name
+// components.
+func (l *ConfiguredJarList) CopyOfJars() []string {
+	return CopyOf(l.jars)
+}
+
+// CopyOfApexJarPairs returns a copy of the list of strings with colon-separated
+// (apex, jar) pairs.
+func (l *ConfiguredJarList) CopyOfApexJarPairs() []string {
+	pairs := make([]string, 0, l.Len())
+
+	for i, jar := range l.jars {
+		apex := l.apexes[i]
+		pairs = append(pairs, apex+":"+jar)
+	}
+
+	return pairs
+}
+
+// BuildPaths returns a list of build paths based on the given directory prefix.
+func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths {
+	paths := make(WritablePaths, l.Len())
+	for i, jar := range l.jars {
+		paths[i] = dir.Join(ctx, ModuleStem(jar)+".jar")
+	}
+	return paths
+}
+
+// BuildPathsByModule returns a map from module name to build paths based on the given directory
+// prefix.
+func (l *ConfiguredJarList) BuildPathsByModule(ctx PathContext, dir OutputPath) map[string]WritablePath {
+	paths := map[string]WritablePath{}
+	for _, jar := range l.jars {
+		paths[jar] = dir.Join(ctx, ModuleStem(jar)+".jar")
+	}
+	return paths
+}
+
+// UnmarshalJSON converts JSON configuration from raw bytes into a
+// ConfiguredJarList structure.
+func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error {
+	// Try and unmarshal into a []string each item of which contains a pair
+	// <apex>:<jar>.
+	var list []string
+	err := json.Unmarshal(b, &list)
+	if err != nil {
+		// Did not work so return
+		return err
+	}
+
+	apexes, jars, err := splitListOfPairsIntoPairOfLists(list)
+	if err != nil {
+		return err
+	}
+	l.apexes = apexes
+	l.jars = jars
+	return nil
+}
+
+func (l *ConfiguredJarList) MarshalJSON() ([]byte, error) {
+	if len(l.apexes) != len(l.jars) {
+		return nil, errors.New(fmt.Sprintf("Inconsistent ConfiguredJarList: apexes: %q, jars: %q", l.apexes, l.jars))
+	}
+
+	list := make([]string, 0, len(l.apexes))
+
+	for i := 0; i < len(l.apexes); i++ {
+		list = append(list, l.apexes[i]+":"+l.jars[i])
+	}
+
+	return json.Marshal(list)
+}
+
+// ModuleStem hardcodes the stem of framework-minus-apex to return "framework".
+//
+// TODO(b/139391334): hard coded until we find a good way to query the stem of a
+// module before any other mutators are run.
+func ModuleStem(module string) string {
+	if module == "framework-minus-apex" {
+		return "framework"
+	}
+	return module
+}
+
+// DevicePaths computes the on-device paths for the list of (apex, jar) pairs,
+// based on the operating system.
+func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string {
+	paths := make([]string, l.Len())
+	for i, jar := range l.jars {
+		apex := l.apexes[i]
+		name := ModuleStem(jar) + ".jar"
+
+		var subdir string
+		if apex == "platform" {
+			subdir = "system/framework"
+		} else if apex == "system_ext" {
+			subdir = "system_ext/framework"
+		} else {
+			subdir = filepath.Join("apex", apex, "javalib")
+		}
+
+		if ostype.Class == Host {
+			paths[i] = filepath.Join(cfg.Getenv("OUT_DIR"), "host", cfg.PrebuiltOS(), subdir, name)
+		} else {
+			paths[i] = filepath.Join("/", subdir, name)
+		}
+	}
+	return paths
+}
+
+func (l *ConfiguredJarList) String() string {
+	var pairs []string
+	for i := 0; i < l.Len(); i++ {
+		pairs = append(pairs, l.apexes[i]+":"+l.jars[i])
+	}
+	return strings.Join(pairs, ",")
+}
+
+func splitListOfPairsIntoPairOfLists(list []string) ([]string, []string, error) {
+	// Now we need to populate this list by splitting each item in the slice of
+	// pairs and appending them to the appropriate list of apexes or jars.
+	apexes := make([]string, len(list))
+	jars := make([]string, len(list))
+
+	for i, apexjar := range list {
+		apex, jar, err := splitConfiguredJarPair(apexjar)
+		if err != nil {
+			return nil, nil, err
+		}
+		apexes[i] = apex
+		jars[i] = jar
+	}
+
+	return apexes, jars, nil
+}
+
+// Expected format for apexJarValue = <apex name>:<jar name>
+func splitConfiguredJarPair(str string) (string, string, error) {
+	pair := strings.SplitN(str, ":", 2)
+	if len(pair) == 2 {
+		apex := pair[0]
+		jar := pair[1]
+		if apex == "" {
+			return apex, jar, fmt.Errorf("invalid apex '%s' in <apex>:<jar> pair '%s', expected format: <apex>:<jar>", apex, str)
+		}
+		return apex, jar, nil
+	} else {
+		return "error-apex", "error-jar", fmt.Errorf("malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
+	}
+}
+
+// EmptyConfiguredJarList returns an empty jar list.
+func EmptyConfiguredJarList() ConfiguredJarList {
+	return ConfiguredJarList{}
+}
+
+var earlyBootJarsKey = NewOnceKey("earlyBootJars")
diff --git a/android/test_config.go b/android/test_config.go
new file mode 100644
index 0000000..f36e8ba
--- /dev/null
+++ b/android/test_config.go
@@ -0,0 +1,145 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// 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 android
+
+import (
+	"encoding/json"
+	"os"
+	"path/filepath"
+	"runtime"
+
+	"github.com/google/blueprint/proptools"
+)
+
+// TestConfig returns a Config object for testing.
+func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
+	envCopy := make(map[string]string)
+	for k, v := range env {
+		envCopy[k] = v
+	}
+
+	// Copy the real PATH value to the test environment, it's needed by
+	// NonHermeticHostSystemTool() used in x86_darwin_host.go
+	envCopy["PATH"] = os.Getenv("PATH")
+
+	config := &config{
+		productVariables: productVariables{
+			DeviceName:                          stringPtr("test_device"),
+			DeviceProduct:                       stringPtr("test_product"),
+			Platform_sdk_version:                intPtr(30),
+			Platform_sdk_codename:               stringPtr("S"),
+			Platform_base_sdk_extension_version: intPtr(1),
+			Platform_version_active_codenames:   []string{"S", "Tiramisu"},
+			DeviceSystemSdkVersions:             []string{"14", "15"},
+			Platform_systemsdk_versions:         []string{"29", "30"},
+			AAPTConfig:                          []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
+			AAPTPreferredConfig:                 stringPtr("xhdpi"),
+			AAPTCharacteristics:                 stringPtr("nosdcard"),
+			AAPTPrebuiltDPI:                     []string{"xhdpi", "xxhdpi"},
+			UncompressPrivAppDex:                boolPtr(true),
+			ShippingApiLevel:                    stringPtr("30"),
+		},
+
+		outDir:       buildDir,
+		soongOutDir:  filepath.Join(buildDir, "soong"),
+		captureBuild: true,
+		env:          envCopy,
+
+		// Set testAllowNonExistentPaths so that test contexts don't need to specify every path
+		// passed to PathForSource or PathForModuleSrc.
+		TestAllowNonExistentPaths: true,
+
+		BazelContext:              noopBazelContext{},
+		mixedBuildDisabledModules: make(map[string]struct{}),
+		mixedBuildEnabledModules:  make(map[string]struct{}),
+	}
+	config.deviceConfig = &deviceConfig{
+		config: config,
+	}
+	config.TestProductVariables = &config.productVariables
+
+	config.mockFileSystem(bp, fs)
+
+	determineBuildOS(config)
+
+	return Config{config}
+}
+
+func modifyTestConfigToSupportArchMutator(testConfig Config) {
+	config := testConfig.config
+
+	config.Targets = map[OsType][]Target{
+		Android: []Target{
+			{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
+			{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false},
+		},
+		config.BuildOS: []Target{
+			{config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
+			{config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
+		},
+	}
+
+	if runtime.GOOS == "darwin" {
+		config.Targets[config.BuildOS] = config.Targets[config.BuildOS][:1]
+	}
+
+	config.BuildOSTarget = config.Targets[config.BuildOS][0]
+	config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
+	config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
+	config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
+	config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
+	config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a")
+	config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm")
+	config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon")
+}
+
+func modifyTestConfigForMusl(config Config) {
+	delete(config.Targets, config.BuildOS)
+	config.productVariables.HostMusl = boolPtr(true)
+	determineBuildOS(config.config)
+	config.Targets[config.BuildOS] = []Target{
+		{config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
+		{config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
+	}
+
+	config.BuildOSTarget = config.Targets[config.BuildOS][0]
+	config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
+}
+
+// TestArchConfig returns a Config object suitable for using for tests that
+// need to run the arch mutator.
+func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
+	testConfig := TestConfig(buildDir, env, bp, fs)
+	modifyTestConfigToSupportArchMutator(testConfig)
+	return testConfig
+}
+
+// CreateTestConfiguredJarList is a function to create ConfiguredJarList for tests.
+func CreateTestConfiguredJarList(list []string) ConfiguredJarList {
+	// Create the ConfiguredJarList in as similar way as it is created at runtime by marshalling to
+	// a json list of strings and then unmarshalling into a ConfiguredJarList instance.
+	b, err := json.Marshal(list)
+	if err != nil {
+		panic(err)
+	}
+
+	var jarList ConfiguredJarList
+	err = json.Unmarshal(b, &jarList)
+	if err != nil {
+		panic(err)
+	}
+
+	return jarList
+}
diff --git a/android/variable.go b/android/variable.go
index 874b69d..86b8c8f 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -249,7 +249,8 @@
 	AAPTPreferredConfig *string  `json:",omitempty"`
 	AAPTPrebuiltDPI     []string `json:",omitempty"`
 
-	DefaultAppCertificate *string `json:",omitempty"`
+	DefaultAppCertificate           *string `json:",omitempty"`
+	MainlineSepolicyDevCertificates *string `json:",omitempty"`
 
 	AppsDefaultVersionName *string `json:",omitempty"`
 
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 5282941..49a5d2a 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -26,6 +26,7 @@
 	"strings"
 	"testing"
 
+	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
@@ -9544,6 +9545,63 @@
 	}
 }
 
+func TestApexBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
+	bp := `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["libfoo"],
+			min_sdk_version: "29",
+		}
+		apex_key {
+			name: "myapex.key",
+		}
+		cc_library {
+			name: "libfoo",
+			shared_libs: ["libc"],
+			apex_available: ["myapex"],
+			min_sdk_version: "29",
+		}
+		cc_api_library {
+			name: "libc",
+			src: "libc.so",
+			min_sdk_version: "29",
+			recovery_available: true,
+		}
+		api_imports {
+			name: "api_imports",
+			shared_libs: [
+				"libc",
+			],
+			header_libs: [],
+		}
+		`
+	result := testApex(t, bp)
+
+	hasDep := func(m android.Module, wantDep android.Module) bool {
+		t.Helper()
+		var found bool
+		result.VisitDirectDeps(m, func(dep blueprint.Module) {
+			if dep == wantDep {
+				found = true
+			}
+		})
+		return found
+	}
+
+	libfooApexVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex29").Module()
+	libcApexVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared_apex29").Module()
+
+	android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(libfooApexVariant, libcApexVariant))
+
+	// libfoo core variant should be buildable in the same inner tree since
+	// certain mcombo files might build system and apexes in the same inner tree
+	// libfoo core variant should link against source libc
+	libfooCoreVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+	libcCoreVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared").Module()
+	android.AssertBoolEquals(t, "core variant should link against source libc", true, hasDep(libfooCoreVariant, libcCoreVariant))
+}
+
 func TestMain(m *testing.M) {
 	os.Exit(m.Run())
 }
diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go
index 53056c7..5810364 100644
--- a/bazel/aquery_test.go
+++ b/bazel/aquery_test.go
@@ -507,11 +507,14 @@
   "depSetOfFiles": [{
     "id": 1111,
     "directArtifactIds": [3 , 4]
+  }, {
+    "id": 2222,
+    "directArtifactIds": [3]
   }],
   "actions": [{
     "targetId": 100,
     "actionKey": "x",
-    "inputDepSetIds": [1111],
+    "inputDepSetIds": [1111, 2222],
     "mnemonic": "x",
     "arguments": ["bogus", "command"],
     "outputIds": [2],
@@ -527,7 +530,7 @@
   ]
 }`
 	actualBuildStatements, actualDepsets, _ := AqueryBuildStatements([]byte(inputString))
-	if len(actualDepsets) != 1 {
+	if len(actualDepsets) != 2 {
 		t.Errorf("expected 1 depset but found %#v", actualDepsets)
 		return
 	}
diff --git a/cc/cc.go b/cc/cc.go
index fd57e9e..c71fb34 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -31,6 +31,7 @@
 	"android/soong/cc/config"
 	"android/soong/fuzz"
 	"android/soong/genrule"
+	"android/soong/multitree"
 	"android/soong/snapshot"
 )
 
@@ -2183,6 +2184,24 @@
 	}
 }
 
+func GetApiImports(c LinkableInterface, actx android.BottomUpMutatorContext) multitree.ApiImportInfo {
+	apiImportInfo := multitree.ApiImportInfo{}
+
+	if c.Device() {
+		var apiImportModule []blueprint.Module
+		if actx.OtherModuleExists("api_imports") {
+			apiImportModule = actx.AddDependency(c, nil, "api_imports")
+			if len(apiImportModule) > 0 && apiImportModule[0] != nil {
+				apiInfo := actx.OtherModuleProvider(apiImportModule[0], multitree.ApiImportsProvider).(multitree.ApiImportInfo)
+				apiImportInfo = apiInfo
+				actx.SetProvider(multitree.ApiImportsProvider, apiInfo)
+			}
+		}
+	}
+
+	return apiImportInfo
+}
+
 func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo {
 	// Only device modules with BOARD_VNDK_VERSION uses snapshot.  Others use the zero value of
 	// SnapshotInfo, which provides no mappings.
@@ -2208,8 +2227,8 @@
 	return **snapshotInfo
 }
 
-func RewriteSnapshotLib(lib string, snapshotMap map[string]string) string {
-	if snapshot, ok := snapshotMap[lib]; ok {
+func GetReplaceModuleName(lib string, replaceMap map[string]string) string {
+	if snapshot, ok := replaceMap[lib]; ok {
 		return snapshot
 	}
 
@@ -2220,13 +2239,18 @@
 // of names:
 //
 // 1. Name of an NDK library that refers to a prebuilt module.
-//    For each of these, it adds the name of the prebuilt module (which will be in
-//    prebuilts/ndk) to the list of nonvariant libs.
+//
+//	For each of these, it adds the name of the prebuilt module (which will be in
+//	prebuilts/ndk) to the list of nonvariant libs.
+//
 // 2. Name of an NDK library that refers to an ndk_library module.
-//    For each of these, it adds the name of the ndk_library module to the list of
-//    variant libs.
+//
+//	For each of these, it adds the name of the ndk_library module to the list of
+//	variant libs.
+//
 // 3. Anything else (so anything that isn't an NDK library).
-//    It adds these to the nonvariantLibs list.
+//
+//	It adds these to the nonvariantLibs list.
 //
 // The caller can then know to add the variantLibs dependencies differently from the
 // nonvariantLibs
@@ -2238,11 +2262,11 @@
 		// strip #version suffix out
 		name, _ := StubsLibNameAndVersion(entry)
 		if c.InRecovery() {
-			nonvariantLibs = append(nonvariantLibs, RewriteSnapshotLib(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs))
+			nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs))
 		} else if c.UseSdk() && inList(name, *getNDKKnownLibs(config)) {
 			variantLibs = append(variantLibs, name+ndkLibrarySuffix)
 		} else if c.UseVndk() {
-			nonvariantLibs = append(nonvariantLibs, RewriteSnapshotLib(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs))
+			nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs))
 		} else {
 			// put name#version back
 			nonvariantLibs = append(nonvariantLibs, entry)
@@ -2251,6 +2275,25 @@
 	return nonvariantLibs, variantLibs
 }
 
+func updateDepsWithApiImports(deps Deps, apiImports multitree.ApiImportInfo) Deps {
+	for idx, lib := range deps.SharedLibs {
+		deps.SharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs)
+	}
+
+	for idx, lib := range deps.LateSharedLibs {
+		deps.LateSharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs)
+	}
+
+	for idx, lib := range deps.RuntimeLibs {
+		deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs)
+	}
+
+	for idx, lib := range deps.HeaderLibs {
+		deps.HeaderLibs[idx] = GetReplaceModuleName(lib, apiImports.HeaderLibs)
+	}
+	return deps
+}
+
 func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
 	if !c.Enabled() {
 		return
@@ -2266,6 +2309,9 @@
 
 	deps := c.deps(ctx)
 
+	apiImportInfo := GetApiImports(c, actx)
+	deps = updateDepsWithApiImports(deps, apiImportInfo)
+
 	c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs
 
 	var snapshotInfo *SnapshotInfo
@@ -2278,7 +2324,7 @@
 		deps.ReexportSharedLibHeaders, _ = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.ReexportSharedLibHeaders)
 
 		for idx, lib := range deps.RuntimeLibs {
-			deps.RuntimeLibs[idx] = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs)
+			deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs)
 		}
 	}
 
@@ -2288,7 +2334,7 @@
 			depTag.reexportFlags = true
 		}
 
-		lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs)
+		lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs)
 
 		if c.IsStubs() {
 			actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()),
@@ -2301,10 +2347,20 @@
 	if c.isNDKStubLibrary() {
 		// NDK stubs depend on their implementation because the ABI dumps are
 		// generated from the implementation library.
-		actx.AddFarVariationDependencies(append(ctx.Target().Variations(),
-			c.ImageVariation(),
-			blueprint.Variation{Mutator: "link", Variation: "shared"},
-		), stubImplementation, c.BaseModuleName())
+		apiImportName := c.BaseModuleName() + multitree.GetApiImportSuffix()
+
+		// If original library exists as imported API, set dependency on the imported library
+		if actx.OtherModuleExists(apiImportName) {
+			actx.AddFarVariationDependencies(append(ctx.Target().Variations(),
+				c.ImageVariation(),
+				blueprint.Variation{Mutator: "link", Variation: "shared"},
+			), stubImplementation, apiImportName)
+		} else {
+			actx.AddFarVariationDependencies(append(ctx.Target().Variations(),
+				c.ImageVariation(),
+				blueprint.Variation{Mutator: "link", Variation: "shared"},
+			), stubImplementation, c.BaseModuleName())
+		}
 	}
 
 	// sysprop_library has to support both C++ and Java. So sysprop_library internally creates one
@@ -2320,7 +2376,7 @@
 			lib = impl
 		}
 
-		lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
+		lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
 
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
@@ -2340,7 +2396,7 @@
 			lib = impl
 		}
 
-		lib = RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
+		lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
 
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
@@ -2354,7 +2410,7 @@
 		depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true}
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
-		}, depTag, RewriteSnapshotLib(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
+		}, depTag, GetReplaceModuleName(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
 	}
 
 	// shared lib names without the #version suffix
@@ -2386,14 +2442,14 @@
 		depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
-		}, depTag, RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
+		}, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
 	}
 
 	for _, lib := range deps.UnexportedStaticLibs {
 		depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency, unexportedSymbols: true}
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
-		}, depTag, RewriteSnapshotLib(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
+		}, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
 	}
 
 	for _, lib := range deps.LateSharedLibs {
@@ -2434,11 +2490,11 @@
 	actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...)
 	for _, crt := range deps.CrtBegin {
 		actx.AddVariationDependencies(crtVariations, CrtBeginDepTag,
-			RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
+			GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
 	}
 	for _, crt := range deps.CrtEnd {
 		actx.AddVariationDependencies(crtVariations, CrtEndDepTag,
-			RewriteSnapshotLib(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
+			GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
 	}
 	if deps.DynamicLinker != "" {
 		actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker)
@@ -2463,7 +2519,7 @@
 			actx.AddVariationDependencies([]blueprint.Variation{
 				c.ImageVariation(),
 				{Mutator: "link", Variation: "shared"},
-			}, vndkExtDepTag, RewriteSnapshotLib(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs))
+			}, vndkExtDepTag, GetReplaceModuleName(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs))
 		}
 	}
 }
@@ -3185,6 +3241,11 @@
 
 			return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix()
 		}
+
+		// Remove API import suffix if exists
+		if _, ok := ccDepModule.linker.(*apiLibraryDecorator); ok {
+			libName = strings.TrimSuffix(libName, multitree.GetApiImportSuffix())
+		}
 	}
 
 	if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() &&
@@ -3520,6 +3581,10 @@
 	if _, ok := c.linker.(prebuiltLinkerInterface); ok {
 		return nil
 	}
+	if _, ok := c.linker.(*apiLibraryDecorator); ok {
+		return nil
+	}
+
 	minSdkVersion := c.MinSdkVersion()
 	if minSdkVersion == "apex_inherit" {
 		return nil
@@ -3637,9 +3702,7 @@
 	}
 }
 
-//
 // Defaults
-//
 type Defaults struct {
 	android.ModuleBase
 	android.DefaultsModuleBase
diff --git a/cc/config/global.go b/cc/config/global.go
index 357ea44..4fcef9d 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -290,7 +290,11 @@
 		"-Wno-deprecated-non-prototype",
 	}
 
-	llvmNextExtraCommonGlobalCflags = []string{}
+	llvmNextExtraCommonGlobalCflags = []string{
+		"-Wno-error=array-parameter",     // http://b/241941550
+		"-Wno-error=deprecated-builtins", // http://b/241601211
+		"-Wno-error=deprecated",          // in external/googletest/googletest
+	}
 
 	IllegalFlags = []string{
 		"-w",
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index 674edad..232e686 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -37,16 +37,22 @@
 		// http://b/216364337 - TODO: Follow-up after compiler update to
 		// disable or fix individual instances.
 		"-cert-err33-c",
+		// http://b/241125373
+		"-bugprone-unchecked-optional-access",
 	}
 
 	// Some clang-tidy checks are included in some tidy_checks_as_errors lists,
 	// but not all warnings are fixed/suppressed yet. These checks are not
 	// disabled in the TidyGlobalNoChecks list, so we can see them and fix/suppress them.
 	globalNoErrorCheckList = []string{
-		// http://b/155034563
-		"-bugprone-signed-char-misuse",
+		// http://b/241997913
+		"-bugprone-assignment-in-if-condition",
 		// http://b/155034972
 		"-bugprone-branch-clone",
+		// http://b/155034563
+		"-bugprone-signed-char-misuse",
+		// http://b/241819232
+		"-misc-const-correctness",
 	}
 )
 
@@ -80,8 +86,10 @@
 			"misc-*",
 			"performance-*",
 			"portability-*",
+			"-bugprone-assignment-in-if-condition",
 			"-bugprone-easily-swappable-parameters",
 			"-bugprone-narrowing-conversions",
+			"-misc-const-correctness",
 			"-misc-no-recursion",
 			"-misc-non-private-member-variables-in-classes",
 			"-misc-unused-parameters",
diff --git a/cc/library_stub.go b/cc/library_stub.go
index 4d0148d..14d1b96 100644
--- a/cc/library_stub.go
+++ b/cc/library_stub.go
@@ -17,6 +17,7 @@
 import (
 	"android/soong/android"
 	"android/soong/multitree"
+	"strings"
 )
 
 func init() {
@@ -25,10 +26,96 @@
 
 func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) {
 	// cc_api_stub_library shares a lot of ndk_library, and this will be refactored later
+	ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory)
 	ctx.RegisterModuleType("cc_api_stub_library", CcApiStubLibraryFactory)
 	ctx.RegisterModuleType("cc_api_contribution", CcApiContributionFactory)
 }
 
+// 'cc_api_library' is a module type which is from the exported API surface
+// with C shared library type. The module will replace original module, and
+// offer a link to the module that generates shared library object from the
+// map file.
+type apiLibraryProperties struct {
+	Src *string `android:"arch_variant"`
+}
+
+type apiLibraryDecorator struct {
+	*libraryDecorator
+	properties apiLibraryProperties
+}
+
+func CcApiLibraryFactory() android.Module {
+	module, decorator := NewLibrary(android.DeviceSupported)
+	apiLibraryDecorator := &apiLibraryDecorator{
+		libraryDecorator: decorator,
+	}
+	apiLibraryDecorator.BuildOnlyShared()
+
+	module.stl = nil
+	module.sanitize = nil
+	decorator.disableStripping()
+
+	module.compiler = nil
+	module.linker = apiLibraryDecorator
+	module.installer = nil
+	module.AddProperties(&module.Properties, &apiLibraryDecorator.properties)
+
+	// Mark module as stub, so APEX would not include this stub in the package.
+	module.library.setBuildStubs(true)
+
+	// Prevent default system libs (libc, libm, and libdl) from being linked
+	if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil {
+		apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{}
+	}
+
+	module.Init()
+
+	return module
+}
+
+func (d *apiLibraryDecorator) Name(basename string) string {
+	return basename + multitree.GetApiImportSuffix()
+}
+
+func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
+	// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
+	d.libraryDecorator.flagExporter.exportIncludes(ctx)
+	d.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
+	d.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
+	d.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
+	d.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
+	d.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
+	d.libraryDecorator.flagExporter.setProvider(ctx)
+
+	in := android.PathForModuleSrc(ctx, *d.properties.Src)
+
+	d.unstrippedOutputFile = in
+	libName := d.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
+
+	tocFile := android.PathForModuleOut(ctx, libName+".toc")
+	d.tocFile = android.OptionalPathForPath(tocFile)
+	TransformSharedObjectToToc(ctx, in, tocFile)
+
+	ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
+		SharedLibrary: in,
+		Target:        ctx.Target(),
+
+		TableOfContents: d.tocFile,
+	})
+
+	return in
+}
+
+func (d *apiLibraryDecorator) availableFor(what string) bool {
+	// Stub from API surface should be available for any APEX.
+	return true
+}
+
+func (d *apiLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
+	d.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), multitree.GetApiImportSuffix())
+	return d.libraryDecorator.linkerFlags(ctx, flags)
+}
+
 func CcApiStubLibraryFactory() android.Module {
 	module, decorator := NewLibrary(android.DeviceSupported)
 	apiStubDecorator := &apiStubDecorator{
diff --git a/cc/library_stub_test.go b/cc/library_stub_test.go
index 15b56d2..c2ac941 100644
--- a/cc/library_stub_test.go
+++ b/cc/library_stub_test.go
@@ -22,6 +22,8 @@
 
 	"android/soong/android"
 	"android/soong/multitree"
+
+	"github.com/google/blueprint"
 )
 
 func TestCcApiStubLibraryOutputFiles(t *testing.T) {
@@ -106,3 +108,111 @@
 	android.AssertStringEquals(t, "name", "foo.mysdk", api_surface_gen_rule_args["name"])
 	android.AssertStringEquals(t, "symbol_file", "foo.map.txt", api_surface_gen_rule_args["symbol_file"])*/
 }
+
+func hasDirectDependency(t *testing.T, ctx *android.TestResult, from android.Module, to android.Module) bool {
+	t.Helper()
+	var found bool
+	ctx.VisitDirectDeps(from, func(dep blueprint.Module) {
+		if dep == to {
+			found = true
+		}
+	})
+	return found
+}
+
+func TestApiLibraryReplacesExistingModule(t *testing.T) {
+	bp := `
+		cc_library {
+			name: "libfoo",
+			shared_libs: ["libbar"],
+		}
+
+		cc_library {
+			name: "libbar",
+		}
+
+		cc_api_library {
+			name: "libbar",
+			src: "libbar.so",
+		}
+
+		api_imports {
+			name: "api_imports",
+			shared_libs: [
+				"libbar",
+			],
+			header_libs: [],
+		}
+	`
+
+	ctx := prepareForCcTest.RunTestWithBp(t, bp)
+
+	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+	libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
+	libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+
+	android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbar))
+	android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
+}
+
+func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) {
+	bp := `
+		cc_library {
+			name: "libfoo",
+			shared_libs: ["libbar"],
+		}
+
+		cc_api_library {
+			name: "libbar",
+			src: "libbar.so",
+		}
+
+		api_imports {
+			name: "api_imports",
+			shared_libs: [
+				"libbar",
+			],
+			header_libs: [],
+		}
+	`
+
+	ctx := prepareForCcTest.RunTestWithBp(t, bp)
+
+	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+	libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+
+	android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
+}
+
+func TestApiLibraryShouldNotReplaceWithoutApiImport(t *testing.T) {
+	bp := `
+		cc_library {
+			name: "libfoo",
+			shared_libs: ["libbar"],
+		}
+
+		cc_library {
+			name: "libbar",
+		}
+
+		cc_api_library {
+			name: "libbar",
+			src: "libbar.so",
+		}
+
+		api_imports {
+			name: "api_imports",
+			shared_libs: [],
+			header_libs: [],
+		}
+	`
+
+	ctx := prepareForCcTest.RunTestWithBp(t, bp)
+
+	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
+	libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
+	libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+
+	android.AssertBoolEquals(t, "original library should be linked", true, hasDirectDependency(t, ctx, libfoo, libbar))
+	android.AssertBoolEquals(t, "Stub library from API surface should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
+}
diff --git a/cc/testing.go b/cc/testing.go
index 79ae3c3..44a865d 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -20,6 +20,7 @@
 
 	"android/soong/android"
 	"android/soong/genrule"
+	"android/soong/multitree"
 	"android/soong/snapshot"
 )
 
@@ -31,6 +32,8 @@
 	RegisterLibraryHeadersBuildComponents(ctx)
 	RegisterLibraryStubBuildComponents(ctx)
 
+	multitree.RegisterApiImportsModule(ctx)
+
 	ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory)
 	ctx.RegisterModuleType("cc_object", ObjectFactory)
 	ctx.RegisterModuleType("cc_genrule", GenRuleFactory)
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 16f994d..cb85634 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -66,11 +66,9 @@
 	{
 		flag:        "--make-mode",
 		description: "build the modules by the target name (i.e. soong_docs)",
-		config: func(ctx build.Context, args ...string) build.Config {
-			return build.NewConfig(ctx, args...)
-		},
-		stdio: stdio,
-		run:   runMake,
+		config:      build.NewConfig,
+		stdio:       stdio,
+		run:         runMake,
 	}, {
 		flag:         "--dumpvar-mode",
 		description:  "print the value of the legacy make variable VAR to stdout",
@@ -114,7 +112,7 @@
 
 // Main execution of soong_ui. The command format is as follows:
 //
-//    soong_ui <command> [<arg 1> <arg 2> ... <arg n>]
+//	soong_ui <command> [<arg 1> <arg 2> ... <arg n>]
 //
 // Command is the type of soong_ui execution. Only one type of
 // execution is specified. The args are specific to the command.
@@ -270,6 +268,8 @@
 
 func dumpVar(ctx build.Context, config build.Config, args []string, _ string) {
 	flags := flag.NewFlagSet("dumpvar", flag.ExitOnError)
+	flags.SetOutput(ctx.Writer)
+
 	flags.Usage = func() {
 		fmt.Fprintf(ctx.Writer, "usage: %s --dumpvar-mode [--abs] <VAR>\n\n", os.Args[0])
 		fmt.Fprintln(ctx.Writer, "In dumpvar mode, print the value of the legacy make variable VAR to stdout")
@@ -320,6 +320,8 @@
 
 func dumpVars(ctx build.Context, config build.Config, args []string, _ string) {
 	flags := flag.NewFlagSet("dumpvars", flag.ExitOnError)
+	flags.SetOutput(ctx.Writer)
+
 	flags.Usage = func() {
 		fmt.Fprintf(ctx.Writer, "usage: %s --dumpvars-mode [--vars=\"VAR VAR ...\"]\n\n", os.Args[0])
 		fmt.Fprintln(ctx.Writer, "In dumpvars mode, dump the values of one or more legacy make variables, in")
@@ -403,6 +405,8 @@
 
 func buildActionConfig(ctx build.Context, args ...string) build.Config {
 	flags := flag.NewFlagSet("build-mode", flag.ContinueOnError)
+	flags.SetOutput(ctx.Writer)
+
 	flags.Usage = func() {
 		fmt.Fprintf(ctx.Writer, "usage: %s --build-mode --dir=<path> <build action> [<build arg 1> <build arg 2> ...]\n\n", os.Args[0])
 		fmt.Fprintln(ctx.Writer, "In build mode, build the set of modules based on the specified build")
@@ -455,21 +459,32 @@
 	const numBuildActionFlags = 2
 	if len(args) < numBuildActionFlags {
 		flags.Usage()
-		ctx.Fatalln("Improper build action arguments.")
+		ctx.Fatalln("Improper build action arguments: too few arguments")
 	}
-	flags.Parse(args[0:numBuildActionFlags])
+	parseError := flags.Parse(args[0:numBuildActionFlags])
 
 	// The next block of code is to validate that exactly one build action is set and the dir flag
 	// is specified.
-	buildActionCount := 0
+	buildActionFound := false
 	var buildAction build.BuildAction
-	for _, flag := range buildActionFlags {
-		if flag.set {
-			buildActionCount++
-			buildAction = flag.action
+	for _, f := range buildActionFlags {
+		if f.set {
+			if buildActionFound {
+				if parseError == nil {
+					//otherwise Parse() already called Usage()
+					flags.Usage()
+				}
+				ctx.Fatalf("Build action already specified, omit: --%s\n", f.name)
+			}
+			buildActionFound = true
+			buildAction = f.action
 		}
 	}
-	if buildActionCount != 1 {
+	if !buildActionFound {
+		if parseError == nil {
+			//otherwise Parse() already called Usage()
+			flags.Usage()
+		}
 		ctx.Fatalln("Build action not defined.")
 	}
 	if *dir == "" {
@@ -491,11 +506,7 @@
 		fmt.Fprintln(writer, "!")
 		fmt.Fprintln(writer, "! Older versions are saved in verbose.log.#.gz files")
 		fmt.Fprintln(writer, "")
-		select {
-		case <-time.After(5 * time.Second):
-		case <-ctx.Done():
-			return
-		}
+		ctx.Fatal("done")
 	}
 
 	if _, ok := config.Environment().Get("ONE_SHOT_MAKEFILE"); ok {
@@ -515,8 +526,16 @@
 // getCommand finds the appropriate command based on args[1] flag. args[0]
 // is the soong_ui filename.
 func getCommand(args []string) (*command, []string, error) {
+	listFlags := func() []string {
+		flags := make([]string, len(commands))
+		for i, c := range commands {
+			flags[i] = c.flag
+		}
+		return flags
+	}
+
 	if len(args) < 2 {
-		return nil, nil, fmt.Errorf("Too few arguments: %q", args)
+		return nil, nil, fmt.Errorf("Too few arguments: %q\nUse one of these: %q", args, listFlags())
 	}
 
 	for _, c := range commands {
@@ -524,13 +543,7 @@
 			return &c, args[2:], nil
 		}
 	}
-
-	// command not found
-	flags := make([]string, len(commands))
-	for i, c := range commands {
-		flags[i] = c.flag
-	}
-	return nil, nil, fmt.Errorf("Command not found: %q\nDid you mean one of these: %q", args, flags)
+	return nil, nil, fmt.Errorf("Command not found: %q\nDid you mean one of these: %q", args[1], listFlags())
 }
 
 // For Bazel support, this moves files and directories from e.g. out/dist/$f to DIST_DIR/$f if necessary.
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 64cd46a..eefda19 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -522,7 +522,7 @@
 	return &GlobalSoongConfig{
 		Profman:          ctx.Config().HostToolPath(ctx, "profman"),
 		Dex2oat:          dex2oatPathFromDep(ctx),
-		Aapt:             ctx.Config().HostToolPath(ctx, "aapt"),
+		Aapt:             ctx.Config().HostToolPath(ctx, "aapt2"),
 		SoongZip:         ctx.Config().HostToolPath(ctx, "soong_zip"),
 		Zip2zip:          ctx.Config().HostToolPath(ctx, "zip2zip"),
 		ManifestCheck:    ctx.Config().HostToolPath(ctx, "manifest_check"),
@@ -724,7 +724,7 @@
 	return &GlobalSoongConfig{
 		Profman:          android.PathForTesting("profman"),
 		Dex2oat:          android.PathForTesting("dex2oat"),
-		Aapt:             android.PathForTesting("aapt"),
+		Aapt:             android.PathForTesting("aapt2"),
 		SoongZip:         android.PathForTesting("soong_zip"),
 		Zip2zip:          android.PathForTesting("zip2zip"),
 		ManifestCheck:    android.PathForTesting("manifest_check"),
diff --git a/java/app.go b/java/app.go
index 7b5efc7..3c8fcd3 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1377,7 +1377,7 @@
 		Flag("--enforce-uses-libraries").
 		Input(inputFile).
 		FlagWithOutput("--enforce-uses-libraries-status ", statusFile).
-		FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt"))
+		FlagWithInput("--aapt ", ctx.Config().HostToolPath(ctx, "aapt2"))
 
 	if outputFile != nil {
 		cmd.FlagWithOutput("-o ", outputFile)
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index e99cb05..01e7e6e 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -101,7 +101,6 @@
 --warning_check WrongViewCast                      # 1 occurences in 1 modules
 
 --warning_check CoarseFineLocation
---warning_check ExtraText
 --warning_check IntentFilterExportedReceiver
 --warning_check MissingInflatedId
 --warning_check NotificationPermission
diff --git a/multitree/Android.bp b/multitree/Android.bp
index 9b16d20..78c4962 100644
--- a/multitree/Android.bp
+++ b/multitree/Android.bp
@@ -10,6 +10,7 @@
         "soong-android",
     ],
     srcs: [
+        "api_imports.go",
         "api_surface.go",
         "export.go",
         "metadata.go",
diff --git a/multitree/api_imports.go b/multitree/api_imports.go
new file mode 100644
index 0000000..2c4cf80
--- /dev/null
+++ b/multitree/api_imports.go
@@ -0,0 +1,88 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// 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 multitree
+
+import (
+	"android/soong/android"
+
+	"github.com/google/blueprint"
+)
+
+var (
+	apiImportNameSuffix = ".apiimport"
+)
+
+func init() {
+	RegisterApiImportsModule(android.InitRegistrationContext)
+}
+
+func RegisterApiImportsModule(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("api_imports", apiImportsFactory)
+}
+
+type ApiImports struct {
+	android.ModuleBase
+	properties apiImportsProperties
+}
+
+type apiImportsProperties struct {
+	Shared_libs []string // List of C shared libraries from API surfaces
+	Header_libs []string // List of C header libraries from API surfaces
+}
+
+// 'api_imports' is a module which describes modules available from API surfaces.
+// This module is required to get the list of all imported API modules, because
+// it is discouraged to loop and fetch all modules from its type information. The
+// only module with name 'api_imports' will be used from the build.
+func apiImportsFactory() android.Module {
+	module := &ApiImports{}
+	module.AddProperties(&module.properties)
+	android.InitAndroidModule(module)
+	return module
+}
+
+func (imports *ApiImports) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	// ApiImport module does not generate any build actions
+}
+
+type ApiImportInfo struct {
+	SharedLibs, HeaderLibs map[string]string
+}
+
+var ApiImportsProvider = blueprint.NewMutatorProvider(ApiImportInfo{}, "deps")
+
+// Store module lists into ApiImportInfo and share it over mutator provider.
+func (imports *ApiImports) DepsMutator(ctx android.BottomUpMutatorContext) {
+	generateNameMapWithSuffix := func(names []string) map[string]string {
+		moduleNameMap := make(map[string]string)
+		for _, name := range names {
+			moduleNameMap[name] = name + apiImportNameSuffix
+		}
+
+		return moduleNameMap
+	}
+
+	sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs)
+	headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs)
+
+	ctx.SetProvider(ApiImportsProvider, ApiImportInfo{
+		SharedLibs: sharedLibs,
+		HeaderLibs: headerLibs,
+	})
+}
+
+func GetApiImportSuffix() string {
+	return apiImportNameSuffix
+}
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 72cc894..0199d3a 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -299,7 +299,15 @@
 		ClangProperties:    cc.RustBindgenClangProperties{},
 	}
 
-	module := NewSourceProviderModule(hod, bindgen, false)
+	module := NewSourceProviderModule(hod, bindgen, false, true)
+
+	android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+		type stub_props struct {
+			Visibility []string
+		}
+		props := &stub_props{[]string{":__subpackages__"}}
+		ctx.PrependProperties(props)
+	})
 
 	return module, bindgen
 }
diff --git a/rust/protobuf.go b/rust/protobuf.go
index 9fe27c4c..88e80fe 100644
--- a/rust/protobuf.go
+++ b/rust/protobuf.go
@@ -238,7 +238,7 @@
 		Properties:         ProtobufProperties{},
 	}
 
-	module := NewSourceProviderModule(hod, protobuf, false)
+	module := NewSourceProviderModule(hod, protobuf, false, false)
 
 	return module, protobuf
 }
diff --git a/rust/rust.go b/rust/rust.go
index 4d9fe4c..1517e62 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1373,6 +1373,11 @@
 	var commonDepVariations []blueprint.Variation
 	var snapshotInfo *cc.SnapshotInfo
 
+	apiImportInfo := cc.GetApiImports(mod, actx)
+	for idx, lib := range deps.SharedLibs {
+		deps.SharedLibs[idx] = cc.GetReplaceModuleName(lib, apiImportInfo.SharedLibs)
+	}
+
 	if ctx.Os() == android.Android {
 		deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs)
 	}
@@ -1393,7 +1398,7 @@
 	rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation})
 	for _, lib := range deps.Rlibs {
 		depTag := rlibDepTag
-		lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+		lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
 
 		actx.AddVariationDependencies(rlibDepVariations, depTag, lib)
 	}
@@ -1431,7 +1436,7 @@
 		if mod.compiler.stdLinkage(ctx) == RlibLinkage {
 			for _, lib := range deps.Stdlibs {
 				depTag := rlibDepTag
-				lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+				lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
 
 				actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
 					depTag, lib)
@@ -1455,7 +1460,7 @@
 
 	for _, lib := range deps.WholeStaticLibs {
 		depTag := cc.StaticDepTag(true)
-		lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
+		lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
 
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
@@ -1464,7 +1469,7 @@
 
 	for _, lib := range deps.StaticLibs {
 		depTag := cc.StaticDepTag(false)
-		lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
+		lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
 
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
@@ -1476,11 +1481,11 @@
 	crtVariations := cc.GetCrtVariations(ctx, mod)
 	for _, crt := range deps.CrtBegin {
 		actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag,
-			cc.RewriteSnapshotLib(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
+			cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
 	}
 	for _, crt := range deps.CrtEnd {
 		actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag,
-			cc.RewriteSnapshotLib(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
+			cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
 	}
 
 	if mod.sourceProvider != nil {
@@ -1503,7 +1508,7 @@
 
 // addRlibDependency will add an rlib dependency, rewriting to the snapshot library if available.
 func addRlibDependency(actx android.BottomUpMutatorContext, lib string, mod *Module, snapshotInfo *cc.SnapshotInfo, variations []blueprint.Variation) {
-	lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+	lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
 	actx.AddVariationDependencies(variations, rlibDepTag, lib)
 }
 
diff --git a/rust/source_provider.go b/rust/source_provider.go
index 7719611..4f8d22b 100644
--- a/rust/source_provider.go
+++ b/rust/source_provider.go
@@ -65,9 +65,12 @@
 	}
 }
 
-func NewSourceProviderModule(hod android.HostOrDeviceSupported, sourceProvider SourceProvider, enableLints bool) *Module {
+func NewSourceProviderModule(hod android.HostOrDeviceSupported, sourceProvider SourceProvider, enableLints bool, rlibOnly bool) *Module {
 	_, library := NewRustLibrary(hod)
 	library.BuildOnlyRust()
+	if rlibOnly {
+		library.BuildOnlyRlib()
+	}
 	library.sourceProvider = sourceProvider
 
 	module := newModule(hod, android.MultilibBoth)
diff --git a/ui/build/build.go b/ui/build/build.go
index 5b80b4d..f7a2d7b 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -201,7 +201,20 @@
 	buildLock := BecomeSingletonOrFail(ctx, config)
 	defer buildLock.Unlock()
 
+	logArgsOtherThan := func(specialTargets ...string) {
+		var ignored []string
+		for _, a := range config.Arguments() {
+			if !inList(a, specialTargets) {
+				ignored = append(ignored, a)
+			}
+		}
+		if len(ignored) > 0 {
+			ctx.Printf("ignoring arguments %q", ignored)
+		}
+	}
+
 	if inList("clean", config.Arguments()) || inList("clobber", config.Arguments()) {
+		logArgsOtherThan("clean", "clobber")
 		clean(ctx, config)
 		return
 	}
@@ -279,6 +292,7 @@
 
 	if inList("installclean", config.Arguments()) ||
 		inList("install-clean", config.Arguments()) {
+		logArgsOtherThan("installclean", "install-clean")
 		installClean(ctx, config)
 		ctx.Println("Deleted images and staging directories.")
 		return
@@ -286,6 +300,7 @@
 
 	if inList("dataclean", config.Arguments()) ||
 		inList("data-clean", config.Arguments()) {
+		logArgsOtherThan("dataclean", "data-clean")
 		dataClean(ctx, config)
 		ctx.Println("Deleted data files.")
 		return
diff --git a/ui/build/soong.go b/ui/build/soong.go
index cfcf990..29c3b65 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -312,14 +312,6 @@
 		fmt.Sprintf("generating Soong docs at %s", config.SoongDocsHtml()),
 	)
 
-	globFiles := []string{
-		config.NamedGlobFile(soongBuildTag),
-		config.NamedGlobFile(bp2buildTag),
-		config.NamedGlobFile(jsonModuleGraphTag),
-		config.NamedGlobFile(queryviewTag),
-		config.NamedGlobFile(soongDocsTag),
-	}
-
 	// The glob .ninja files are subninja'd. However, they are generated during
 	// the build itself so we write an empty file if the file does not exist yet
 	// so that the subninja doesn't fail on clean builds
@@ -342,7 +334,7 @@
 		runGoTests:  !config.skipSoongTests,
 		// If we want to debug soong_build, we need to compile it for debugging
 		debugCompilation: os.Getenv("SOONG_DELVE") != "",
-		subninjas:        globFiles,
+		subninjas:        bootstrapGlobFileList(config),
 		primaryBuilderInvocations: []bootstrap.PrimaryBuilderInvocation{
 			mainSoongBuildInvocation,
 			bp2buildInvocation,