Merge "Add array type property flags, equivalent to args"
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 9f4df28..269ad5d 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -225,7 +225,7 @@
 // PrebuiltSourceDepsMutator adds dependencies to the prebuilt module from the
 // corresponding source module, if one exists for the same variant.
 func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
-	if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
+	if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Enabled() && m.Prebuilt() != nil {
 		p := m.Prebuilt()
 		if !p.properties.PrebuiltRenamedToSource {
 			name := m.base().BaseModuleName()
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 8029b85..6c3cd9e 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -22,9 +22,10 @@
 )
 
 var prebuiltsTests = []struct {
-	name     string
-	modules  string
-	prebuilt []OsClass
+	name      string
+	replaceBp bool // modules is added to default bp boilerplate if false.
+	modules   string
+	prebuilt  []OsType
 }{
 	{
 		name: "no prebuilt",
@@ -42,7 +43,7 @@
 				prefer: false,
 				srcs: ["prebuilt_file"],
 			}`,
-		prebuilt: []OsClass{Device, Host},
+		prebuilt: []OsType{Android, BuildOs},
 	},
 	{
 		name: "no source prebuilt preferred",
@@ -52,7 +53,7 @@
 				prefer: true,
 				srcs: ["prebuilt_file"],
 			}`,
-		prebuilt: []OsClass{Device, Host},
+		prebuilt: []OsType{Android, BuildOs},
 	},
 	{
 		name: "prebuilt not preferred",
@@ -80,7 +81,7 @@
 				prefer: true,
 				srcs: ["prebuilt_file"],
 			}`,
-		prebuilt: []OsClass{Device, Host},
+		prebuilt: []OsType{Android, BuildOs},
 	},
 	{
 		name: "prebuilt no file not preferred",
@@ -120,7 +121,7 @@
 				prefer: true,
 				srcs: [":fg"],
 			}`,
-		prebuilt: []OsClass{Device, Host},
+		prebuilt: []OsType{Android, BuildOs},
 	},
 	{
 		name: "prebuilt module for device only",
@@ -135,7 +136,7 @@
 				prefer: true,
 				srcs: ["prebuilt_file"],
 			}`,
-		prebuilt: []OsClass{Device},
+		prebuilt: []OsType{Android},
 	},
 	{
 		name: "prebuilt file for host only",
@@ -153,7 +154,7 @@
 					},
 				},
 			}`,
