Merge "rust: Migrate default edition to 2021"
diff --git a/android/deapexer.go b/android/deapexer.go
index bed6574..265f531 100644
--- a/android/deapexer.go
+++ b/android/deapexer.go
@@ -143,12 +143,16 @@
 }
 
 // FindDeapexerProviderForModule searches through the direct dependencies of the current context
-// module for a DeapexerTag dependency and returns its DeapexerInfo. If there is an error then it is
-// reported with ctx.ModuleErrorf and nil is returned.
+// module for a DeapexerTag dependency and returns its DeapexerInfo. If a single nonambiguous
+// deapexer module isn't found then errors are reported with ctx.ModuleErrorf and nil is returned.
 func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo {
 	var di *DeapexerInfo
 	ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) {
 		p := ctx.OtherModuleProvider(m, DeapexerProvider).(DeapexerInfo)
+		if di != nil {
+			ctx.ModuleErrorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s",
+				di.ApexModuleName(), p.ApexModuleName())
+		}
 		di = &p
 	})
 	if di != nil {
diff --git a/apex/apex.go b/apex/apex.go
index 0a785f3..e5cee72 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -3270,7 +3270,7 @@
 	Updatable          bazel.BoolAttribute
 	Installable        bazel.BoolAttribute
 	Native_shared_libs bazel.LabelListAttribute
-	Binaries           bazel.StringListAttribute
+	Binaries           bazel.LabelListAttribute
 	Prebuilts          bazel.LabelListAttribute
 }
 
@@ -3329,8 +3329,8 @@
 	prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, prebuilts)
 	prebuiltsLabelListAttribute := bazel.MakeLabelListAttribute(prebuiltsLabelList)
 
-	binaries := module.properties.ApexNativeDependencies.Binaries
-	binariesStringListAttribute := bazel.MakeStringListAttribute(binaries)
+	binaries := android.BazelLabelForModuleDeps(ctx, module.properties.ApexNativeDependencies.Binaries)
+	binariesLabelListAttribute := bazel.MakeLabelListAttribute(binaries)
 
 	var updatableAttribute bazel.BoolAttribute
 	if module.properties.Updatable != nil {
@@ -3352,7 +3352,7 @@
 		Updatable:          updatableAttribute,
 		Installable:        installableAttribute,
 		Native_shared_libs: nativeSharedLibsLabelListAttribute,
-		Binaries:           binariesStringListAttribute,
+		Binaries:           binariesLabelListAttribute,
 		Prebuilts:          prebuiltsLabelListAttribute,
 	}
 
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 3cc312d..c71b6d0 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7045,6 +7045,75 @@
 	return result.TestContext
 }
 
+func TestDuplicateDeapexeresFromPrebuiltApexes(t *testing.T) {
+	preparers := android.GroupFixturePreparers(
+		java.PrepareForTestWithJavaDefaultModules,
+		PrepareForTestWithApexBuildComponents,
+	).
+		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+			"Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.myapex and com.mycompany.android.myapex"))
+
+	bpBase := `
+		apex_set {
+			name: "com.android.myapex",
+			installable: true,
+			exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
+			set: "myapex.apks",
+		}
+
+		apex_set {
+			name: "com.mycompany.android.myapex",
+			apex_name: "com.android.myapex",
+			installable: true,
+			exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
+			set: "company-myapex.apks",
+		}
+
+		prebuilt_bootclasspath_fragment {
+			name: "my-bootclasspath-fragment",
+			apex_available: ["com.android.myapex"],
+			%s
+		}
+	`
+
+	t.Run("java_import", func(t *testing.T) {
+		_ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
+			java_import {
+				name: "libfoo",
+				jars: ["libfoo.jar"],
+				apex_available: ["com.android.myapex"],
+			}
+		`)
+	})
+
+	t.Run("java_sdk_library_import", func(t *testing.T) {
+		_ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
+			java_sdk_library_import {
+				name: "libfoo",
+				public: {
+					jars: ["libbar.jar"],
+				},
+				apex_available: ["com.android.myapex"],
+			}
+		`)
+	})
+
+	t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) {
+		_ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `
+			image_name: "art",
+			contents: ["libfoo"],
+		`)+`
+			java_sdk_library_import {
+				name: "libfoo",
+				public: {
+					jars: ["libbar.jar"],
+				},
+				apex_available: ["com.android.myapex"],
+			}
+		`)
+	})
+}
+
 func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
 	testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
 		apex {
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 9e030f1..7ecf9b2 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -548,7 +548,7 @@
 }
 
 func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
