Merge "Save compilation units in protobuf format."
diff --git a/android/apex.go b/android/apex.go
index 8482dc2..0b901ae 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -144,9 +144,9 @@
 
 func CheckAvailableForApex(what string, apex_available []string) bool {
 	if len(apex_available) == 0 {
-		// apex_available defaults to ["//apex_available:platform", "//apex_available:anyapex"],
-		// which means 'available to everybody'.
-		return true
+		// apex_available defaults to ["//apex_available:platform"],
+		// which means 'available to the platform but no apexes'.
+		return what == AvailableToPlatform
 	}
 	return InList(what, apex_available) ||
 		(what != AvailableToPlatform && InList(availableToAnyApex, apex_available))
diff --git a/android/package.go b/android/package.go
index ed604c6..077c4a4 100644
--- a/android/package.go
+++ b/android/package.go
@@ -22,7 +22,19 @@
 )
 
 func init() {
-	RegisterModuleType("package", PackageFactory)
+	RegisterPackageBuildComponents(InitRegistrationContext)
+}
+
+// Register the package module type and supporting mutators.
+//
+// This must be called in the correct order (relative to other methods that also
+// register mutators) to match the order of mutator registration in mutator.go.
+// Failing to do so will result in an unrealistic test environment.
+func RegisterPackageBuildComponents(ctx RegistrationContext) {
+	ctx.RegisterModuleType("package", PackageFactory)
+
+	// Register mutators that are hard coded in to mutator.go.
+	ctx.HardCodedPreArchMutators(RegisterPackageRenamer)
 }
 
 // The information maintained about each package.
diff --git a/android/package_test.go b/android/package_test.go
index bc66928..4710e39 100644
--- a/android/package_test.go
+++ b/android/package_test.go
@@ -87,8 +87,7 @@
 	config := TestArchConfig(buildDir, nil, "", fs)
 
 	ctx := NewTestArchContext()
-	ctx.RegisterModuleType("package", PackageFactory)
-	ctx.PreArchMutators(RegisterPackageRenamer)
+	RegisterPackageBuildComponents(ctx)
 	ctx.Register(config)
 
 	_, errs := ctx.ParseBlueprintsFiles(".")
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 2c99f1f..c780cb2 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -36,6 +36,9 @@
 
 var PrebuiltDepTag prebuiltDependencyTag
 
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+func (t prebuiltDependencyTag) ExcludeFromVisibilityEnforcement() {}
+
 type PrebuiltProperties struct {
 	// When prefer is set to true the prebuilt will be used instead of any source module with
 	// a matching name.
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 8648b93..8ff5c40 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -141,10 +141,8 @@
 			config := TestConfig(buildDir, nil, bp, fs)
 
 			ctx := NewTestContext()
-			RegisterPrebuiltMutators(ctx)
+			registerTestPrebuiltBuildComponents(ctx)
 			ctx.RegisterModuleType("filegroup", FileGroupFactory)
-			ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
-			ctx.RegisterModuleType("source", newSourceModule)
 			ctx.Register(config)
 
 			_, errs := ctx.ParseBlueprintsFiles("Android.bp")
@@ -212,6 +210,13 @@
 	}
 }
 
+func registerTestPrebuiltBuildComponents(ctx RegistrationContext) {
+	ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
+	ctx.RegisterModuleType("source", newSourceModule)
+
+	RegisterPrebuiltMutators(ctx)
+}
+
 type prebuiltModule struct {
 	ModuleBase
 	prebuilt   Prebuilt
diff --git a/android/register.go b/android/register.go
index b48d3d1..d5aa1a5 100644
--- a/android/register.go
+++ b/android/register.go
@@ -127,6 +127,12 @@
 	RegisterModuleType(name string, factory ModuleFactory)
 	RegisterSingletonType(name string, factory SingletonFactory)
 	PreArchMutators(f RegisterMutatorFunc)
+
+	// Register pre arch mutators that are hard coded into mutator.go.
+	//
+	// Only registers mutators for testing, is a noop on the InitRegistrationContext.
+	HardCodedPreArchMutators(f RegisterMutatorFunc)
+
 	PreDepsMutators(f RegisterMutatorFunc)
 	PostDepsMutators(f RegisterMutatorFunc)
 }
@@ -180,6 +186,10 @@
 	PreArchMutators(f)
 }
 
+func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
+	// Nothing to do as the mutators are hard code in preArch in mutator.go
+}
+
 func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
 	PreDepsMutators(f)
 }
diff --git a/android/testing.go b/android/testing.go
index 6663728..c07af7f 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -59,6 +59,11 @@
 	ctx.preArch = append(ctx.preArch, f)
 }
 