-		prebuilt: []OsClass{Host},
+		prebuilt: []OsType{BuildOs},
 	},
 	{
 		name: "prebuilt override not preferred",
@@ -191,7 +192,72 @@
 				prefer: true,
 				srcs: ["prebuilt_file"],
 			}`,
-		prebuilt: []OsClass{Device, Host},
+		prebuilt: []OsType{Android, BuildOs},
+	},
+	{
+		name:      "prebuilt including default-disabled OS",
+		replaceBp: true,
+		modules: `
+			source {
+				name: "foo",
+				deps: [":bar"],
+				target: {
+					windows: {
+						enabled: true,
+					},
+				},
+			}
+
+			source {
+				name: "bar",
+				target: {
+					windows: {
+						enabled: true,
+					},
+				},
+			}
+
+			prebuilt {
+				name: "bar",
+				prefer: true,
+				srcs: ["prebuilt_file"],
+				target: {
+					windows: {
+						enabled: true,
+					},
+				},
+			}`,
+		prebuilt: []OsType{Android, BuildOs, Windows},
+	},
+	{
+		name:      "fall back to source for default-disabled OS",
+		replaceBp: true,
+		modules: `
+			source {
+				name: "foo",
+				deps: [":bar"],
+				target: {
+					windows: {
+						enabled: true,
+					},
+				},
+			}
+
+			source {
+				name: "bar",
+				target: {
+					windows: {
+						enabled: true,
+					},
+				},
+			}
+
+			prebuilt {
+				name: "bar",
+				prefer: true,
+				srcs: ["prebuilt_file"],
+			}`,
+		prebuilt: []OsType{Android, BuildOs},
 	},
 }
 
@@ -203,14 +269,25 @@
 
 	for _, test := range prebuiltsTests {
 		t.Run(test.name, func(t *testing.T) {
-			bp := `
-				source {
-					name: "foo",
-					deps: [":bar"],
-				}
-				` + test.modules
+			bp := test.modules
+			if !test.replaceBp {
+				bp = bp + `
+					source {
+						name: "foo",
+						deps: [":bar"],
+					}`
+			}
 			config := TestArchConfig(buildDir, nil, bp, fs)
 
+			// Add windows to the target list to test the logic when a variant is
+			// disabled by default.
+			if !Windows.DefaultDisabled {
+				t.Errorf("windows is assumed to be disabled by default")
+			}
+			config.config.Targets[Windows] = []Target{
+				{Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", ""},
+			}
+
 			ctx := NewTestArchContext()
 			registerTestPrebuiltBuildComponents(ctx)
 			ctx.RegisterModuleType("filegroup", FileGroupFactory)
@@ -223,7 +300,7 @@
 
 			for _, variant := range ctx.ModuleVariantsForTests("foo") {
 				foo := ctx.ModuleForTests("foo", variant)
-				t.Run(foo.Module().Target().Os.Class.String(), func(t *testing.T) {
+				t.Run(foo.Module().Target().Os.String(), func(t *testing.T) {
 					var dependsOnSourceModule, dependsOnPrebuiltModule bool
 					ctx.VisitDirectDeps(foo.Module(), func(m blueprint.Module) {
 						if _, ok := m.(*sourceModule); ok {
@@ -237,26 +314,38 @@
 						}
 					})
 
+					moduleIsDisabled := !foo.Module().Enabled()
 					deps := foo.Module().(*sourceModule).deps
-					if deps == nil || len(deps) != 1 {
-						t.Errorf("deps does not have single path, but is %v", deps)
+					if moduleIsDisabled {
+						if len(deps) > 0 {
+							t.Errorf("disabled module got deps: %v", deps)
+						}
+					} else {
+						if len(deps) != 1 {
+							t.Errorf("deps does not have single path, but is %v", deps)
+						}
 					}
+
 					var usingSourceFile, usingPrebuiltFile bool
-					if deps[0].String() == "source_file" {
+					if len(deps) > 0 && deps[0].String() == "source_file" {
 						usingSourceFile = true
 					}
-					if deps[0].String() == "prebuilt_file" {
+					if len(deps) > 0 && deps[0].String() == "prebuilt_file" {
 						usingPrebuiltFile = true
 					}
 
 					prebuilt := false
 					for _, os := range test.prebuilt {
-						if os == foo.Module().Target().Os.Class {
+						if os == foo.Module().Target().Os {
 							prebuilt = true
 						}
 					}
 
 					if prebuilt {
+						if moduleIsDisabled {
+							t.Errorf("dependent module for prebuilt is disabled")
+						}
+
 						if !dependsOnPrebuiltModule {
 							t.Errorf("doesn't depend on prebuilt module")
 						}
@@ -270,7 +359,7 @@
 						if usingSourceFile {
 							t.Errorf("using source_file")
 						}
-					} else {
+					} else if !moduleIsDisabled {
 						if dependsOnPrebuiltModule {
 							t.Errorf("depends on prebuilt module")
 						}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 7595238..156906d 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -203,6 +203,7 @@
 				panic(fmt.Sprintf("Expected %s to be AndroidAppSet", fi.module))
 			}
 			fmt.Fprintln(w, "LOCAL_APK_SET_MASTER_FILE :=", as.MasterFile())
+			fmt.Fprintln(w, "LOCAL_APKCERTS_FILE :=", as.APKCertsFile().String())
 			fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_android_app_set.mk")
 		case nativeSharedLib, nativeExecutable, nativeTest:
 			fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.Stem())
diff --git a/apex/builder.go b/apex/builder.go
index 5fb9a5f..49e4642 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -390,7 +390,7 @@
 		} else {
 			if fi.class == appSet {
 				copyCommands = append(copyCommands,
-					fmt.Sprintf("unzip -q -d %s %s", destPathDir, fi.builtFile.String()))
+					fmt.Sprintf("unzip -qDD -d %s %s", destPathDir, fi.builtFile.String()))
 			} else {
 				copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath)
 			}
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 7ff20f4..71c9204 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -225,6 +225,8 @@
 func llndkHeadersFactory() android.Module {
 	module, library := NewLibrary(android.DeviceSupported)
 	library.HeaderOnly()
+	module.stl = nil
+	module.sanitize = nil
 
 	decorator := &llndkHeadersDecorator{
 		libraryDecorator: library,
diff --git a/java/aar.go b/java/aar.go
index 500788f..ad9b5e7 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -641,7 +641,7 @@
 var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
 	blueprint.RuleParams{
 		Command: `rm -rf $outDir && mkdir -p $outDir && ` +
-			`unzip -qo -d $outDir $in && rm -rf $outDir/res && touch $out`,
+			`unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out`,
 	},
 	"outDir")
 
diff --git a/java/app.go b/java/app.go
index 98bce94..4071c0a 100755
--- a/java/app.go
+++ b/java/app.go
@@ -106,6 +106,10 @@
 	return as.masterFile
 }
 
+func (as *AndroidAppSet) APKCertsFile() android.Path {
+	return as.apkcertsFile
+}
+
 var TargetCpuAbi = map[string]string{
 	"arm":    "ARMEABI_V7A",
 	"arm64":  "ARM64_V8A",
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 130b634..b5a0217 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -146,7 +146,7 @@
 
 var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{
 	Command: `rm -rf $tmpDir && mkdir -p $tmpDir && mkdir $tmpDir/dex-input && mkdir $tmpDir/dex-output &&