-	result := android.GroupFixturePreparers(
+	preparers := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		prepareForTestWithArtApex,
 
@@ -559,7 +559,9 @@
 
 		// Configure some libraries in the art bootclasspath_fragment.
 		java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
-	).RunTestWithBp(t, `
+	)
+
+	bp := `
 		prebuilt_apex {
 			name: "com.android.art",
 			arch: {
@@ -605,22 +607,45 @@
 				all_flags: "mybootclasspathfragment/all-flags.csv",
 			},
 		}
-	`)
 
-	java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
-		`com.android.art.apex.selector`,
-		`prebuilt_mybootclasspathfragment`,
+		// A prebuilt apex with the same apex_name that shouldn't interfere when it isn't enabled.
+		prebuilt_apex {
+			name: "com.mycompany.android.art",
+			apex_name: "com.android.art",
+			%s
+			src: "com.mycompany.android.art.apex",
+			exported_bootclasspath_fragments: ["mybootclasspathfragment"],
+		}
+	`
+
+	t.Run("disabled alternative APEX", func(t *testing.T) {
+		result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,"))
+
+		java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
+			`com.android.art.apex.selector`,
+			`prebuilt_mybootclasspathfragment`,
+		})
+
+		java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_com.android.art", []string{
+			`com.android.art.deapexer`,
+			`dex2oatd`,
+			`prebuilt_bar`,
+			`prebuilt_foo`,
+		})
+
+		module := result.ModuleForTests("mybootclasspathfragment", "android_common_com.android.art")
+		checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
+
+		// Check that the right deapexer module was chosen for a boot image.
+		param := module.Output("out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art")
+		android.AssertStringDoesContain(t, "didn't find the expected deapexer in the input path", param.Input.String(), "/com.android.art.deapexer")
 	})
 
-	java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_com.android.art", []string{
-		`com.android.art.deapexer`,
-		`dex2oatd`,
-		`prebuilt_bar`,
-		`prebuilt_foo`,
+	t.Run("enabled alternative APEX", func(t *testing.T) {
+		preparers.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+			"Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.art and com.mycompany.android.art")).
+			RunTestWithBp(t, fmt.Sprintf(bp, ""))
 	})
-
-	module := result.ModuleForTests("mybootclasspathfragment", "android_common_com.android.art")
-	checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
 }
 
 // checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index 1a23db7..64440df 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -19,6 +19,7 @@
 	"android/soong/apex"
 	"android/soong/cc"
 	"android/soong/java"
+	"android/soong/sh"
 
 	"testing"
 )
@@ -32,6 +33,8 @@
 	// CC module types needed as they can be APEX dependencies
 	cc.RegisterCCBuildComponents(ctx)
 
+	ctx.RegisterModuleType("sh_binary", sh.ShBinaryFactory)
+	ctx.RegisterModuleType("cc_binary", cc.BinaryFactory)
 	ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
 	ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory)
 	ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
