Merge "rust: Emit android vndk cfg flag."
diff --git a/Android.bp b/Android.bp
index 1012dba..9d5b07d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 subdirs = [
     "androidmk",
     "bpfix",
diff --git a/android/Android.bp b/android/Android.bp
index eabb137..00139d8 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-android",
     pkgPath: "android/soong/android",
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 5ba6d62..a5c4bed 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -467,7 +467,6 @@
 		return err
 	}
 
-	fmt.Printf("Build statements %s", context.buildStatements)
 	// Clear requests.
 	context.requests = map[cqueryKey]bool{}
 	return nil
diff --git a/android/config.go b/android/config.go
index e0f3a91..50e39d7 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1413,6 +1413,14 @@
 	return c.config.productVariables.VendorSnapshotModules
 }
 
+func (c *deviceConfig) DirectedRecoverySnapshot() bool {
+	return c.config.productVariables.DirectedRecoverySnapshot
+}
+
+func (c *deviceConfig) RecoverySnapshotModules() map[string]bool {
+	return c.config.productVariables.RecoverySnapshotModules
+}
+
 // 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
diff --git a/android/module.go b/android/module.go
index 1409d44..bf74cad 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2374,6 +2374,16 @@
 	return b.bp.FinalModule().(Module)
 }
 
+// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
+func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
+	if tag == licenseKindTag {
+		return true
+	} else if tag == licensesTag {
+		return true
+	}
+	return false
+}
+
 // A regexp for removing boilerplate from BaseDependencyTag from the string representation of
 // a dependency tag.
 var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`)
diff --git a/android/paths.go b/android/paths.go
index 44221be..c3fa61a 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1949,3 +1949,28 @@
 	// The install path of the data file, relative to the install root.
 	RelativeInstallPath string
 }
+
+// PathsIfNonNil returns a Paths containing only the non-nil input arguments.
+func PathsIfNonNil(paths ...Path) Paths {
+	if len(paths) == 0 {
+		// Fast path for empty argument list
+		return nil
+	} else if len(paths) == 1 {
+		// Fast path for a single argument
+		if paths[0] != nil {
+			return paths
+		} else {
+			return nil
+		}
+	}
+	ret := make(Paths, 0, len(paths))
+	for _, path := range paths {
+		if path != nil {
+			ret = append(ret, path)
+		}
+	}
+	if len(ret) == 0 {
+		return nil
+	}
+	return ret
+}
diff --git a/android/soongconfig/Android.bp b/android/soongconfig/Android.bp
index 6bb68eb..e7fa5a0 100644
--- a/android/soongconfig/Android.bp
+++ b/android/soongconfig/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-android-soongconfig",
     pkgPath: "android/soong/android/soongconfig",
diff --git a/android/variable.go b/android/variable.go
index 799369d..e76d683 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -307,6 +307,9 @@
 	DirectedVendorSnapshot bool            `json:",omitempty"`
 	VendorSnapshotModules  map[string]bool `json:",omitempty"`
 
+	DirectedRecoverySnapshot bool            `json:",omitempty"`
+	RecoverySnapshotModules  map[string]bool `json:",omitempty"`
+
 	BoardVendorSepolicyDirs      []string `json:",omitempty"`
 	BoardOdmSepolicyDirs         []string `json:",omitempty"`
 	BoardReqdMaskPolicy          []string `json:",omitempty"`
diff --git a/androidmk/Android.bp b/androidmk/Android.bp
index 70fc1f7..f04d01c 100644
--- a/androidmk/Android.bp
+++ b/androidmk/Android.bp
@@ -16,6 +16,10 @@
 // androidmk Android.mk to Blueprints translator
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "androidmk",
     srcs: [
diff --git a/apex/Android.bp b/apex/Android.bp
index b6fdcf4..8a2edeb 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-apex",
     pkgPath: "android/soong/apex",
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index 5d00e06..aee3fc4 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -39,6 +39,7 @@
 android.hardware.media.c2@1.1(minSdkVersion:29)
 android.hardware.media.omx@1.0(minSdkVersion:29)
 android.hardware.media@1.0(minSdkVersion:29)
+android.hardware.neuralnetworks-V1-ndk_platform(minSdkVersion:30)
 android.hardware.neuralnetworks@1.0(minSdkVersion:30)
 android.hardware.neuralnetworks@1.1(minSdkVersion:30)
 android.hardware.neuralnetworks@1.2(minSdkVersion:30)
@@ -499,6 +500,7 @@
 neuralnetworks_utils_hal_1_1(minSdkVersion:30)
 neuralnetworks_utils_hal_1_2(minSdkVersion:30)
 neuralnetworks_utils_hal_1_3(minSdkVersion:30)
+neuralnetworks_utils_hal_aidl(minSdkVersion:30)
 neuralnetworks_utils_hal_common(minSdkVersion:30)
 neuralnetworks_utils_hal_service(minSdkVersion:30)
 no_op(minSdkVersion:current)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 83eb56a..181946b 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -4364,7 +4364,7 @@
 
 	checkDexJarBuildPath := func(t *testing.T, ctx *android.TestContext, name string) {
 		// Make sure the import has been given the correct path to the dex jar.
-		p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.Dependency)
+		p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
 		dexJarBuildPath := p.DexJarBuildPath()
 		if expected, actual := ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar", android.NormalizePathForTesting(dexJarBuildPath); actual != expected {
 			t.Errorf("Incorrect DexJarBuildPath value '%s', expected '%s'", actual, expected)
diff --git a/bazel/Android.bp b/bazel/Android.bp
index d222d98..117fd46 100644
--- a/bazel/Android.bp
+++ b/bazel/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-bazel",
     pkgPath: "android/soong/bazel",
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 54fc93f..fdac88d 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-bp2build",
     pkgPath: "android/soong/bp2build",
diff --git a/bpf/Android.bp b/bpf/Android.bp
index 882cd8a..3ffa29f 100644
--- a/bpf/Android.bp
+++ b/bpf/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-bpf",
     pkgPath: "android/soong/bpf",
diff --git a/bpfix/Android.bp b/bpfix/Android.bp
index b244e3a..345dbd0 100644
--- a/bpfix/Android.bp
+++ b/bpfix/Android.bp
@@ -16,6 +16,10 @@
 // androidmk Android.mk to Blueprints translator
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "bpfix",
     srcs: [
diff --git a/cc/Android.bp b/cc/Android.bp
index 6ec7e0e..bdbb3c0 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-cc",
     pkgPath: "android/soong/cc",
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
index ce4bdfb..5ef247d 100644
--- a/cc/config/Android.bp
+++ b/cc/config/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-cc-config",
     pkgPath: "android/soong/cc/config",
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 45c18c2..425e349 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -41,6 +41,9 @@
 	"android.hardware.power-V1-ndk_platform",
 	"android.hardware.power-ndk_platform",
 	"android.hardware.rebootescrow-V1-ndk_platform",
+	"android.hardware.power.stats-V1-ndk_platform",
+	"android.hardware.power.stats-ndk_platform",
+	"android.hardware.power.stats-unstable-ndk_platform",
 	"android.hardware.rebootescrow-ndk_platform",
 	"android.hardware.security.keymint-V1-ndk_platform",
 	"android.hardware.security.keymint-ndk_platform",
diff --git a/cc/libbuildversion/Android.bp b/cc/libbuildversion/Android.bp
index b63338d..4debb1c 100644
--- a/cc/libbuildversion/Android.bp
+++ b/cc/libbuildversion/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_library_static {
     name: "libbuildversion",
     host_supported: true,
diff --git a/cc/libbuildversion/tests/Android.bp b/cc/libbuildversion/tests/Android.bp
index b3b2061..0e97fed 100644
--- a/cc/libbuildversion/tests/Android.bp
+++ b/cc/libbuildversion/tests/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_defaults {
     name: "build_version_test_defaults",
     use_version_lib: true,
diff --git a/cc/library.go b/cc/library.go
index f185cb7..65533bc 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -648,6 +648,11 @@
 		return objs
 	}
 	if library.buildStubs() {
+		symbolFile := String(library.Properties.Stubs.Symbol_file)
+		if symbolFile != "" && !strings.HasSuffix(symbolFile, ".map.txt") {
+			ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
+			return Objects{}
+		}
 		objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "--apex")
 		library.versionScriptPath = android.OptionalPathForPath(versionScript)
 		return objs
diff --git a/cc/ndk_api_coverage_parser/Android.bp b/cc/ndk_api_coverage_parser/Android.bp
index 8d9827c..b119e90 100644
--- a/cc/ndk_api_coverage_parser/Android.bp
+++ b/cc/ndk_api_coverage_parser/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 python_library_host {
     name: "ndk_api_coverage_parser_lib",
     pkg_path: "ndk_api_coverage_parser",
diff --git a/cc/ndkstubgen/Android.bp b/cc/ndkstubgen/Android.bp
index 85dfaee..782c124 100644
--- a/cc/ndkstubgen/Android.bp
+++ b/cc/ndkstubgen/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 python_binary_host {
     name: "ndkstubgen",
     pkg_path: "ndkstubgen",
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index b82628c..62daafd 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -195,8 +195,12 @@
 }
 
 func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
-	// directed recovery snapshot is not implemented yet
-	return false
+	// If we're using full snapshot, not directed snapshot, capture every module
+	if !cfg.DirectedRecoverySnapshot() {
+		return false
+	}
+	// Else, checks if name is in RECOVERY_SNAPSHOT_MODULES.
+	return !cfg.RecoverySnapshotModules()[name]
 }
 
 func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
diff --git a/cc/symbolfile/Android.bp b/cc/symbolfile/Android.bp
index 5b43309..6722110 100644
--- a/cc/symbolfile/Android.bp
+++ b/cc/symbolfile/Android.bp
@@ -14,6 +14,10 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 python_library_host {
     name: "symbolfile",
     pkg_path: "symbolfile",
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
index 659b693..7e283fb 100644
--- a/cc/vendor_snapshot_test.go
+++ b/cc/vendor_snapshot_test.go
@@ -1051,3 +1051,85 @@
 		}
 	}
 }
+
+func TestRecoverySnapshotDirected(t *testing.T) {
+	bp := `
+	cc_library_shared {
+		name: "librecovery",
+		recovery: true,
+		nocrt: true,
+	}
+
+	cc_library_shared {
+		name: "librecovery_available",
+		recovery_available: true,
+		nocrt: true,
+	}
+
+	genrule {
+		name: "libfoo_gen",
+		cmd: "",
+		out: ["libfoo.so"],
+	}
+
+	cc_prebuilt_library_shared {
+		name: "libfoo",
+		recovery: true,
+		prefer: true,
+		srcs: [":libfoo_gen"],
+	}
+
+	cc_library_shared {
+		name: "libfoo",
+		recovery: true,
+		nocrt: true,
+	}
+`
+	config := TestConfig(buildDir, android.Android, nil, bp, nil)
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+	config.TestProductVariables.DirectedRecoverySnapshot = true
+	config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool)
+	config.TestProductVariables.RecoverySnapshotModules["librecovery"] = true
+	config.TestProductVariables.RecoverySnapshotModules["libfoo"] = true
+	ctx := testCcWithConfig(t, config)
+
+	// Check recovery snapshot output.
+
+	snapshotDir := "recovery-snapshot"
+	snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+	snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
+
+	var includeJsonFiles []string
+
+	for _, arch := range [][]string{
+		[]string{"arm64", "armv8-a"},
+	} {
+		archType := arch[0]
+		archVariant := arch[1]
+		archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
+
+		sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
+		sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
+
+		// Included modules
+		checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
+		includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
+		// Check that snapshot captures "prefer: true" prebuilt
+		checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
+		includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
+
+		// Excluded modules. Modules not included in the directed recovery snapshot
+		// are still include as fake modules.
+		checkSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
+		includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery_available.so.json"))
+	}
+
+	// Verify that each json file for an included module has a rule.
+	for _, jsonFile := range includeJsonFiles {
+		if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
+			t.Errorf("include json file %q not found", jsonFile)
+		}
+	}
+}
diff --git a/cmd/dep_fixer/Android.bp b/cmd/dep_fixer/Android.bp
index 97364d5..818fd28 100644
--- a/cmd/dep_fixer/Android.bp
+++ b/cmd/dep_fixer/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "dep_fixer",
     deps: ["soong-makedeps"],
diff --git a/cmd/diff_target_files/Android.bp b/cmd/diff_target_files/Android.bp
index bc6b068..ae8c329 100644
--- a/cmd/diff_target_files/Android.bp
+++ b/cmd/diff_target_files/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "diff_target_files",
     srcs: [
diff --git a/cmd/extract_apks/Android.bp b/cmd/extract_apks/Android.bp
index f8fe864..8a4ed63 100644
--- a/cmd/extract_apks/Android.bp
+++ b/cmd/extract_apks/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "extract_apks",
     srcs: ["main.go"],
diff --git a/cmd/extract_jar_packages/Android.bp b/cmd/extract_jar_packages/Android.bp
index 4ea8798..ab33504 100644
--- a/cmd/extract_jar_packages/Android.bp
+++ b/cmd/extract_jar_packages/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "extract_jar_packages",
     deps: [
diff --git a/cmd/extract_linker/Android.bp b/cmd/extract_linker/Android.bp
index 690c4fa..d40d250 100644
--- a/cmd/extract_linker/Android.bp
+++ b/cmd/extract_linker/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "extract_linker",
     srcs: ["main.go"],
diff --git a/cmd/fileslist/Android.bp b/cmd/fileslist/Android.bp
index cbf939a..3c6f675 100644
--- a/cmd/fileslist/Android.bp
+++ b/cmd/fileslist/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "fileslist",
     srcs: [
diff --git a/cmd/host_bionic_inject/Android.bp b/cmd/host_bionic_inject/Android.bp
index 5994103..16bc179 100644
--- a/cmd/host_bionic_inject/Android.bp
+++ b/cmd/host_bionic_inject/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "host_bionic_inject",
     deps: ["soong-symbol_inject"],
diff --git a/cmd/javac_wrapper/Android.bp b/cmd/javac_wrapper/Android.bp
index c00f4bd..e441567 100644
--- a/cmd/javac_wrapper/Android.bp
+++ b/cmd/javac_wrapper/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "soong_javac_wrapper",
     srcs: [
diff --git a/cmd/merge_zips/Android.bp b/cmd/merge_zips/Android.bp
index 8c97b6d..930d040 100644
--- a/cmd/merge_zips/Android.bp
+++ b/cmd/merge_zips/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "merge_zips",
     deps: [
diff --git a/cmd/multiproduct_kati/Android.bp b/cmd/multiproduct_kati/Android.bp
index d34f8c3..21d8e21 100644
--- a/cmd/multiproduct_kati/Android.bp
+++ b/cmd/multiproduct_kati/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "multiproduct_kati",
     deps: [
diff --git a/cmd/path_interposer/Android.bp b/cmd/path_interposer/Android.bp
index 41a219f..875cd72 100644
--- a/cmd/path_interposer/Android.bp
+++ b/cmd/path_interposer/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "path_interposer",
     deps: ["soong-ui-build-paths"],
diff --git a/cmd/pom2bp/Android.bp b/cmd/pom2bp/Android.bp
index 0b2b7b5..0dfed8b 100644
--- a/cmd/pom2bp/Android.bp
+++ b/cmd/pom2bp/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "pom2bp",
     deps: [
diff --git a/cmd/pom2mk/Android.bp b/cmd/pom2mk/Android.bp
index 54422b1..cc9dacc 100644
--- a/cmd/pom2mk/Android.bp
+++ b/cmd/pom2mk/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "pom2mk",
     deps: ["blueprint-proptools"],
diff --git a/cmd/sbox/Android.bp b/cmd/sbox/Android.bp
index f5e87c0..d88505f 100644
--- a/cmd/sbox/Android.bp
+++ b/cmd/sbox/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "sbox",
     deps: [
diff --git a/cmd/soong_build/Android.bp b/cmd/soong_build/Android.bp
index 6714978..6a0a87b 100644
--- a/cmd/soong_build/Android.bp
+++ b/cmd/soong_build/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_binary {
     name: "soong_build",
     deps: [
diff --git a/cmd/soong_env/Android.bp b/cmd/soong_env/Android.bp
index 4db0da3..ad717d0 100644
--- a/cmd/soong_env/Android.bp
+++ b/cmd/soong_env/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_binary {
     name: "soong_env",
     deps: [
diff --git a/cmd/soong_ui/Android.bp b/cmd/soong_ui/Android.bp
index 4e57bef..4f5eea9 100644
--- a/cmd/soong_ui/Android.bp
+++ b/cmd/soong_ui/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "soong_ui",
     deps: [
diff --git a/cmd/zip2zip/Android.bp b/cmd/zip2zip/Android.bp
index 2c4cd82..3ef7668 100644
--- a/cmd/zip2zip/Android.bp
+++ b/cmd/zip2zip/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "zip2zip",
     deps: [
diff --git a/cmd/zipsync/Android.bp b/cmd/zipsync/Android.bp
index 49b5f3e..0dcdd5c 100644
--- a/cmd/zipsync/Android.bp
+++ b/cmd/zipsync/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "zipsync",
     deps: [
diff --git a/cuj/Android.bp b/cuj/Android.bp
index 21d667f..a2da6e6 100644
--- a/cuj/Android.bp
+++ b/cuj/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "cuj_tests",
     deps: [
diff --git a/dexpreopt/Android.bp b/dexpreopt/Android.bp
index 35f90df..679d066 100644
--- a/dexpreopt/Android.bp
+++ b/dexpreopt/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-dexpreopt",
     pkgPath: "android/soong/dexpreopt",
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index ec62eb3..ad52b00 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -489,20 +489,16 @@
 }
 
 // Class loader contexts that come from Make via JSON dexpreopt.config. JSON CLC representation is
-// slightly different: it uses a map of library names to their CLC (instead of a list of structs
-// that including the name, as in the Soong CLC representation). The difference is insubstantial, it
-// is caused only by the language differerences between Go and JSON.
+// the same as Soong representation except that SDK versions and paths are represented with strings.
 type jsonClassLoaderContext struct {
+	Name        string
 	Host        string
 	Device      string
-	Subcontexts map[string]*jsonClassLoaderContext
+	Subcontexts []*jsonClassLoaderContext
 }
 
-// A map of <uses-library> name to its on-host and on-device build paths and CLC.
-type jsonClassLoaderContexts map[string]*jsonClassLoaderContext
-
 // A map from SDK version (represented with a JSON string) to JSON CLCs.
-type jsonClassLoaderContextMap map[string]map[string]*jsonClassLoaderContext
+type jsonClassLoaderContextMap map[string][]*jsonClassLoaderContext
 
 // Convert JSON CLC map to Soong represenation.
 func fromJsonClassLoaderContext(ctx android.PathContext, jClcMap jsonClassLoaderContextMap) ClassLoaderContextMap {
@@ -522,11 +518,11 @@
 }
 
 // Recursive helper for fromJsonClassLoaderContext.
-func fromJsonClassLoaderContextRec(ctx android.PathContext, jClcs map[string]*jsonClassLoaderContext) []*ClassLoaderContext {
+func fromJsonClassLoaderContextRec(ctx android.PathContext, jClcs []*jsonClassLoaderContext) []*ClassLoaderContext {
 	clcs := make([]*ClassLoaderContext, 0, len(jClcs))
-	for lib, clc := range jClcs {
+	for _, clc := range jClcs {
 		clcs = append(clcs, &ClassLoaderContext{
-			Name:        lib,
+			Name:        clc.Name,
 			Host:        constructPath(ctx, clc.Host),
 			Device:      clc.Device,
 			Subcontexts: fromJsonClassLoaderContextRec(ctx, clc.Subcontexts),
@@ -546,14 +542,15 @@
 }
 
 // Recursive helper for toJsonClassLoaderContext.
-func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) map[string]*jsonClassLoaderContext {
-	jClcs := make(map[string]*jsonClassLoaderContext, len(clcs))
+func toJsonClassLoaderContextRec(clcs []*ClassLoaderContext) []*jsonClassLoaderContext {
+	jClcs := make([]*jsonClassLoaderContext, len(clcs))
 	for _, clc := range clcs {
-		jClcs[clc.Name] = &jsonClassLoaderContext{
+		jClcs = append(jClcs, &jsonClassLoaderContext{
+			Name:        clc.Name,
 			Host:        clc.Host.String(),
 			Device:      clc.Device,
 			Subcontexts: toJsonClassLoaderContextRec(clc.Subcontexts),
-		}
+		})
 	}
 	return jClcs
 }
diff --git a/dexpreopt/dexpreopt_gen/Android.bp b/dexpreopt/dexpreopt_gen/Android.bp
index 3f0619c..2111451 100644
--- a/dexpreopt/dexpreopt_gen/Android.bp
+++ b/dexpreopt/dexpreopt_gen/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "dexpreopt_gen",
     srcs: [
diff --git a/env/Android.bp b/env/Android.bp
index 90c6047..c6a97b1 100644
--- a/env/Android.bp
+++ b/env/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-env",
     pkgPath: "android/soong/env",
diff --git a/etc/Android.bp b/etc/Android.bp
index cfd303e..cab7389 100644
--- a/etc/Android.bp
+++ b/etc/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-etc",
     pkgPath: "android/soong/etc",
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index 9994241..42a4c88 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-filesystem",
     pkgPath: "android/soong/filesystem",
diff --git a/finder/Android.bp b/finder/Android.bp
index a5d7fd4..a3df6ec 100644
--- a/finder/Android.bp
+++ b/finder/Android.bp
@@ -16,6 +16,10 @@
 // fast, parallel, caching implementation of `find`
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 subdirs = [
     "cmd",
 ]
diff --git a/finder/cmd/Android.bp b/finder/cmd/Android.bp
index e066c39..32843a0 100644
--- a/finder/cmd/Android.bp
+++ b/finder/cmd/Android.bp
@@ -16,6 +16,10 @@
 // fast, parallel, caching implementation of `find`
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "finder",
     srcs: [
diff --git a/finder/fs/Android.bp b/finder/fs/Android.bp
index 85929ae..14bdb30 100644
--- a/finder/fs/Android.bp
+++ b/finder/fs/Android.bp
@@ -16,6 +16,21 @@
 // mock filesystem
 //
 
+package {
+    default_applicable_licenses: [
+        "Android-Apache-2.0",
+        "build_soong_finder_fs_license",
+    ],
+}
+
+license {
+    name: "build_soong_finder_fs_license",
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+    ],
+    license_text: ["LICENSE"],
+}
+
 bootstrap_go_package {
     name: "soong-finder-fs",
     pkgPath: "android/soong/finder/fs",
diff --git a/finder/fs/LICENSE b/finder/fs/LICENSE
new file mode 100644
index 0000000..e5c5baf
--- /dev/null
+++ b/finder/fs/LICENSE
@@ -0,0 +1,28 @@
+Copyright 2009, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of the Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/genrule/Android.bp b/genrule/Android.bp
index 0e27d4e..214940d 100644
--- a/genrule/Android.bp
+++ b/genrule/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-genrule",
     pkgPath: "android/soong/genrule",
diff --git a/jar/Android.bp b/jar/Android.bp
index 2563474..46113d8 100644
--- a/jar/Android.bp
+++ b/jar/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-jar",
     pkgPath: "android/soong/jar",
diff --git a/java/Android.bp b/java/Android.bp
index 364566a..9bfd009 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-java",
     pkgPath: "android/soong/java",
diff --git a/java/aar.go b/java/aar.go
index e3ad252..ac7ae25 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -28,7 +28,6 @@
 )
 
 type AndroidLibraryDependency interface {
-	Dependency
 	ExportPackage() android.Path
 	ExportedProguardFlagFiles() android.Paths
 	ExportedRRODirs() []rroDir
@@ -796,9 +795,13 @@
 
 	aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
 		linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil)
-}
 
-var _ Dependency = (*AARImport)(nil)
+	ctx.SetProvider(JavaInfoProvider, JavaInfo{
+		HeaderJars:                     android.PathsIfNonNil(a.classpathFile),
+		ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
+		ImplementationJars:             android.PathsIfNonNil(a.classpathFile),
+	})
+}
 
 func (a *AARImport) HeaderJars() android.Paths {
 	return android.Paths{a.classpathFile}
diff --git a/java/boot_image.go b/java/boot_image.go
index 0a525b7..8a1e3c9 100644
--- a/java/boot_image.go
+++ b/java/boot_image.go
@@ -90,6 +90,10 @@
 		// The dex2oat tool is only needed for building and is not required in the apex.
 		return false
 	}
+	if android.IsMetaDependencyTag(tag) {
+		// Cross-cutting metadata dependencies are metadata.
+		return false
+	}
 	panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
 }
 
diff --git a/java/config/Android.bp b/java/config/Android.bp
index 1983521..194e2c6 100644
--- a/java/config/Android.bp
+++ b/java/config/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-java-config",
     pkgPath: "android/soong/java/config",
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 4914d74..ee7d018 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -97,15 +97,15 @@
 	}
 
 	ctx.VisitDirectDepsWithTag(deviceHostConverterDepTag, func(m android.Module) {
-		if dep, ok := m.(Dependency); ok {
-			d.headerJars = append(d.headerJars, dep.HeaderJars()...)
-			d.implementationJars = append(d.implementationJars, dep.ImplementationJars()...)
-			d.implementationAndResourceJars = append(d.implementationAndResourceJars, dep.ImplementationAndResourcesJars()...)
-			d.resourceJars = append(d.resourceJars, dep.ResourceJars()...)
+		if ctx.OtherModuleHasProvider(m, JavaInfoProvider) {
+			dep := ctx.OtherModuleProvider(m, JavaInfoProvider).(JavaInfo)
+			d.headerJars = append(d.headerJars, dep.HeaderJars...)
+			d.implementationJars = append(d.implementationJars, dep.ImplementationJars...)
+			d.implementationAndResourceJars = append(d.implementationAndResourceJars, dep.ImplementationAndResourcesJars...)
+			d.resourceJars = append(d.resourceJars, dep.ResourceJars...)
 
-			srcJarArgs, srcJarDeps := dep.SrcJarArgs()
-			d.srcJarArgs = append(d.srcJarArgs, srcJarArgs...)
-			d.srcJarDeps = append(d.srcJarDeps, srcJarDeps...)
+			d.srcJarArgs = append(d.srcJarArgs, dep.SrcJarArgs...)
+			d.srcJarDeps = append(d.srcJarDeps, dep.SrcJarDeps...)
 		} else {
 			ctx.PropertyErrorf("libs", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
 		}
@@ -131,9 +131,16 @@
 		d.combinedHeaderJar = d.headerJars[0]
 	}
 
-}
+	ctx.SetProvider(JavaInfoProvider, JavaInfo{
+		HeaderJars:                     d.headerJars,
+		ImplementationAndResourcesJars: d.implementationAndResourceJars,
+		ImplementationJars:             d.implementationJars,
+		ResourceJars:                   d.resourceJars,
+		SrcJarArgs:                     d.srcJarArgs,
+		SrcJarDeps:                     d.srcJarDeps,
+	})
 
-var _ Dependency = (*DeviceHostConverter)(nil)
+}
 
 func (d *DeviceHostConverter) HeaderJars() android.Paths {
 	return d.headerJars
diff --git a/java/dex.go b/java/dex.go
index 24600c2..e52fdb5 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -204,8 +204,9 @@
 	// - prevent ProGuard stripping subclass in the support library that extends class added in the higher SDK version.
 	// See b/20667396
 	var proguardRaiseDeps classpath
-	ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(dep android.Module) {
-		proguardRaiseDeps = append(proguardRaiseDeps, dep.(Dependency).HeaderJars()...)
+	ctx.VisitDirectDepsWithTag(proguardRaiseTag, func(m android.Module) {
+		dep := ctx.OtherModuleProvider(m, JavaInfoProvider).(JavaInfo)
+		proguardRaiseDeps = append(proguardRaiseDeps, dep.HeaderJars...)
 	})
 
 	r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars"))
diff --git a/java/droiddoc.go b/java/droiddoc.go
index c74009e..8f1644c 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -470,8 +470,9 @@
 
 		switch tag {
 		case bootClasspathTag:
-			if dep, ok := module.(Dependency); ok {
-				deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
+			if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+				dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+				deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars...)
 			} else if sm, ok := module.(SystemModulesProvider); ok {
 				// A system modules dependency has been added to the bootclasspath
 				// so add its libs to the bootclasspath.
@@ -480,23 +481,23 @@
 				panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
 			}
 		case libTag:
-			switch dep := module.(type) {
-			case SdkLibraryDependency:
+			if dep, ok := module.(SdkLibraryDependency); ok {
 				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
-			case Dependency:
-				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
-				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
-			case android.SourceFileProducer:
+			} else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+				dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+				deps.classpath = append(deps.classpath, dep.HeaderJars...)
+				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
+			} else if dep, ok := module.(android.SourceFileProducer); ok {
 				checkProducesJars(ctx, dep)
 				deps.classpath = append(deps.classpath, dep.Srcs()...)
-			default:
+			} else {
 				ctx.ModuleErrorf("depends on non-java module %q", otherName)
 			}
 		case java9LibTag:
-			switch dep := module.(type) {
-			case Dependency:
-				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
-			default:
+			if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+				dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
+			} else {
 				ctx.ModuleErrorf("depends on non-java module %q", otherName)
 			}
 		case systemModulesTag:
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 069595e..1651c1c 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -28,9 +28,27 @@
 }, "outFlag", "stubAPIFlags")
 
 type hiddenAPI struct {
-	// True if the module containing this structure contributes to the hiddenapi information.
+	// The name of the module as it would be used in the boot jars configuration, e.g. without any
+	// prebuilt_ prefix (if it is a prebuilt), without any "-hiddenapi" suffix if it just provides
+	// annotations and without any ".impl" suffix if it is a java_sdk_library implementation library.
+	configurationName string
+
+	// True if the module containing this structure contributes to the hiddenapi information or has
+	// that information encoded within it.
 	active bool
 
+	// Identifies the active module variant which will be used as the source of hiddenapi information.
+	//
+	// A class may be compiled into a number of different module variants each of which will need the
+	// hiddenapi information encoded into it and so will be marked as active. However, only one of
+	// them must be used as a source of information by hiddenapi otherwise it will end up with
+	// duplicate entries. That module will have primary=true.
+	//
+	// Note, that modules <x>-hiddenapi that provide additional annotation information for module <x>
+	// that is on the bootclasspath are marked as primary=true as they are the primary source of that
+	// annotation information.
+	primary bool
+
 	// True if the module only contains additional annotations and so does not require hiddenapi
 	// information to be encoded in its dex file and should not be used to generate the
 	// hiddenAPISingletonPathsStruct.stubFlags file.
@@ -109,18 +127,45 @@
 
 	// Modules whose names are of the format <x>-hiddenapi provide hiddenapi information for the boot
 	// jar module <x>. Otherwise, the module provides information for itself. Either way extract the
-	// name of the boot jar module.
-	bootJarName := strings.TrimSuffix(name, "-hiddenapi")
+	// configurationName of the boot jar module.
+	configurationName := strings.TrimSuffix(name, "-hiddenapi")
+	h.configurationName = configurationName
 
 	// It is important that hiddenapi information is only gathered for/from modules that are actually
 	// on the boot jars list because the runtime only enforces access to the hidden API for the
 	// bootclassloader. If information is gathered for modules not on the list then that will cause
 	// failures in the CtsHiddenApiBlocklist... tests.
-	h.active = inList(bootJarName, ctx.Config().BootJars())
+	h.active = inList(configurationName, ctx.Config().BootJars())
+	if !h.active {
+		// The rest of the properties will be ignored if active is false.
+		return
+	}
 
 	// If this module has a suffix of -hiddenapi then it only provides additional annotation
 	// information for a module on the boot jars list.
 	h.annotationsOnly = strings.HasSuffix(name, "-hiddenapi")
+
+	// Determine whether this module is the primary module or not.
+	primary := true
+
+	// A prebuilt module is only primary if it is preferred and conversely a source module is only
+	// primary if it has not been replaced by a prebuilt module.
+	module := ctx.Module()
+	if pi, ok := module.(android.PrebuiltInterface); ok {
+		if p := pi.Prebuilt(); p != nil {
+			primary = p.UsePrebuilt()
+		}
+	} else {
+		// The only module that will pass a different name to its module name to this method is the
+		// implementation library of a java_sdk_library. It has a configuration name of <x> the same
+		// as its parent java_sdk_library but a module name of <x>.impl. It is not the primary module,
+		// the java_sdk_library with the name of <x> is.
+		primary = name == ctx.ModuleName()
+
+		// A source module that has been replaced by a prebuilt can never be the primary module.
+		primary = primary && !module.IsReplacedByPrebuilt()
+	}
+	h.primary = primary
 }
 
 // hiddenAPIExtractAndEncode is called by any module that could contribute to the hiddenapi
@@ -137,17 +182,17 @@
 // 3. Conditionally creates a copy of the supplied dex file into which it has encoded the hiddenapi
 //    flags and returns this instead of the supplied dex jar, otherwise simply returns the supplied
 //    dex jar.
-func (h *hiddenAPI) hiddenAPIExtractAndEncode(ctx android.ModuleContext, name string, primary bool, dexJar android.OutputPath,
+func (h *hiddenAPI) hiddenAPIExtractAndEncode(ctx android.ModuleContext, dexJar android.OutputPath,
 	implementationJar android.Path, uncompressDex bool) android.OutputPath {
 
 	if !h.active {
 		return dexJar
 	}
 
-	h.hiddenAPIExtractInformation(ctx, dexJar, implementationJar, primary)
+	h.hiddenAPIExtractInformation(ctx, dexJar, implementationJar)
 
 	if !h.annotationsOnly {
-		hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", name+".jar").OutputPath
+		hiddenAPIJar := android.PathForModuleOut(ctx, "hiddenapi", h.configurationName+".jar").OutputPath
 
 		// Create a copy of the dex jar which has been encoded with hiddenapi flags.
 		hiddenAPIEncodeDex(ctx, hiddenAPIJar, dexJar, uncompressDex)
@@ -164,7 +209,7 @@
 //
 // It also makes the dex jar available for use when generating the
 // hiddenAPISingletonPathsStruct.stubFlags.
-func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJar, classesJar android.Path, primary bool) {
+func (h *hiddenAPI) hiddenAPIExtractInformation(ctx android.ModuleContext, dexJar, classesJar android.Path) {
 	if !h.active {
 		return
 	}
@@ -172,7 +217,7 @@
 	// More than one library with the same classes may need to be encoded but only one should be
 	// used as a source of information for hidden API processing otherwise it will result in
 	// duplicate entries in the files.
-	if !primary {
+	if !h.primary {
 		return
 	}
 
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 568d15f..6341a34 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -223,7 +223,7 @@
 
 	ctx.VisitAllModules(func(module android.Module) {
 		// Collect dex jar paths for the modules listed above.
-		if j, ok := module.(Dependency); ok {
+		if j, ok := module.(UsesLibraryDependency); ok {
 			name := ctx.ModuleName(module)
 			for moduleList, pathList := range moduleListToPathList {
 				if i := android.IndexList(name, *moduleList); i != -1 {
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 77cfff4..df825bb 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -84,6 +84,12 @@
 			compile_dex: true,
 		}
 
+		java_library {
+			name: "foo-hiddenapi",
+			srcs: ["a.java"],
+			compile_dex: true,
+		}
+
 		java_import {
 			name: "foo",
 			jars: ["a.jar"],
@@ -102,6 +108,7 @@
 	indexRule := hiddenAPIIndex.Rule("singleton-merged-hiddenapi-index")
 	CheckHiddenAPIRuleInputs(t, `
 .intermediates/bar/android_common/hiddenapi/index.csv