-		unzip -o -q $in 'classes*.dex' -d $tmpDir/dex-input &&
+		unzip -qoDD $in 'classes*.dex' -d $tmpDir/dex-input &&
 		for INPUT_DEX in $$(find $tmpDir/dex-input -maxdepth 1 -name 'classes*.dex' | sort); do
 		  echo "--input-dex=$${INPUT_DEX}";
 		  echo "--output-dex=$tmpDir/dex-output/$$(basename $${INPUT_DEX})";
diff --git a/rust/binary.go b/rust/binary.go
index a1cd410..9fc52cd 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -106,7 +106,8 @@
 func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
 
-	srcPath := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
+	srcPath, paths := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
+	deps.SrcDeps = paths
 
 	outputFile := android.PathForModuleOut(ctx, fileName)
 	binary.unstrippedOutputFile = outputFile
diff --git a/rust/builder.go b/rust/builder.go
index 16d7306..7f94bb5 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -166,6 +166,7 @@
 	implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
 	implicits = append(implicits, deps.StaticLibs...)
 	implicits = append(implicits, deps.SharedLibs...)
+	implicits = append(implicits, deps.SrcDeps...)
 	if deps.CrtBegin.Valid() {
 		implicits = append(implicits, deps.CrtBegin.Path(), deps.CrtEnd.Path())
 	}
diff --git a/rust/compiler.go b/rust/compiler.go
index 92a3b07..c20179b 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -253,10 +253,24 @@
 	return String(compiler.Properties.Relative_install_path)
 }
 