+func (ctx *TestContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
+	// Register mutator function as normal for testing.
+	ctx.PreArchMutators(f)
+}
+
 func (ctx *TestContext) PreDepsMutators(f RegisterMutatorFunc) {
 	ctx.preDeps = append(ctx.preDeps, f)
 }
diff --git a/android/visibility.go b/android/visibility.go
index c28ec93..a597687 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -19,6 +19,8 @@
 	"regexp"
 	"strings"
 	"sync"
+
+	"github.com/google/blueprint"
 )
 
 // Enforces visibility rules between modules.
@@ -190,6 +192,15 @@
 	}).(*sync.Map)
 }
 
+// Marker interface that identifies dependencies that are excluded from visibility
+// enforcement.
+type ExcludeFromVisibilityEnforcementTag interface {
+	blueprint.DependencyTag
+
+	// Method that differentiates this interface from others.
+	ExcludeFromVisibilityEnforcement()
+}
+
 // The rule checker needs to be registered before defaults expansion to correctly check that
 // //visibility:xxx isn't combined with other packages in the same list in any one module.
 func RegisterVisibilityRuleChecker(ctx RegisterMutatorsContext) {
@@ -389,6 +400,12 @@
 
 	// Visit all the dependencies making sure that this module has access to them all.
 	ctx.VisitDirectDeps(func(dep Module) {
+		// Ignore dependencies that have an ExcludeFromVisibilityEnforcementTag
+		tag := ctx.OtherModuleDependencyTag(dep)
+		if _, ok := tag.(ExcludeFromVisibilityEnforcementTag); ok {
+			return
+		}
+
 		depName := ctx.OtherModuleName(dep)
 		depDir := ctx.OtherModuleDir(dep)
 		depQualified := qualifiedModuleName{depDir, depName}
diff --git a/android/visibility_test.go b/android/visibility_test.go
index fbf2fb7..6006072 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -853,6 +853,51 @@
 				` not visible to this module`,
 		},
 	},
+	{
+		name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
+		fs: map[string][]byte{
+			"prebuilts/Blueprints": []byte(`
+				prebuilt {
+					name: "module",
+					visibility: ["//top/other"],
+				}`),
+			"top/sources/source_file": nil,
+			"top/sources/Blueprints": []byte(`
+				source {
+					name: "module",
+					visibility: ["//top/other"],
+				}`),
+			"top/other/source_file": nil,
+			"top/other/Blueprints": []byte(`
+				source {
+					name: "other",
+					deps: [":module"],
+				}`),
+		},
+	},
+	{
+		name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
+		fs: map[string][]byte{
+			"prebuilts/Blueprints": []byte(`
+				prebuilt {
+					name: "module",
+					visibility: ["//top/other"],
+					prefer: true,
+				}`),
+			"top/sources/source_file": nil,
+			"top/sources/Blueprints": []byte(`
+				source {
+					name: "module",
+					visibility: ["//top/other"],
+				}`),
+			"top/other/source_file": nil,
+			"top/other/Blueprints": []byte(`
+				source {
+					name: "other",
+					deps: [":module"],
+				}`),
+		},
+	},
 }
 
 func TestVisibility(t *testing.T) {
@@ -871,10 +916,12 @@
 	config := TestArchConfig(buildDir, nil, "", fs)
 
 	ctx := NewTestArchContext()
-	ctx.RegisterModuleType("package", PackageFactory)
 	ctx.RegisterModuleType("mock_library", newMockLibraryModule)
 	ctx.RegisterModuleType("mock_defaults", defaultsFactory)
-	ctx.PreArchMutators(RegisterPackageRenamer)
+
+	// Order of the following method calls is significant.
+	RegisterPackageBuildComponents(ctx)
+	registerTestPrebuiltBuildComponents(ctx)
 	ctx.PreArchMutators(RegisterVisibilityRuleChecker)
 	ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
diff --git a/apex/androidmk.go b/apex/androidmk.go
index b2fe8da..ad7d2f1 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -245,6 +245,14 @@
 				if apexType == imageApex {
 					fmt.Fprintln(w, "ALL_MODULES.$(LOCAL_MODULE).BUNDLE :=", a.bundleModuleFile.String())
 				}
+
+				if a.installedFilesFile != nil {
+					goal := "droidcore"
+					distFile := name + "-installed-files.txt"
+					fmt.Fprintln(w, ".PHONY:", goal)
+					fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n",
+						goal, a.installedFilesFile.String(), distFile)
+				}
 			}
 		}}
 }
diff --git a/apex/apex.go b/apex/apex.go
index 7d6b7f0..33b1be3 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -57,8 +57,249 @@
 	certificateTag = dependencyTag{name: "certificate"}
 	usesTag        = dependencyTag{name: "uses"}
 	androidAppTag  = dependencyTag{name: "androidApp"}