@@ -40,60 +43,63 @@
 
 func TestApexBundleSimple(t *testing.T) {
 	runApexTestCase(t, bp2buildTestCase{
-		description:                        "apex - simple example",
+		description:                        "apex - example with all props",
 		moduleTypeUnderTest:                "apex",
 		moduleTypeUnderTestFactory:         apex.BundleFactory,
 		moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build,
 		filesystem:                         map[string]string{},
 		blueprint: `
 apex_key {
-        name: "com.android.apogee.key",
-        public_key: "com.android.apogee.avbpubkey",
-        private_key: "com.android.apogee.pem",
+	name: "com.android.apogee.key",
+	public_key: "com.android.apogee.avbpubkey",
+	private_key: "com.android.apogee.pem",
 	bazel_module: { bp2build_available: false },
 }
 
 android_app_certificate {
-        name: "com.android.apogee.certificate",
-        certificate: "com.android.apogee",
-        bazel_module: { bp2build_available: false },
-}
-
-cc_library {
-        name: "native_shared_lib_1",
+	name: "com.android.apogee.certificate",
+	certificate: "com.android.apogee",
 	bazel_module: { bp2build_available: false },
 }
 
 cc_library {
-        name: "native_shared_lib_2",
+	name: "native_shared_lib_1",
+	bazel_module: { bp2build_available: false },
+}
+
+cc_library {
+	name: "native_shared_lib_2",
 	bazel_module: { bp2build_available: false },
 }
 
 // TODO(b/194878861): Add bp2build support for prebuilt_etc
 cc_library {
-        name: "pretend_prebuilt_1",
-        bazel_module: { bp2build_available: false },
+	name: "pretend_prebuilt_1",
+	bazel_module: { bp2build_available: false },
 }
 
 // TODO(b/194878861): Add bp2build support for prebuilt_etc
 cc_library {
-        name: "pretend_prebuilt_2",
-        bazel_module: { bp2build_available: false },
+	name: "pretend_prebuilt_2",
+	bazel_module: { bp2build_available: false },
 }
 
 filegroup {
 	name: "com.android.apogee-file_contexts",
-        srcs: [
-                "com.android.apogee-file_contexts",
-        ],
-        bazel_module: { bp2build_available: false },
+	srcs: [
+			"com.android.apogee-file_contexts",
+	],
+	bazel_module: { bp2build_available: false },
 }
 
+cc_binary { name: "cc_binary_1", bazel_module: { bp2build_available: false } }
+sh_binary { name: "sh_binary_2", bazel_module: { bp2build_available: false } }
+
 apex {
 	name: "com.android.apogee",
 	manifest: "apogee_manifest.json",
 	androidManifest: "ApogeeAndroidManifest.xml",
-        file_contexts: "com.android.apogee-file_contexts",
+	file_contexts: "com.android.apogee-file_contexts",
 	min_sdk_version: "29",
 	key: "com.android.apogee.key",
 	certificate: "com.android.apogee.certificate",
@@ -104,8 +110,8 @@
 	    "native_shared_lib_2",
 	],
 	binaries: [
-            "binary_1",
-	    "binary_2",
+		"cc_binary_1",
+		"sh_binary_2",
 	],
 	prebuilts: [
 	    "pretend_prebuilt_1",
@@ -117,8 +123,8 @@
 			makeBazelTarget("apex", "com.android.apogee", attrNameToString{
 				"android_manifest": `"ApogeeAndroidManifest.xml"`,
 				"binaries": `[
-        "binary_1",
-        "binary_2",
+        ":cc_binary_1",
+        ":sh_binary_2",
     ]`,
 				"certificate":     `":com.android.apogee.certificate"`,
 				"file_contexts":   `":com.android.apogee-file_contexts"`,
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index e0331be..64f368e 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -450,3 +450,18 @@
 		},
 	})
 }
+
+func TestCcLibrarySharedUseVersionLib(t *testing.T) {
+	runCcLibrarySharedTestCase(t, bp2buildTestCase{
+		blueprint: soongCcProtoPreamble + `cc_library_shared {
+        name: "foo",
+        use_version_lib: true,
+        include_build_directory: false,
+}`,
+		expectedBazelTargets: []string{
+			makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+				"use_version_lib": "True",
+			}),
+		},
+	})
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 02229e5..ef82c6b 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1443,3 +1443,18 @@
 		},
 	})
 }
+
+func TestCcLibraryStaticUseVersionLib(t *testing.T) {
+	runCcLibraryStaticTestCase(t, bp2buildTestCase{
+		blueprint: soongCcProtoPreamble + `cc_library_static {
+	name: "foo",
+	use_version_lib: true,
+	include_build_directory: false,
+}`,
+		expectedBazelTargets: []string{
+			makeBazelTarget("cc_library_static", "foo", attrNameToString{
+				"use_version_lib": "True",
+			}),
+		},
+	})
+}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index f9bbe87..09aa136 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -496,6 +496,7 @@
 
 	linkCrt                       bazel.BoolAttribute
 	useLibcrt                     bazel.BoolAttribute
+	useVersionLib                 bazel.BoolAttribute
 	linkopts                      bazel.StringListAttribute
 	additionalLinkerInputs        bazel.LabelListAttribute
 	stripKeepSymbols              bazel.BoolAttribute
@@ -565,6 +566,10 @@
 	la.linkopts.SetSelectValue(axis, config, linkerFlags)
 	la.useLibcrt.SetSelectValue(axis, config, props.libCrt())
 
+	if axis == bazel.NoConfigAxis {
+		la.useVersionLib.SetSelectValue(axis, config, props.Use_version_lib)
+	}
+
 	// it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it.
 	if props.crt() != nil {
 		if axis == bazel.NoConfigAxis {
diff --git a/cc/library.go b/cc/library.go
index a081c7d..771a6df 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -2480,7 +2480,9 @@
 		attrs = &bazelCcLibraryStaticAttributes{
 			staticOrSharedAttributes: commonAttrs,
 
-			Use_libcrt:             linkerAttrs.useLibcrt,
+			Use_libcrt:      linkerAttrs.useLibcrt,
+			Use_version_lib: linkerAttrs.useVersionLib,
+
 			Rtti:                   compilerAttrs.rtti,
 			Stl:                    compilerAttrs.stl,
 			Cpp_std:                compilerAttrs.cppStd,
@@ -2505,14 +2507,16 @@
 			Cppflags:   compilerAttrs.cppFlags,
 			Conlyflags: compilerAttrs.conlyFlags,
 			Asflags:    asFlags,
-			Linkopts:   linkerAttrs.linkopts,
 
-			Link_crt:   linkerAttrs.linkCrt,
-			Use_libcrt: linkerAttrs.useLibcrt,
-			Rtti:       compilerAttrs.rtti,
-			Stl:        compilerAttrs.stl,
-			Cpp_std:    compilerAttrs.cppStd,
-			C_std:      compilerAttrs.cStd,
+			Linkopts:        linkerAttrs.linkopts,
+			Link_crt:        linkerAttrs.linkCrt,
+			Use_libcrt:      linkerAttrs.useLibcrt,
+			Use_version_lib: linkerAttrs.useVersionLib,
+
+			Rtti:    compilerAttrs.rtti,
+			Stl:     compilerAttrs.stl,
+			Cpp_std: compilerAttrs.cppStd,
+			C_std:   compilerAttrs.cStd,
 
 			Export_includes:          exportedIncludes.Includes,
 			Export_system_includes:   exportedIncludes.SystemIncludes,
@@ -2544,11 +2548,13 @@
 type bazelCcLibraryStaticAttributes struct {
 	staticOrSharedAttributes
 
-	Use_libcrt bazel.BoolAttribute
-	Rtti       bazel.BoolAttribute
-	Stl        *string
-	Cpp_std    *string
-	C_std      *string
+	Use_libcrt      bazel.BoolAttribute
+	Use_version_lib bazel.BoolAttribute
+
+	Rtti    bazel.BoolAttribute
+	Stl     *string
+	Cpp_std *string
+	C_std   *string
 
 	Export_includes        bazel.StringListAttribute
 	Export_system_includes bazel.StringListAttribute
@@ -2579,13 +2585,16 @@
 type bazelCcLibrarySharedAttributes struct {
 	staticOrSharedAttributes
 
-	Linkopts   bazel.StringListAttribute
-	Link_crt   bazel.BoolAttribute // Only for linking shared library (and cc_binary)
-	Use_libcrt bazel.BoolAttribute
-	Rtti       bazel.BoolAttribute
-	Stl        *string
-	Cpp_std    *string
-	C_std      *string
+	Linkopts bazel.StringListAttribute
+	Link_crt bazel.BoolAttribute // Only for linking shared library (and cc_binary)
+
+	Use_libcrt      bazel.BoolAttribute
+	Use_version_lib bazel.BoolAttribute
+
+	Rtti    bazel.BoolAttribute
+	Stl     *string
+	Cpp_std *string
+	C_std   *string
 
 	Export_includes        bazel.StringListAttribute
 	Export_system_includes bazel.StringListAttribute
diff --git a/scripts/gen_java_usedby_apex.sh b/scripts/gen_java_usedby_apex.sh
index 251d7aa..0cadb1a 100755
--- a/scripts/gen_java_usedby_apex.sh
+++ b/scripts/gen_java_usedby_apex.sh
@@ -30,9 +30,11 @@
   shift
   rm -f "$out"
   touch "$out"
+  echo "<externals>" >> "$out"
   for x in "$@"; do
     "$dexdeps" "$x" >> "$out" || true
   done
+  echo "</externals>" >> "$out"
 }
 
 if [[ "$1" == "help" ]]
diff --git a/ui/terminal/simple_status.go b/ui/terminal/simple_status.go
index 936b275..3157813 100644
--- a/ui/terminal/simple_status.go
+++ b/ui/terminal/simple_status.go
@@ -22,32 +22,41 @@
 )
 
 type simpleStatusOutput struct {
-	writer    io.Writer
-	formatter formatter
-	keepANSI  bool
+	writer      io.Writer
+	formatter   formatter
+	keepANSI    bool
+	outputLevel status.MsgLevel
 }
 
 // NewSimpleStatusOutput returns a StatusOutput that represents the
 // current build status similarly to Ninja's built-in terminal
 // output.
-func NewSimpleStatusOutput(w io.Writer, formatter formatter, keepANSI bool) status.StatusOutput {
+func NewSimpleStatusOutput(w io.Writer, formatter formatter, keepANSI bool, quietBuild bool) status.StatusOutput {
+	level := status.StatusLvl
+	if quietBuild {
+		level = status.PrintLvl
+	}
 	return &simpleStatusOutput{
-		writer:    w,
-		formatter: formatter,
-		keepANSI:  keepANSI,
+		writer:      w,
+		formatter:   formatter,
+		keepANSI:    keepANSI,
+		outputLevel: level,
 	}
 }
 
 func (s *simpleStatusOutput) Message(level status.MsgLevel, message string) {
-	if level >= status.StatusLvl {
+	if level >= s.outputLevel {
 		fmt.Fprintln(s.writer, s.formatter.message(level, message))
 	}
 }
 
-func (s *simpleStatusOutput) StartAction(action *status.Action, counts status.Counts) {
+func (s *simpleStatusOutput) StartAction(_ *status.Action, _ status.Counts) {
 }
 
 func (s *simpleStatusOutput) FinishAction(result status.ActionResult, counts status.Counts) {
+	if s.outputLevel > status.StatusLvl {
+		return
+	}
 	str := result.Description
 	if str == "" {
 		str = result.Command
diff --git a/ui/terminal/status.go b/ui/terminal/status.go
index 2ad174f..ff0af47 100644
--- a/ui/terminal/status.go
+++ b/ui/terminal/status.go
@@ -29,9 +29,9 @@
 func NewStatusOutput(w io.Writer, statusFormat string, forceSimpleOutput, quietBuild, forceKeepANSI bool) status.StatusOutput {
 	formatter := newFormatter(statusFormat, quietBuild)
 
-	if !forceSimpleOutput && isSmartTerminal(w) {
-		return NewSmartStatusOutput(w, formatter)
+	if forceSimpleOutput || quietBuild || !isSmartTerminal(w) {
+		return NewSimpleStatusOutput(w, formatter, forceKeepANSI, quietBuild)
 	} else {
-		return NewSimpleStatusOutput(w, formatter, forceKeepANSI)
+		return NewSmartStatusOutput(w, formatter)
 	}
 }