-func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
-	srcPaths := android.PathsForModuleSrc(ctx, srcs)
-	if len(srcPaths) != 1 {
-		ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
+func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
+	// The srcs can contain strings with prefix ":".
+	// They are dependent modules of this module, with android.SourceDepTag.
+	// They are not the main source file compiled by rustc.
+	numSrcs := 0
+	srcIndex := 0
+	for i, s := range srcs {
+		if android.SrcIsModule(s) == "" {
+			numSrcs++
+			srcIndex = i
+		}
 	}
-	return srcPaths[0]
+	if numSrcs != 1 {
+		ctx.PropertyErrorf("srcs", "srcs can only contain one path for a rust file")
+	}
+	if srcIndex != 0 {
+		ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
+	}
+	paths := android.PathsForModuleSrc(ctx, srcs)
+	return paths[srcIndex], paths
 }
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index bcde757..58ca52a 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -43,7 +43,7 @@
 // Test that we reject multiple source files.
 func TestEnforceSingleSourceFile(t *testing.T) {
 
-	singleSrcError := "srcs can only contain one path for rust modules"
+	singleSrcError := "srcs can only contain one path for a rust file"
 
 	// Test libraries
 	testRustError(t, singleSrcError, `
diff --git a/rust/library.go b/rust/library.go
index 8b8e797..d718eb8 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -368,7 +368,8 @@
 func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	var outputFile android.WritablePath
 
-	srcPath := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
+	srcPath, paths := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
+	deps.SrcDeps = paths
 
 	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
 
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index 67d649d..3b4f40a 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -95,7 +95,8 @@
 func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	prebuilt.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
 
-	srcPath := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
+	srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
+	deps.SrcDeps = paths
 
 	prebuilt.unstrippedOutputFile = srcPath
 
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 2719161..49dbd8d 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -65,7 +65,8 @@
 	fileName := procMacro.getStem(ctx) + ctx.toolchain().ProcMacroSuffix()
 	outputFile := android.PathForModuleOut(ctx, fileName)
 
-	srcPath := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
+	srcPath, paths := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
+	deps.SrcDeps = paths
 
 	procMacro.unstrippedOutputFile = outputFile
 
diff --git a/rust/rust.go b/rust/rust.go
index 72301a7..7a98c64 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -239,6 +239,9 @@
 
 	CrtBegin android.OptionalPath
 	CrtEnd   android.OptionalPath
+
+	// Paths to generated source files
+	SrcDeps android.Paths
 }
 
 type RustLibraries []RustLibrary
@@ -843,6 +846,7 @@
 	// Dedup exported flags from dependencies
 	depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
 	depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
+	depPaths.SrcDeps = android.FirstUniquePaths(depPaths.SrcDeps)
 
 	return depPaths
 }
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 08bc8ca..e803925 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -61,6 +61,7 @@
 		"foo.rs":     nil,
 		"foo.c":      nil,
 		"src/bar.rs": nil,
+		"src/any.h":  nil,
 		"liby.so":    nil,
 		"libz.so":    nil,
 	}
@@ -181,7 +182,7 @@
 		}
 		rust_library_host_rlib {
 			name: "librlib",
-			srcs: ["foo.rs"],
+			srcs: ["foo.rs", ":my_generator"],
 			crate_name: "rlib",
 		}
 		rust_proc_macro {
@@ -189,17 +190,38 @@
 			srcs: ["foo.rs"],
 			crate_name: "pm",
 		}
+		genrule {
+			name: "my_generator",
+			tools: ["any_rust_binary"],
+			cmd: "$(location) -o $(out) $(in)",
+			srcs: ["src/any.h"],
+			out: ["src/any.rs"],
+		}
 		rust_binary_host {
-			name: "fizz-buzz",
+			name: "fizz-buzz-dep",
 			dylibs: ["libdylib"],
 			rlibs: ["librlib"],
 			proc_macros: ["libpm"],
 			static_libs: ["libstatic"],
 			shared_libs: ["libshared"],
-			srcs: ["foo.rs"],
+			srcs: [
+				"foo.rs",
+				":my_generator",
+			],
 		}
 	`)
-	module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
+	module := ctx.ModuleForTests("fizz-buzz-dep", "linux_glibc_x86_64").Module().(*Module)
+	rlibmodule := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib").Module().(*Module)
+
+	srcs := module.compiler.(*binaryDecorator).baseCompiler.Properties.Srcs
+	if len(srcs) != 2 || !android.InList(":my_generator", srcs) {
+		t.Errorf("missing module dependency in fizz-buzz)")
+	}
+
+	srcs = rlibmodule.compiler.(*libraryDecorator).baseCompiler.Properties.Srcs
+	if len(srcs) != 2 || !android.InList(":my_generator", srcs) {
+		t.Errorf("missing module dependency in rlib")
+	}
 
 	// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
 	if !android.InList("libdylib", module.Properties.AndroidMkDylibs) {
diff --git a/rust/testing.go b/rust/testing.go
index 3d583e1..430b40b 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -17,6 +17,7 @@
 import (
 	"android/soong/android"
 	"android/soong/cc"
+	"android/soong/genrule"
 )
 
 func GatherRequiredDepsForTest() string {
@@ -77,6 +78,7 @@
 func CreateTestContext() *android.TestContext {
 	ctx := android.NewTestArchContext()
 	cc.RegisterRequiredBuildComponentsForTest(ctx)
+	ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
 	ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
 	ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
 	ctx.RegisterModuleType("rust_test", RustTestFactory)
diff --git a/sdk/update.go b/sdk/update.go
index 8241151..cf25008 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -911,7 +911,7 @@
 
 	if commonVariants, ok := variantsByArchName["common"]; ok {
 		if len(osTypeVariants) != 1 {
-			panic("Expected to only have 1 variant when arch type is common but found " + string(len(osTypeVariants)))
+			panic(fmt.Errorf("Expected to only have 1 variant when arch type is common but found %d", len(osTypeVariants)))
 		}
 
 		// A common arch type only has one variant and its properties should be treated