+	apexAvailWl    = makeApexAvailableWhitelist()
 )
 
+// This is a map from apex to modules, which overrides the
+// apex_available setting for that particular module to make
+// it available for the apex regardless of its setting.
+// TODO(b/147364041): remove this
+func makeApexAvailableWhitelist() map[string][]string {
+	// The "Module separator"s below are employed to minimize merge conflicts.
+	m := make(map[string][]string)
+	//
+	// Module separator
+	//
+	m["com.android.adbd"] = []string{"adbd", "libcrypto"}
+	//
+	// Module separator
+	//
+	m["com.android.art"] = []string{
+		"jacocoagent",
+		"libadbconnection_server",
+		"libartd-disassembler",
+		"libbacktrace",
+		"libbase",
+		"libc++",
+		"libcrypto",
+		"libdexfile_support",
+		"libexpat",
+		"libicuuc",
+		"liblzma",
+		"libmeminfo",
+		"libprocinfo",
+		"libunwindstack",
+		"libvixl",
+		"libvixld",
+		"libz",
+		"libziparchive",
+		"prebuilt_libclang_rt",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.bluetooth.updatable"] = []string{
+		"android.hardware.audio.common@5.0",
+		"android.hardware.bluetooth@1.0",
+		"android.hardware.bluetooth@1.1",
+		"android.hardware.bluetooth.a2dp@1.0",
+		"android.hardware.bluetooth.audio@2.0",
+		"android.hidl.safe_union@1.0",
+		"libbase",
+		"libbinderthreadstate",
+		"libbluetooth",
+		"libbluetooth_jni",
+		"libc++",
+		"libchrome",
+		"libcrypto",
+		"libcutils",
+		"libevent",
+		"libfmq",
+		"libhidlbase",
+		"libprocessgroup",
+		"libprotobuf-cpp-lite",
+		"libstatslog",
+		"libtinyxml2",
+		"libutils",
+		"libz",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.conscrypt"] = []string{"boringssl_self_test", "libc++", "libcrypto", "libssl"}
+	//
+	// Module separator
+	//
+	m["com.android.cronet"] = []string{"org.chromium.net.cronet", "prebuilt_libcronet.80.0.3986.0"}
+	//
+	// Module separator
+	//
+	m["com.android.media"] = []string{
+		"android.hardware.cas@1.0",
+		"android.hardware.cas.native@1.0",
+		"android.hidl.allocator@1.0",
+		"android.hidl.memory@1.0",
+		"android.hidl.memory.token@1.0",
+		"android.hidl.token@1.0",
+		"android.hidl.token@1.0-utils",
+		"libaacextractor",
+		"libamrextractor",
+		"libbase",
+		"libbinderthreadstate",
+		"libc++",
+		"libcrypto",
+		"libcutils",
+		"libflacextractor",
+		"libhidlbase",
+		"libhidlmemory",
+		"libmidiextractor",
+		"libmkvextractor",
+		"libmp3extractor",
+		"libmp4extractor",
+		"libmpeg2extractor",
+		"liboggextractor",
+		"libprocessgroup",
+		"libutils",
+		"libwavextractor",
+		"updatable-media",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.media.swcodec"] = []string{
+		"android.frameworks.bufferhub@1.0",
+		"android.hardware.configstore@1.0",
+		"android.hardware.configstore@1.1",
+		"android.hardware.configstore-utils",
+		"android.hardware.graphics.allocator@2.0",
+		"android.hardware.graphics.allocator@3.0",
+		"android.hardware.graphics.bufferqueue@1.0",
+		"android.hardware.graphics.bufferqueue@2.0",
+		"android.hardware.graphics.common@1.0",
+		"android.hardware.graphics.common@1.1",
+		"android.hardware.graphics.common@1.2",
+		"android.hardware.graphics.mapper@2.0",
+		"android.hardware.graphics.mapper@2.1",
+		"android.hardware.graphics.mapper@3.0",
+		"android.hardware.media@1.0",
+		"android.hardware.media.bufferpool@2.0",
+		"android.hardware.media.c2@1.0",
+		"android.hardware.media.omx@1.0",
+		"android.hidl.memory@1.0",
+		"android.hidl.memory.token@1.0",
+		"android.hidl.safe_union@1.0",
+		"android.hidl.token@1.0",
+		"android.hidl.token@1.0-utils",
+		"libavservices_minijail",
+		"libbacktrace",
+		"libbase",
+		"libbinderthreadstate",
+		"libc++",
+		"libcap",
+		"libcodec2",
+		"libcodec2_hidl@1.0",
+		"libcodec2_soft_aacdec",
+		"libcodec2_soft_aacenc",
+		"libcodec2_soft_amrnbdec",
+		"libcodec2_soft_amrnbenc",
+		"libcodec2_soft_amrwbdec",
+		"libcodec2_soft_amrwbenc",
+		"libcodec2_soft_av1dec_gav1",
+		"libcodec2_soft_avcdec",
+		"libcodec2_soft_avcenc",
+		"libcodec2_soft_common",
+		"libcodec2_soft_flacdec",
+		"libcodec2_soft_flacenc",
+		"libcodec2_soft_g711alawdec",
+		"libcodec2_soft_g711mlawdec",
+		"libcodec2_soft_gsmdec",
+		"libcodec2_soft_h263dec",
+		"libcodec2_soft_h263enc",
+		"libcodec2_soft_hevcdec",
+		"libcodec2_soft_hevcenc",
+		"libcodec2_soft_mp3dec",
+		"libcodec2_soft_mpeg2dec",
+		"libcodec2_soft_mpeg4dec",
+		"libcodec2_soft_mpeg4enc",
+		"libcodec2_soft_opusdec",
+		"libcodec2_soft_opusenc",
+		"libcodec2_soft_rawdec",
+		"libcodec2_soft_vorbisdec",
+		"libcodec2_soft_vp8dec",
+		"libcodec2_soft_vp8enc",
+		"libcodec2_soft_vp9dec",
+		"libcodec2_soft_vp9enc",
+		"libcodec2_vndk",
+		"libc_scudo",
+		"libcutils",
+		"libdexfile_support",
+		"libEGL",
+		"libfmq",
+		"libgraphicsenv",
+		"libhardware",
+		"libhidlbase",
+		"libhidlmemory",
+		"libion",
+		"liblzma",
+		"libmedia_codecserviceregistrant",
+		"libminijail",
+		"libnativebridge_lazy",
+		"libnativeloader_lazy",
+		"libopus",
+		"libprocessgroup",
+		"libscudo_wrapper",
+		"libsfplugin_ccodec_utils",
+		"libstagefright_amrnb_common",
+		"libstagefright_bufferpool@2.0.1",
+		"libstagefright_bufferqueue_helper",
+		"libstagefright_enc_common",
+		"libstagefright_flacdec",
+		"libstagefright_foundation",
+		"libsync",
+		"libui",
+		"libunwindstack",
+		"libutils",
+		"libvorbisidec",
+		"libvpx",
+		"mediaswcodec",
+		"prebuilt_libclang_rt",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.runtime"] = []string{
+		"libbase",
+		"libc++",
+		"libdexfile_support",
+		"liblzma",
+		"libunwindstack",
+		"prebuilt_libclang_rt",
+	}
+	//
+	// Module separator
+	//
+	m["com.android.resolv"] = []string{"libcrypto", "libnetd_resolv", "libssl"}
+	//
+	// Module separator
+	//
+	m["com.android.tethering"] = []string{"libbase", "libc++", "libnativehelper_compat_libc++"}
+	//
+	// Module separator
+	//
+	m["com.android.vndk"] = []string{
+		"libbacktrace",
+		"libbinderthreadstate",
+		"libblas",
+		"libcompiler_rt",
+		"libgui",
+		"libunwind",
+	}
+	//
+	// Module separator
+	//
+	return m
+}
+
 func init() {
 	android.RegisterModuleType("apex", BundleFactory)
 	android.RegisterModuleType("apex_test", testApexBundleFactory)
@@ -547,6 +788,8 @@
 	// Suffix of module name in Android.mk
 	// ".flattened", ".apex", ".zipapex", or ""
 	suffix string
+
+	installedFilesFile android.WritablePath
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -1231,7 +1474,12 @@
 	if !ctx.Host() && !a.testApex {
 		for _, fi := range filesInfo {
 			if am, ok := fi.module.(android.ApexModule); ok {
-				if !am.AvailableFor(ctx.ModuleName()) {
+				// vndk {enabled:true} implies visibility to the vndk apex
+				if ccm, ok := fi.module.(*cc.Module); ok && ccm.IsVndk() && a.vndkApex {
+					continue
+				}
+
+				if !am.AvailableFor(ctx.ModuleName()) && !whitelistedApexAvailable(ctx.ModuleName(), a.vndkApex, fi.module) {
 					ctx.ModuleErrorf("requires %q that is not available for the APEX", fi.module.Name())
 					// don't stop so that we can report other violations in the same run
 				}
@@ -1280,6 +1528,25 @@
 	a.buildApexDependencyInfo(ctx)
 }
 
+func whitelistedApexAvailable(apex string, is_vndk bool, module android.Module) bool {
+	key := apex
+	key = strings.Replace(key, "test_", "", 1)
+	key = strings.Replace(key, "com.android.art.debug", "com.android.art", 1)
+	key = strings.Replace(key, "com.android.art.release", "com.android.art", 1)
+
+	moduleName := module.Name()
+	if strings.Contains(moduleName, "prebuilt_libclang_rt") {
+		// This module has variants that depend on the product being built.
+		moduleName = "prebuilt_libclang_rt"
+	}
+
+	if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) {
+		return true
+	}
+
+	return false
+}
+
 func newApexBundle() *apexBundle {
 	module := &apexBundle{}
 	module.AddProperties(&module.properties)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b37674f..84bb2b5 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -403,6 +403,11 @@
 			shared_libs: ["mylib2"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_binary {
@@ -422,6 +427,7 @@
 			system_shared_libs: [],
 			static_executable: true,
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -430,6 +436,11 @@
 			system_shared_libs: [],
 			stl: "none",
 			notice: "custom_notice",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		java_library {
@@ -440,6 +451,11 @@
 			compile_dex: true,
 			static_libs: ["myotherjar"],
 			libs: ["mysharedjar"],
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		java_library {
@@ -560,6 +576,7 @@
 			name: "mylib",
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		java_library {
@@ -568,6 +585,7 @@
 			sdk_version: "none",
 			system_modules: "none",
 			compile_dex: true,
+			apex_available: [ "myapex" ],
 		}
 
 		android_app {
@@ -575,6 +593,7 @@
 			srcs: ["foo/bar/MyClass.java"],
 			sdk_version: "none",
 			system_modules: "none",
+			apex_available: [ "myapex" ],
 		}
 	`)
 	ensureExactContents(t, ctx, "myapex", []string{
@@ -627,6 +646,7 @@
 			shared_libs: ["mylib2"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -634,6 +654,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`)
 
@@ -674,6 +695,7 @@
 			shared_libs: ["mylib2", "mylib3"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -696,6 +718,7 @@
 			stubs: {
 				versions: ["10", "11", "12"],
 			},
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -703,6 +726,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`)
 
@@ -764,6 +788,7 @@
 			shared_libs: ["libfoo#10"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex2" ],
 		}
 
 		cc_library {
@@ -845,6 +870,7 @@
 			runtime_libs: ["libfoo", "libbar"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -862,6 +888,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 	`)
@@ -906,6 +933,7 @@
 			shared_libs: ["libbar"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -956,6 +984,7 @@
 			srcs: ["mylib.cpp"],
 			shared_libs: ["libdl#27"],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library_shared {
@@ -963,6 +992,7 @@
 			srcs: ["mylib.cpp"],
 			shared_libs: ["libdl#27"],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -985,6 +1015,10 @@
 			stubs: {
 				versions: ["27", "28", "29"],
 			},
+			apex_available: [
+				"//apex_available:platform",
+				"myapex"
+			],
 		}
 
 		cc_library {
@@ -996,6 +1030,10 @@
 			stubs: {
 				versions: ["27", "28", "29"],
 			},
+			apex_available: [
+				"//apex_available:platform",
+				"myapex"
+			],
 		}
 
 		cc_library {
@@ -1087,6 +1125,7 @@
 			relative_install_path: "foo/bar",
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_binary {
@@ -1096,6 +1135,7 @@
 			system_shared_libs: [],
 			static_executable: true,
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`)
 
@@ -1140,6 +1180,7 @@
 			system_shared_libs: [],
 			vendor_available: true,
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -1148,6 +1189,7 @@
 			system_shared_libs: [],
 			vendor_available: true,
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`, func(fs map[string][]byte, config android.Config) {
 		setUseVendorWhitelistForTest(config, []string{"myapex"})
@@ -1248,6 +1290,10 @@
 			stubs: {
 				versions: ["1", "2", "3"],
 			},
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_binary {
@@ -1281,6 +1327,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex_keytest" ],
 		}
 
 		apex_key {
@@ -1474,6 +1521,12 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+				"otherapex",
+			],
 		}
 	`)
 
@@ -1527,6 +1580,7 @@
 			stubs: {
 				versions: ["1", "2", "3"],
 			},
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -1629,6 +1683,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -1641,6 +1696,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 	`+vndkLibrariesTxtFiles("current"))
 
@@ -1678,6 +1734,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_prebuilt_library_shared {
@@ -1695,6 +1752,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 		`+vndkLibrariesTxtFiles("current"),
 		withFiles(map[string][]byte{
@@ -1765,6 +1823,7 @@
 					srcs: ["libvndk27_arm64.so"],
 				},
 			},
+			apex_available: [ "myapex_v27" ],
 		}
 
 		vndk_prebuilt_shared {
@@ -1901,6 +1960,7 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 		`+vndkLibrariesTxtFiles("current"),
 		withTargets(map[android.OsType][]android.Target{
@@ -1993,6 +2053,7 @@
 					srcs: ["libvndk27binder32.so"],
 				}
 			},
+			apex_available: [ "myapex_v27" ],
 		}
 		`+vndkLibrariesTxtFiles("27"),
 		withFiles(map[string][]byte{
@@ -2058,6 +2119,7 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex_nodep" ],
 		}
 
 		cc_library {
@@ -2066,6 +2128,11 @@
 			shared_libs: ["libfoo"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [
+				"myapex_dep",
+				"myapex_provider",
+				"myapex_selfcontained",
+			],
 		}
 
 		cc_library {
@@ -2076,6 +2143,10 @@
 			},
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [
+				"myapex_provider",
+				"myapex_selfcontained",
+			],
 		}
 	`)
 
@@ -2148,6 +2219,10 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [
+					"//apex_available:platform",
+				  "myapex",
+		  ],
 		}
 	`)
 
@@ -2199,6 +2274,11 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 	`)
 
@@ -2267,6 +2347,11 @@
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_library {
@@ -2275,6 +2360,11 @@
 			system_shared_libs: [],
 			stl: "none",
 			compile_multilib: "first",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_library {
@@ -2701,6 +2791,7 @@
 			shared_libs: ["libcommon"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library {
@@ -2708,6 +2799,12 @@
 			srcs: ["mylib_common.cpp"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"commonapex",
+				"myapex",
+			],
 		}
 	`)
 
@@ -2859,6 +2956,7 @@
 			sdk_version: "none",
 			system_modules: "none",
 			jni_libs: ["libjni"],
+			apex_available: [ "myapex" ],
 		}
 
 		android_app {
@@ -2867,6 +2965,7 @@
 			sdk_version: "none",
 			system_modules: "none",
 			privileged: true,
+			apex_available: [ "myapex" ],
 		}
 
 		cc_library_shared {
@@ -2960,6 +3059,7 @@
 		android_test_helper_app {
 			name: "TesterHelpAppFoo",
 			srcs: ["foo/bar/MyClass.java"],
+			apex_available: [ "myapex" ],
 		}
 
 	`)
@@ -3215,6 +3315,7 @@
 			package_name: "foo",
 			sdk_version: "none",
 			system_modules: "none",
+			apex_available: [ "myapex" ],
 		}
 
 		override_android_app {
@@ -3278,6 +3379,7 @@
 	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
 	args := module.Rule("apexRule").Args
 	ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
+	ensureNotContains(t, args["opt_flags"], "--no_hashtree")
 }
 
 func TestJavaSDKLibrary(t *testing.T) {
@@ -3298,6 +3400,7 @@
 			name: "foo",
 			srcs: ["a.java"],
 			api_packages: ["foo"],
+			apex_available: [ "myapex" ],
 		}
 	`, withFiles(map[string][]byte{
 		"api/current.txt":        nil,
@@ -3363,6 +3466,7 @@
 			required: ["a", "b"],
 			host_required: ["c", "d"],
 			target_required: ["e", "f"],
+			apex_available: [ "myapex" ],
 		}
 	`)
 
diff --git a/apex/builder.go b/apex/builder.go
index 2f1e453..9122188 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -233,6 +233,19 @@
 	return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.FirstUniquePaths(noticeFiles)).HtmlGzOutput
 }
 
+func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
+	output := android.PathForModuleOut(ctx, "installed-files.txt")
+	rule := android.NewRuleBuilder()
+	rule.Command().
+		Implicit(builtApex).
+		Text("(cd " + imageDir.String() + " ; ").
+		Text("find . -type f -printf \"%s %p\\n\") ").
+		Text(" | sort -nr > ").
+		Output(output)
+	rule.Build(pctx, ctx, "installed-files."+a.Name(), "Installed files")
+	return output.OutputPath
+}
+
 func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
 	var abis []string
 	for _, target := range ctx.MultiTargets() {
@@ -307,6 +320,7 @@
 	outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
 	prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
 
+	imageDir := android.PathForModuleOut(ctx, "image"+suffix)
 	if apexType == imageApex {
 		// files and dirs that will be created in APEX
 		var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
@@ -383,7 +397,7 @@
 			ctx.PropertyErrorf("test_only_no_hashtree", "not available")
 			return
 		}
-		if (!ctx.Config().UnbundledBuild() && a.installable()) || a.testOnlyShouldSkipHashtreeGeneration() {
+		if !proptools.Bool(a.properties.Legacy_android10_support) || a.testOnlyShouldSkipHashtreeGeneration() {
 			// Apexes which are supposed to be installed in builtin dirs(/system, etc)
 			// don't need hashtree for activation. Therefore, by removing hashtree from
 			// apex bundle (filesystem image in it, to be specific), we can save storage.
@@ -408,7 +422,7 @@
 			Description: "apex (" + apexType.name() + ")",
 			Args: map[string]string{
 				"tool_path":        outHostBinDir + ":" + prebuiltSdkToolsBinDir,
-				"image_dir":        android.PathForModuleOut(ctx, "image"+suffix).String(),
+				"image_dir":        imageDir.String(),
 				"copy_commands":    strings.Join(copyCommands, " && "),
 				"manifest":         a.manifestPbOut.String(),
 				"file_contexts":    a.fileContexts.String(),
@@ -446,7 +460,7 @@
 			Description: "apex (" + apexType.name() + ")",
 			Args: map[string]string{
 				"tool_path":     outHostBinDir + ":" + prebuiltSdkToolsBinDir,
-				"image_dir":     android.PathForModuleOut(ctx, "image"+suffix).String(),
+				"image_dir":     imageDir.String(),
 				"copy_commands": strings.Join(copyCommands, " && "),
 				"manifest":      a.manifestPbOut.String(),
 			},
@@ -474,6 +488,9 @@
 		ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
 	}
 	a.buildFilesInfo(ctx)
+
+	// installed-files.txt is dist'ed
+	a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
 }
 
 func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {
diff --git a/cc/ccdeps.go b/cc/ccdeps.go
index 9b89110..4e23a7b 100644
--- a/cc/ccdeps.go
+++ b/cc/ccdeps.go
@@ -142,7 +142,7 @@
 			compilerParams.HeaderSearchPath =
 				append(compilerParams.HeaderSearchPath, strings.TrimPrefix(param, "-I"))
 		case systemHeaderSearchPath:
-			if i < len(params)-1 {
+			if i < len(cparams)-1 {
 				compilerParams.SystemHeaderSearchPath = append(compilerParams.SystemHeaderSearchPath, cparams[i+1])
 			}
 			i = i + 1
diff --git a/java/app.go b/java/app.go
index a6b3408..7828a80 100755
--- a/java/app.go
+++ b/java/app.go
@@ -926,6 +926,16 @@
 
 func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
 	ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
+	// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
+	// with them may invalidate pre-existing signature data.
+	if ctx.InstallInTestcases() && Bool(a.properties.Presigned) {
+		ctx.Build(pctx, android.BuildParams{
+			Rule:   android.Cp,
+			Output: outputPath,
+			Input:  inputPath,
+		})
+		return
+	}
 	rule := android.NewRuleBuilder()
 	rule.Command().
 		Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
@@ -1003,6 +1013,8 @@
 	var installDir android.InstallPath
 	if Bool(a.properties.Privileged) {
 		installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName())
+	} else if ctx.InstallInTestcases() {
+		installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
 	} else {
 		installDir = android.PathForModuleInstall(ctx, "app", a.BaseModuleName())
 	}
@@ -1159,6 +1171,10 @@
 	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
 }
 
+func (a *AndroidTestImport) InstallInTestcases() bool {
+	return true
+}
+
 // android_test_import imports a prebuilt test apk with additional processing specified in the
 // module. DPI or arch variant configurations can be made as with android_app_import.
 func AndroidTestImportFactory() android.Module {
diff --git a/java/app_test.go b/java/app_test.go
index 9bdef4e..862af77 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1628,6 +1628,40 @@
 	}
 }
 
+func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
+	ctx, _ := testJava(t, `
+		android_test_import {
+			name: "foo",
+			apk: "prebuilts/apk/app.apk",
+			certificate: "cert/new_cert",
+			data: [
+				"testdata/data",
+			],
+		}
+
+		android_test_import {
+			name: "foo_presigned",
+			apk: "prebuilts/apk/app.apk",
+			presigned: true,
+			data: [
+				"testdata/data",
+			],
+		}
+		`)
+
+	variant := ctx.ModuleForTests("foo", "android_common")
+	jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
+	if !strings.HasPrefix(jniRule, "if (zipinfo") {
+		t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
+	}
+
+	variant = ctx.ModuleForTests("foo_presigned", "android_common")
+	jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
+	if jniRule != android.Cp.String() {
+		t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
+	}
+}
+
 func TestStl(t *testing.T) {
 	ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
 		cc_library {
diff --git a/java/java_test.go b/java/java_test.go
index 30a8ca6..a2788cb 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1227,3 +1227,67 @@
 		checkPatchModuleFlag(t, ctx, "baz", expected)
 	})
 }
+
+func TestJavaSystemModules(t *testing.T) {
+	ctx, _ := testJava(t, `
+		java_system_modules {
+			name: "system-modules",
+			libs: ["system-module1", "system-module2"],
+		}
+		java_library {
+			name: "system-module1",
+			srcs: ["a.java"],
+			sdk_version: "none",
+			system_modules: "none",
+		}
+		java_library {
+			name: "system-module2",
+			srcs: ["b.java"],
+			sdk_version: "none",
+			system_modules: "none",
+		}
+		`)
+
+	// check the existence of the module
+	systemModules := ctx.ModuleForTests("system-modules", "android_common")
+
+	cmd := systemModules.Rule("jarsTosystemModules")
+
+	// make sure the command compiles against the supplied modules.
+	for _, module := range []string{"system-module1.jar", "system-module2.jar"} {
+		if !strings.Contains(cmd.Args["classpath"], module) {
+			t.Errorf("system modules classpath %v does not contain %q", cmd.Args["classpath"],
+				module)
+		}
+	}
+}
+
+func TestJavaSystemModulesImport(t *testing.T) {
+	ctx, _ := testJava(t, `
+		java_system_modules_import {
+			name: "system-modules",
+			libs: ["system-module1", "system-module2"],
+		}
+		java_import {
+			name: "system-module1",
+			jars: ["a.jar"],
+		}
+		java_import {
+			name: "system-module2",
+			jars: ["b.jar"],
+		}
+		`)
+
+	// check the existence of the module
+	systemModules := ctx.ModuleForTests("system-modules", "android_common")
+
+	cmd := systemModules.Rule("jarsTosystemModules")
+
+	// make sure the command compiles against the supplied modules.
+	for _, module := range []string{"system-module1.jar", "system-module2.jar"} {
+		if !strings.Contains(cmd.Args["classpath"], module) {
+			t.Errorf("system modules classpath %v does not contain %q", cmd.Args["classpath"],
+				module)
+		}
+	}
+}
diff --git a/java/system_modules.go b/java/system_modules.go
index ed2fc18..92297c4 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -35,6 +35,7 @@
 
 func RegisterSystemModulesBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("java_system_modules", SystemModulesFactory)
+	ctx.RegisterModuleType("java_system_modules_import", systemModulesImportFactory)
 }
 
 var (
@@ -92,6 +93,9 @@
 	return outDir, outputs.Paths()
 }
 
+// java_system_modules creates a system module from a set of java libraries that can
+// be referenced from the system_modules property. It must contain at a minimum the
+// java.base module which must include classes from java.lang amongst other java packages.
 func SystemModulesFactory() android.Module {
 	module := &SystemModules{}
 	module.AddProperties(&module.properties)
@@ -157,3 +161,30 @@
 		},
 	}
 }