+.intermediates/foo-hiddenapi/android_common/hiddenapi/index.csv
 .intermediates/foo/android_common/hiddenapi/index.csv
 `,
 		indexRule)
diff --git a/java/java.go b/java/java.go
index d194ff7..338140b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -533,6 +533,53 @@
 
 var _ android.OutputFileProducer = (*Module)(nil)
 
+// JavaInfo contains information about a java module for use by modules that depend on it.
+type JavaInfo struct {
+	// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
+	// against this module.  If empty, ImplementationJars should be used instead.
+	HeaderJars android.Paths
+
+	// ImplementationAndResourceJars is a list of jars that contain the implementations of classes
+	// in the module as well as any resources included in the module.
+	ImplementationAndResourcesJars android.Paths
+
+	// ImplementationJars is a list of jars that contain the implementations of classes in the
+	//module.
+	ImplementationJars android.Paths
+
+	// ResourceJars is a list of jars that contain the resources included in the module.
+	ResourceJars android.Paths
+
+	// AidlIncludeDirs is a list of directories that should be passed to the aidl tool when
+	// depending on this module.
+	AidlIncludeDirs android.Paths
+
+	// SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this
+	// module.
+	SrcJarArgs []string
+
+	// SrcJarDeps is a list of paths to depend on when packaging the sources of this module.
+	SrcJarDeps android.Paths
+
+	// ExportedPlugins is a list of paths that should be used as annotation processors for any
+	// module that depends on this module.
+	ExportedPlugins android.Paths
+
+	// ExportedPluginClasses is a list of classes that should be run as annotation processors for
+	// any module that depends on this module.
+	ExportedPluginClasses []string
+
+	// ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs,
+	// requiring disbling turbine for any modules that depend on it.
+	ExportedPluginDisableTurbine bool
+
+	// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
+	// instrumented by jacoco.
+	JacocoReportClassesFile android.Path
+}
+
+var JavaInfoProvider = blueprint.NewProvider(JavaInfo{})
+
 // Methods that need to be implemented for a module that is added to apex java_libs property.
 type ApexDependency interface {
 	HeaderJars() android.Paths
@@ -546,18 +593,6 @@
 	ClassLoaderContexts() dexpreopt.ClassLoaderContextMap
 }
 
-type Dependency interface {
-	ApexDependency
-	UsesLibraryDependency
-	ImplementationJars() android.Paths
-	ResourceJars() android.Paths
-	AidlIncludeDirs() android.Paths
-	ExportedPlugins() (android.Paths, []string, bool)
-	SrcJarArgs() ([]string, android.Paths)
-	BaseModuleName() string
-	JacocoReportClassesFile() android.Path
-}
-
 type xref interface {
 	XrefJavaFiles() android.Paths
 }
@@ -1111,44 +1146,42 @@
 			return
 		}
 
-		switch dep := module.(type) {
-		case SdkLibraryDependency:
+		if dep, ok := module.(SdkLibraryDependency); ok {
 			switch tag {
 			case libTag:
 				deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
 			case staticLibTag:
 				ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
 			}
-		case Dependency:
+		} else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+			dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
 			switch tag {
 			case bootClasspathTag:
-				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
+				deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
 			case libTag, instrumentationForTag:
-				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
-				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
-				pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins()
-				addPlugins(&deps, pluginJars, pluginClasses...)
-				deps.disableTurbine = deps.disableTurbine || disableTurbine
+				deps.classpath = append(deps.classpath, dep.HeaderJars...)
+				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
+				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
+				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
 			case java9LibTag:
-				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
+				deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
 			case staticLibTag:
-				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
-				deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
-				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
-				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
-				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
-				pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins()
-				addPlugins(&deps, pluginJars, pluginClasses...)
+				deps.classpath = append(deps.classpath, dep.HeaderJars...)
+				deps.staticJars = append(deps.staticJars, dep.ImplementationJars...)
+				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...)
+				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...)
+				deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
+				addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
 				// Turbine doesn't run annotation processors, so any module that uses an
 				// annotation processor that generates API is incompatible with the turbine
 				// optimization.
-				deps.disableTurbine = deps.disableTurbine || disableTurbine
+				deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
 			case pluginTag:
-				if plugin, ok := dep.(*Plugin); ok {
+				if plugin, ok := module.(*Plugin); ok {
 					if plugin.pluginProperties.Processor_class != nil {
-						addPlugins(&deps, plugin.ImplementationAndResourcesJars(), *plugin.pluginProperties.Processor_class)
+						addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class)
 					} else {
-						addPlugins(&deps, plugin.ImplementationAndResourcesJars())
+						addPlugins(&deps, dep.ImplementationAndResourcesJars)
 					}
 					// Turbine doesn't run annotation processors, so any module that uses an
 					// annotation processor that generates API is incompatible with the turbine
@@ -1158,14 +1191,14 @@
 					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
 				}
 			case errorpronePluginTag:
-				if plugin, ok := dep.(*Plugin); ok {
-					deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, plugin.ImplementationAndResourcesJars()...)
+				if _, ok := module.(*Plugin); ok {
+					deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...)
 				} else {
 					ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
 				}
 			case exportedPluginTag:
-				if plugin, ok := dep.(*Plugin); ok {
-					j.exportedPluginJars = append(j.exportedPluginJars, plugin.ImplementationAndResourcesJars()...)
+				if plugin, ok := module.(*Plugin); ok {
+					j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...)
 					if plugin.pluginProperties.Processor_class != nil {
 						j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class)
 					}
@@ -1177,12 +1210,11 @@
 					ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
 				}
 			case kotlinStdlibTag:
-				deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars()...)
+				deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars...)
 			case kotlinAnnotationsTag:
-				deps.kotlinAnnotations = dep.HeaderJars()
+				deps.kotlinAnnotations = dep.HeaderJars
 			}
-
-		case android.SourceFileProducer:
+		} else if dep, ok := module.(android.SourceFileProducer); ok {
 			switch tag {
 			case libTag:
 				checkProducesJars(ctx, dep)
@@ -1193,7 +1225,7 @@
 				deps.staticJars = append(deps.staticJars, dep.Srcs()...)
 				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
 			}
-		default:
+		} else {
 			switch tag {
 			case bootClasspathTag:
 				// If a system modules dependency has been added to the bootclasspath
@@ -1798,14 +1830,8 @@
 			return
 		}
 
-		configurationName := j.ConfigurationName()
-		primary := configurationName == ctx.ModuleName()
-		// If the prebuilt is being used rather than the from source, skip this
-		// module to prevent duplicated classes
-		primary = primary && !j.IsReplacedByPrebuilt()
-
 		// Hidden API CSV generation and dex encoding
-		dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, configurationName, primary, dexOutputFile, j.implementationJarFile,
+		dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, j.implementationJarFile,
 			proptools.Bool(j.dexProperties.Uncompress_dex))
 
 		// merge dex jar with resources if necessary
@@ -1866,6 +1892,20 @@
 
 	ctx.CheckbuildFile(outputFile)
 
+	ctx.SetProvider(JavaInfoProvider, JavaInfo{
+		HeaderJars:                     android.PathsIfNonNil(j.headerJarFile),
+		ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
+		ImplementationJars:             android.PathsIfNonNil(j.implementationJarFile),
+		ResourceJars:                   android.PathsIfNonNil(j.resourceJar),
+		AidlIncludeDirs:                j.exportAidlIncludeDirs,
+		SrcJarArgs:                     j.srcJarArgs,
+		SrcJarDeps:                     j.srcJarDeps,
+		ExportedPlugins:                j.exportedPluginJars,
+		ExportedPluginClasses:          j.exportedPluginClasses,
+		ExportedPluginDisableTurbine:   j.exportedDisableTurbine,
+		JacocoReportClassesFile:        j.jacocoReportClassesFile,
+	})
+
 	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
 	j.outputFile = outputFile.WithoutRel()
 }
@@ -1973,8 +2013,6 @@
 	return instrumentedJar
 }
 
-var _ Dependency = (*Module)(nil)
-
 func (j *Module) HeaderJars() android.Paths {
 	if j.headerJarFile == nil {
 		return nil
@@ -2886,15 +2924,15 @@
 	ctx.VisitDirectDeps(func(module android.Module) {
 		tag := ctx.OtherModuleDependencyTag(module)
 
-		switch dep := module.(type) {
-		case Dependency:
+		if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
+			dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
 			switch tag {
 			case libTag, staticLibTag:
-				flags.classpath = append(flags.classpath, dep.HeaderJars()...)
+				flags.classpath = append(flags.classpath, dep.HeaderJars...)
 			case bootClasspathTag:
-				flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars()...)
+				flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)
 			}
-		case SdkLibraryDependency:
+		} else if dep, ok := module.(SdkLibraryDependency); ok {
 			switch tag {
 			case libTag:
 				flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
@@ -2917,9 +2955,6 @@
 	j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
 
 	if ctx.Device() {
-		configurationName := j.BaseModuleName()
-		primary := j.Prebuilt().UsePrebuilt()
-
 		// If this is a variant created for a prebuilt_apex then use the dex implementation jar
 		// obtained from the associated deapexer module.
 		ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
@@ -2935,7 +2970,7 @@
 			di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
 			if dexOutputPath := di.PrebuiltExportPath(j.BaseModuleName(), ".dexjar"); dexOutputPath != nil {
 				j.dexJarFile = dexOutputPath
-				j.hiddenAPI.hiddenAPIExtractInformation(ctx, dexOutputPath, outputFile, primary)
+				j.hiddenAPIExtractInformation(ctx, dexOutputPath, outputFile)
 			} else {
 				// This should never happen as a variant for a prebuilt_apex is only created if the
 				// prebuilt_apex has been configured to export the java library dex file.
@@ -2967,12 +3002,19 @@
 			}
 
 			// Hidden API CSV generation and dex encoding
-			dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, configurationName, primary, dexOutputFile, outputFile,
+			dexOutputFile = j.hiddenAPIExtractAndEncode(ctx, dexOutputFile, outputFile,
 				proptools.Bool(j.dexProperties.Uncompress_dex))
 
 			j.dexJarFile = dexOutputFile
 		}
 	}
+
+	ctx.SetProvider(JavaInfoProvider, JavaInfo{
+		HeaderJars:                     android.PathsIfNonNil(j.combinedClasspathFile),
+		ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
+		ImplementationJars:             android.PathsIfNonNil(j.combinedClasspathFile),
+		AidlIncludeDirs:                j.exportAidlIncludeDirs,
+	})
 }
 
 func (j *Import) OutputFiles(tag string) (android.Paths, error) {
@@ -2986,8 +3028,6 @@
 
 var _ android.OutputFileProducer = (*Import)(nil)
 
-var _ Dependency = (*Import)(nil)
-
 func (j *Import) HeaderJars() android.Paths {
 	if j.combinedClasspathFile == nil {
 		return nil
@@ -3333,6 +3373,7 @@
 		&android.ApexProperties{},
 		&RuntimeResourceOverlayProperties{},
 		&LintProperties{},
+		&appTestHelperAppProperties{},
 	)
 
 	android.InitDefaultsModule(module)
diff --git a/java/jdeps.go b/java/jdeps.go
index 2b5ee74..0ab2e42 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -87,8 +87,9 @@
 			dpInfo.Classes = append(dpInfo.Classes, data.Class)
 		}
 
-		if dep, ok := module.(Dependency); ok {
-			dpInfo.Installed_paths = append(dpInfo.Installed_paths, dep.ImplementationJars().Strings()...)
+		if ctx.ModuleHasProvider(module, JavaInfoProvider) {
+			dep := ctx.ModuleProvider(module, JavaInfoProvider).(JavaInfo)
+			dpInfo.Installed_paths = append(dpInfo.Installed_paths, dep.ImplementationJars.Strings()...)
 		}
 		dpInfo.Classes = android.FirstUniqueStrings(dpInfo.Classes)
 		dpInfo.Installed_paths = android.FirstUniqueStrings(dpInfo.Installed_paths)
diff --git a/java/lint.go b/java/lint.go
index cd2a904..c9e0cdd 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -276,8 +276,9 @@
 
 	extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
 	for _, extraLintCheckModule := range extraLintCheckModules {
-		if dep, ok := extraLintCheckModule.(Dependency); ok {
-			l.extraLintCheckJars = append(l.extraLintCheckJars, dep.ImplementationAndResourcesJars()...)
+		if ctx.OtherModuleHasProvider(extraLintCheckModule, JavaInfoProvider) {
+			dep := ctx.OtherModuleProvider(extraLintCheckModule, JavaInfoProvider).(JavaInfo)
+			l.extraLintCheckJars = append(l.extraLintCheckJars, dep.ImplementationAndResourcesJars...)
 		} else {
 			ctx.PropertyErrorf("lint.extra_check_modules",
 				"%s is not a java module", ctx.OtherModuleName(extraLintCheckModule))
diff --git a/java/robolectric.go b/java/robolectric.go
index c821e5b..98bb710 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -148,10 +148,10 @@
 	}
 
 	for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
-		m := dep.(Dependency)
-		r.libs = append(r.libs, m.BaseModuleName())
-		if !android.InList(m.BaseModuleName(), config.FrameworkLibraries) {
-			combinedJarJars = append(combinedJarJars, m.ImplementationAndResourcesJars()...)
+		m := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
+		r.libs = append(r.libs, ctx.OtherModuleName(dep))
+		if !android.InList(ctx.OtherModuleName(dep), config.FrameworkLibraries) {
+			combinedJarJars = append(combinedJarJars, m.ImplementationAndResourcesJars...)
 		}
 	}
 
@@ -245,10 +245,10 @@
 	srcJarDeps := append(android.Paths(nil), instrumentedApp.srcJarDeps...)
 
 	for _, m := range ctx.GetDirectDepsWithTag(roboCoverageLibsTag) {
-		if dep, ok := m.(Dependency); ok {
-			depSrcJarArgs, depSrcJarDeps := dep.SrcJarArgs()
-			srcJarArgs = append(srcJarArgs, depSrcJarArgs...)
-			srcJarDeps = append(srcJarDeps, depSrcJarDeps...)
+		if ctx.OtherModuleHasProvider(m, JavaInfoProvider) {
+			dep := ctx.OtherModuleProvider(m, JavaInfoProvider).(JavaInfo)
+			srcJarArgs = append(srcJarArgs, dep.SrcJarArgs...)
+			srcJarDeps = append(srcJarDeps, dep.SrcJarDeps...)
 		}
 	}
 
diff --git a/java/sdk.go b/java/sdk.go
index a68abfb..7290711 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -566,10 +566,11 @@
 
 	ctx.VisitAllModules(func(module android.Module) {
 		// Collect dex jar paths for the modules listed above.
-		if j, ok := module.(Dependency); ok {
+		if ctx.ModuleHasProvider(module, JavaInfoProvider) {
+			j := ctx.ModuleProvider(module, JavaInfoProvider).(JavaInfo)
 			name := ctx.ModuleName(module)
 			if i := android.IndexList(name, stubsModules); i != -1 {
-				stubsJars[i] = j.HeaderJars()
+				stubsJars[i] = j.HeaderJars
 			}
 		}
 	})
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 638740f..aa96e0d 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -60,12 +60,12 @@
 	apiScope *apiScope
 
 	// Function for extracting appropriate path information from the dependency.
-	depInfoExtractor func(paths *scopePaths, dep android.Module) error
+	depInfoExtractor func(paths *scopePaths, ctx android.ModuleContext, dep android.Module) error
 }
 
 // Extract tag specific information from the dependency.
 func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.Module, paths *scopePaths) {
-	err := tag.depInfoExtractor(paths, dep)
+	err := tag.depInfoExtractor(paths, ctx, dep)
 	if err != nil {
 		ctx.ModuleErrorf("has an invalid {scopeDependencyTag: %s} dependency on module %s: %s", tag.name, ctx.OtherModuleName(dep), err.Error())
 	}
@@ -539,13 +539,14 @@
 	stubsSrcJar android.OptionalPath
 }
 
-func (paths *scopePaths) extractStubsLibraryInfoFromDependency(dep android.Module) error {
-	if lib, ok := dep.(Dependency); ok {
-		paths.stubsHeaderPath = lib.HeaderJars()
-		paths.stubsImplPath = lib.ImplementationJars()
+func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
+	if ctx.OtherModuleHasProvider(dep, JavaInfoProvider) {
+		lib := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
+		paths.stubsHeaderPath = lib.HeaderJars
+		paths.stubsImplPath = lib.ImplementationJars
 		return nil
 	} else {
-		return fmt.Errorf("expected module that implements Dependency, e.g. java_library")
+		return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
 	}
 }
 
@@ -572,7 +573,7 @@
 	paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath())
 }
 
-func (paths *scopePaths) extractApiInfoFromDep(dep android.Module) error {
+func (paths *scopePaths) extractApiInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
 	return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
 		paths.extractApiInfoFromApiStubsProvider(provider)
 	})
@@ -582,13 +583,13 @@
 	paths.stubsSrcJar = android.OptionalPathForPath(provider.StubsSrcJar())
 }
 
-func (paths *scopePaths) extractStubsSourceInfoFromDep(dep android.Module) error {
+func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
 	return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) {
 		paths.extractStubsSourceInfoFromApiStubsProviders(provider)
 	})
 }
 
-func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(dep android.Module) error {
+func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.Module) error {
 	return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
 		paths.extractApiInfoFromApiStubsProvider(provider)
 		paths.extractStubsSourceInfoFromApiStubsProviders(provider)
@@ -951,7 +952,6 @@
 	commonToSdkLibraryAndImport
 }
 
-var _ Dependency = (*SdkLibrary)(nil)
 var _ SdkLibraryDependency = (*SdkLibrary)(nil)
 
 func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
diff --git a/java/system_modules.go b/java/system_modules.go
index 5cc546d..95f71b8 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -160,8 +160,8 @@
 	var jars android.Paths
 
 	ctx.VisitDirectDepsWithTag(systemModulesLibsTag, func(module android.Module) {
-		dep, _ := module.(Dependency)
-		jars = append(jars, dep.HeaderJars()...)
+		dep, _ := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+		jars = append(jars, dep.HeaderJars...)
 	})
 
 	system.headerJars = jars
diff --git a/kernel/Android.bp b/kernel/Android.bp
index f8a48d9..91e7490 100644
--- a/kernel/Android.bp
+++ b/kernel/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-kernel",
     pkgPath: "android/soong/kernel",
diff --git a/licenses/Android.bp b/licenses/Android.bp
index f4a76d7..c70d6bd 100644
--- a/licenses/Android.bp
+++ b/licenses/Android.bp
@@ -307,10 +307,7 @@
 
 license_kind {
     name: "SPDX-license-identifier-Beerware",
-    conditions: [
-        "by_exception_only",
-        "not_allowed",
-    ],
+    conditions: ["notice"],
     url: "https://spdx.org/licenses/Beerware.html",
 }
 
@@ -1137,10 +1134,7 @@
 
 license_kind {
     name: "SPDX-license-identifier-WTFPL",
-    conditions: [
-        "by_exception_only",
-        "not_allowed",
-    ],
+    conditions: ["notice"],
     url: "https://spdx.org/licenses/WTFPL.html",
 }
 
diff --git a/linkerconfig/Android.bp b/linkerconfig/Android.bp
index 8807a2e..9161f0e 100644
--- a/linkerconfig/Android.bp
+++ b/linkerconfig/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-linkerconfig",
     pkgPath: "android/soong/linkerconfig",
diff --git a/linkerconfig/proto/Android.bp b/linkerconfig/proto/Android.bp
index 4d97128..3b1e4ab 100644
--- a/linkerconfig/proto/Android.bp
+++ b/linkerconfig/proto/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 cc_library_static {
     name: "lib_linker_config_proto_lite",
     host_supported: true,
diff --git a/makedeps/Android.bp b/makedeps/Android.bp
index b77b08f..62bdfd5 100644
--- a/makedeps/Android.bp
+++ b/makedeps/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-makedeps",
     pkgPath: "android/soong/makedeps",
diff --git a/partner/Android.bp b/partner/Android.bp
index f2ced8d..7fc873e 100644
--- a/partner/Android.bp
+++ b/partner/Android.bp
@@ -16,6 +16,10 @@
 // Sample project for creating an extended androidmk
 //
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "partner_androidmk",
     srcs: [
diff --git a/phony/Android.bp b/phony/Android.bp
index 2c423ef..db5efc9 100644
--- a/phony/Android.bp
+++ b/phony/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-phony",
     pkgPath: "android/soong/phony",
diff --git a/python/Android.bp b/python/Android.bp
index ffd03fe..b633f1e 100644
--- a/python/Android.bp
+++ b/python/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-python",
     pkgPath: "android/soong/python",
diff --git a/python/tests/Android.bp b/python/tests/Android.bp
index c8bf420..0e8eef6 100644
--- a/python/tests/Android.bp
+++ b/python/tests/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 python_test_host {
     name: "par_test",
     main: "par_test.py",
diff --git a/remoteexec/Android.bp b/remoteexec/Android.bp
index fc2c0e3..9f75df5 100644
--- a/remoteexec/Android.bp
+++ b/remoteexec/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-remoteexec",
     pkgPath: "android/soong/remoteexec",
diff --git a/rust/Android.bp b/rust/Android.bp
index ad3040a..8b2aa30 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-rust",
     pkgPath: "android/soong/rust",
diff --git a/rust/compiler.go b/rust/compiler.go
index e4120d0..c26f208 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -258,7 +258,7 @@
 	if !Bool(compiler.Properties.No_stdlibs) {
 		for _, stdlib := range config.Stdlibs {
 			// If we're building for the primary arch of the build host, use the compiler's stdlibs
-			if ctx.Target().Os == android.BuildOs && ctx.TargetPrimary() {
+			if ctx.Target().Os == android.BuildOs {
 				stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
 			}
 
diff --git a/rust/config/Android.bp b/rust/config/Android.bp
index 1f0109f..5b121c3 100644
--- a/rust/config/Android.bp
+++ b/rust/config/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-rust-config",
     pkgPath: "android/soong/rust/config",
diff --git a/rust/test.go b/rust/test.go
index 3fa5f95..6caa7b1 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -15,6 +15,8 @@
 package rust
 
 import (
+	"github.com/google/blueprint/proptools"
+
 	"android/soong/android"
 	"android/soong/tradefed"
 )
@@ -127,6 +129,9 @@
 		ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set")
 	}
 
+	if ctx.Host() && test.Properties.Test_options.Unit_test == nil {
+		test.Properties.Test_options.Unit_test = proptools.BoolPtr(true)
+	}
 	test.binaryDecorator.install(ctx)
 }
 
diff --git a/rust/testing.go b/rust/testing.go
index 4c4df4a..1afe27e 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -46,6 +46,30 @@
 				sysroot: true,
 		}
 		rust_prebuilt_library {
+				name: "libstd_i686-unknown-linux-gnu",
+                                crate_name: "std",
+                                rlib: {
+                                    srcs: ["libstd.rlib"],
+                                },
+                                dylib: {
+                                    srcs: ["libstd.so"],
+                                },
+				host_supported: true,
+				sysroot: true,
+		}
+		rust_prebuilt_library {
+				name: "libtest_i686-unknown-linux-gnu",
+                                crate_name: "test",
+                                rlib: {
+                                    srcs: ["libtest.rlib"],
+                                },
+                                dylib: {
+                                    srcs: ["libtest.so"],
+                                },
+				host_supported: true,
+				sysroot: true,
+		}
+		rust_prebuilt_library {
 				name: "libstd_x86_64-apple-darwin",
                                 crate_name: "std",
                                 rlib: {
diff --git a/scripts/Android.bp b/scripts/Android.bp
index dd03f28..b9163cc 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 python_binary_host {
     name: "check_boot_jars",
     main: "check_boot_jars/check_boot_jars.py",
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index b8485ea..ac67438 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -26,6 +26,8 @@
   platform-mainline-test-exports
   runtime-module-host-exports
   runtime-module-sdk
+  stats-log-api-gen-exports
+  statsd-module-sdk
   tzdata-module-test-exports
 )
 
diff --git a/sdk/Android.bp b/sdk/Android.bp
index cb93351..8a3119c 100644
--- a/sdk/Android.bp
+++ b/sdk/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-sdk",
     pkgPath: "android/soong/sdk",
diff --git a/sh/Android.bp b/sh/Android.bp
index e5ffeef..f9198dc 100644
--- a/sh/Android.bp
+++ b/sh/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-sh",
     pkgPath: "android/soong/sh",
diff --git a/shared/Android.bp b/shared/Android.bp
index 2a4f56f..5aa9d54 100644
--- a/shared/Android.bp
+++ b/shared/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-shared",
     pkgPath: "android/soong/shared",
diff --git a/symbol_inject/Android.bp b/symbol_inject/Android.bp
index 8308043..7180248 100644
--- a/symbol_inject/Android.bp
+++ b/symbol_inject/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-symbol_inject",
     pkgPath: "android/soong/symbol_inject",
diff --git a/symbol_inject/cmd/Android.bp b/symbol_inject/cmd/Android.bp
index ee2f259..ac23f00 100644
--- a/symbol_inject/cmd/Android.bp
+++ b/symbol_inject/cmd/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "symbol_inject",
     deps: ["soong-symbol_inject"],
diff --git a/sysprop/Android.bp b/sysprop/Android.bp
index 48094f1..540a8da 100644
--- a/sysprop/Android.bp
+++ b/sysprop/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-sysprop",
     pkgPath: "android/soong/sysprop",
diff --git a/third_party/zip/Android.bp b/third_party/zip/Android.bp
index ec89c0c..f279d12 100644
--- a/third_party/zip/Android.bp
+++ b/third_party/zip/Android.bp
@@ -12,6 +12,21 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: [
+        "Android-Apache-2.0",
+        "build_soong_third_party_zip_license",
+    ],
+}
+
+license {
+    name: "build_soong_third_party_zip_license",
+    license_kinds: [
+        "SPDX-license-identifier-BSD",
+    ],
+    license_text: ["LICENSE"],
+}
+
 bootstrap_go_package {
     name: "android-archive-zip",
     pkgPath: "android/soong/third_party/zip",
diff --git a/third_party/zip/LICENSE b/third_party/zip/LICENSE
new file mode 100644
index 0000000..e5c5baf
--- /dev/null
+++ b/third_party/zip/LICENSE
@@ -0,0 +1,28 @@
+Copyright 2009, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of the Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tradefed/Android.bp b/tradefed/Android.bp
index 4e4e6a7..f0336a3 100644
--- a/tradefed/Android.bp
+++ b/tradefed/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-tradefed",
     pkgPath: "android/soong/tradefed",
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index c314b7b..32b6eda 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-ui-build-paths",
     pkgPath: "android/soong/ui/build/paths",
diff --git a/ui/logger/Android.bp b/ui/logger/Android.bp
index 8091ef9..269a5a0 100644
--- a/ui/logger/Android.bp
+++ b/ui/logger/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-ui-logger",
     pkgPath: "android/soong/ui/logger",
diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp
index 95c8f5c..c428ec4 100644
--- a/ui/metrics/Android.bp
+++ b/ui/metrics/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-ui-metrics",
     pkgPath: "android/soong/ui/metrics",
diff --git a/ui/metrics/proc/Android.bp b/ui/metrics/proc/Android.bp
index 32d8217..4501fed 100644
--- a/ui/metrics/proc/Android.bp
+++ b/ui/metrics/proc/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-ui-metrics-proc",
     pkgPath: "android/soong/ui/metrics/proc",
diff --git a/ui/status/Android.bp b/ui/status/Android.bp
index 19e5a2a..ac31390 100644
--- a/ui/status/Android.bp
+++ b/ui/status/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-ui-status",
     pkgPath: "android/soong/ui/status",
diff --git a/ui/terminal/Android.bp b/ui/terminal/Android.bp
index aa6e35d..fdf300f 100644
--- a/ui/terminal/Android.bp
+++ b/ui/terminal/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-ui-terminal",
     pkgPath: "android/soong/ui/terminal",
diff --git a/ui/tracer/Android.bp b/ui/tracer/Android.bp
index af588f1..d8942fd 100644
--- a/ui/tracer/Android.bp
+++ b/ui/tracer/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-ui-tracer",
     pkgPath: "android/soong/ui/tracer",
diff --git a/xml/Android.bp b/xml/Android.bp
index cd25cff..a5e5f4c 100644
--- a/xml/Android.bp
+++ b/xml/Android.bp
@@ -1,3 +1,7 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 bootstrap_go_package {
     name: "soong-xml",
     pkgPath: "android/soong/xml",
diff --git a/zip/Android.bp b/zip/Android.bp
index 5081e91..b28adbd 100644
--- a/zip/Android.bp
+++ b/zip/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 subdirs = ["cmd"]
 
 bootstrap_go_package {
diff --git a/zip/cmd/Android.bp b/zip/cmd/Android.bp
index 6029a69..43bf232 100644
--- a/zip/cmd/Android.bp
+++ b/zip/cmd/Android.bp
@@ -12,6 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
 blueprint_go_binary {
     name: "soong_zip",
     deps: [