+
+// A prebuilt version of java_system_modules. It does not import the
+// generated system module, it generates the system module from imported
+// java libraries in the same way that java_system_modules does. It just
+// acts as a prebuilt, i.e. can have the same base name as another module
+// type and the one to use is selected at runtime.
+func systemModulesImportFactory() android.Module {
+	module := &systemModulesImport{}
+	module.AddProperties(&module.properties)
+	android.InitPrebuiltModule(module, &module.properties.Libs)
+	android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+	android.InitDefaultableModule(module)
+	return module
+}
+
+type systemModulesImport struct {
+	SystemModules
+	prebuilt android.Prebuilt
+}
+
+func (system *systemModulesImport) Name() string {
+	return system.prebuilt.Name(system.ModuleBase.Name())
+}
+
+func (system *systemModulesImport) Prebuilt() *android.Prebuilt {
+	return &system.prebuilt
+}
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 255ac08..9a75610 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -101,6 +101,11 @@
 			srcs: ["libfoo.so"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
 		}
 
 		cc_prebuilt_library_shared {
@@ -109,6 +114,11 @@
 			srcs: ["libfoo.so"],
 			system_shared_libs: [],
 			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex2",
+			],
 		}
 
 		cc_library_shared {
@@ -117,6 +127,10 @@
 			shared_libs: ["sdkmember"],
 			system_shared_libs: [],
 			stl: "none",
+			apex_available: [
+				"myapex",
+				"myapex2",
+			],
 		}
 
 		apex {
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 218a16a..692c205 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -73,6 +73,10 @@
 			sdk_version: "none",
 			compile_dex: true,
 			host_supported: true,
+			apex_available: [
+				"myapex",
+				"myapex2",
+			],
 		}
 
 		apex {
diff --git a/sdk/testing.go b/sdk/testing.go
index 8097889..c9cc30f 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -62,14 +62,12 @@
 	ctx := android.NewTestArchContext()
 
 	// from android package
-	ctx.PreArchMutators(android.RegisterPackageRenamer)
+	android.RegisterPackageBuildComponents(ctx)
 	ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)
 	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
 	ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
 
-	ctx.RegisterModuleType("package", android.PackageFactory)
-
 	// from java package
 	java.RegisterJavaBuildComponents(ctx)
 	java.RegisterAppBuildComponents(ctx)