Merge "Prepare soong for python 3.11" into main
diff --git a/aconfig/rust_aconfig_library.go b/aconfig/rust_aconfig_library.go
index 8b16372..de41776 100644
--- a/aconfig/rust_aconfig_library.go
+++ b/aconfig/rust_aconfig_library.go
@@ -6,6 +6,7 @@
 	"fmt"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 )
 
 type rustDeclarationsTagType struct {
@@ -17,6 +18,7 @@
 type RustAconfigLibraryProperties struct {
 	// name of the aconfig_declarations module to generate a library for
 	Aconfig_declarations string
+	Test                 *bool
 }
 
 type aconfigDecorator struct {
@@ -58,6 +60,11 @@
 	}
 	declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
 
+	mode := "production"
+	if proptools.Bool(a.Properties.Test) {
+		mode = "test"
+	}
+
 	ctx.Build(pctx, android.BuildParams{
 		Rule:  rustRule,
 		Input: declarations.IntermediatePath,
@@ -67,8 +74,7 @@
 		Description: "rust_aconfig_library",
 		Args: map[string]string{
 			"gendir": generatedDir.String(),
-			// TODO: Add test mode
-			"mode": "production",
+			"mode":   mode,
 		},
 	})
 	a.BaseSourceProvider.OutputFiles = android.Paths{generatedSource}
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 71c8d0e..056c1a8 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -145,6 +145,7 @@
 		"external/flatbuffers":                   Bp2BuildDefaultTrueRecursively,
 		"external/fmtlib":                        Bp2BuildDefaultTrueRecursively,
 		"external/fsverity-utils":                Bp2BuildDefaultTrueRecursively,
+		"external/gflags":                        Bp2BuildDefaultTrueRecursively,
 		"external/google-benchmark":              Bp2BuildDefaultTrueRecursively,
 		"external/googletest":                    Bp2BuildDefaultTrueRecursively,
 		"external/guava":                         Bp2BuildDefaultTrueRecursively,
diff --git a/bazel/properties.go b/bazel/properties.go
index 702c31c..bb0eafc 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -194,14 +194,7 @@
 // UniqueSortedBazelLabels takes a []Label and deduplicates the labels, and returns
 // the slice in a sorted order.
 func UniqueSortedBazelLabels(originalLabels []Label) []Label {
-	uniqueLabelsSet := make(map[Label]bool)
-	for _, l := range originalLabels {
-		uniqueLabelsSet[l] = true
-	}
-	var uniqueLabels []Label
-	for l, _ := range uniqueLabelsSet {
-		uniqueLabels = append(uniqueLabels, l)
-	}
+	uniqueLabels := FirstUniqueBazelLabels(originalLabels)
 	sort.SliceStable(uniqueLabels, func(i, j int) bool {
 		return uniqueLabels[i].Label < uniqueLabels[j].Label
 	})
@@ -210,13 +203,13 @@
 
 func FirstUniqueBazelLabels(originalLabels []Label) []Label {
 	var labels []Label
-	found := make(map[Label]bool, len(originalLabels))
+	found := make(map[string]bool, len(originalLabels))
 	for _, l := range originalLabels {
-		if _, ok := found[l]; ok {
+		if _, ok := found[l.Label]; ok {
 			continue
 		}
 		labels = append(labels, l)
-		found[l] = true
+		found[l.Label] = true
 	}
 	return labels
 }
diff --git a/bazel/properties_test.go b/bazel/properties_test.go
index c98ae0e..751cb8b 100644
--- a/bazel/properties_test.go
+++ b/bazel/properties_test.go
@@ -33,8 +33,12 @@
 				{Label: "b"},
 				{Label: "a"},
 				{Label: "c"},
+				// namespaces
+				{Label: "//foo:bar", OriginalModuleName: "bar"},       // when referenced from foo namespace
+				{Label: "//foo:bar", OriginalModuleName: "//foo:bar"}, // when reference from root namespace
 			},
 			expectedUniqueLabels: []Label{
+				{Label: "//foo:bar", OriginalModuleName: "bar"},
 				{Label: "a"},
 				{Label: "b"},
 				{Label: "c"},
@@ -194,6 +198,9 @@
 					{Label: "b"},
 					{Label: "a"},
 					{Label: "c"},
+					// namespaces
+					{Label: "//foo:bar", OriginalModuleName: "bar"},       // when referenced from foo namespace
+					{Label: "//foo:bar", OriginalModuleName: "//foo:bar"}, // when referenced from root namespace
 				},
 				Excludes: []Label{
 					{Label: "x"},
@@ -207,6 +214,7 @@
 					{Label: "a"},
 					{Label: "b"},
 					{Label: "c"},
+					{Label: "//foo:bar", OriginalModuleName: "bar"},
 				},
 				Excludes: []Label{
 					{Label: "x"},
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index d1b4d40..8ed94b4 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -40,6 +40,7 @@
 			"app.java":            "",
 			"res/res.png":         "",
 			"AndroidManifest.xml": "",
+			"assets/asset.png":    "",
 		},
 		Blueprint: `
 android_app {
@@ -54,6 +55,8 @@
 				"manifest":       `"AndroidManifest.xml"`,
 				"resource_files": `["res/res.png"]`,
 				"sdk_version":    `"current"`,
+				"assets":         `["assets/asset.png"]`,
+				"assets_dir":     `"assets"`,
 			}),
 		}})
 }
@@ -68,6 +71,7 @@
 			"resa/res.png":                 "",
 			"resb/res.png":                 "",
 			"manifest/AndroidManifest.xml": "",
+			"assets_/asset.png":            "",
 		},
 		Blueprint: simpleModuleDoNotConvertBp2build("android_app", "static_lib_dep") + `
 android_app {
@@ -81,6 +85,7 @@
         java_version: "7",
         certificate: "foocert",
         required: ["static_lib_dep"],
+        asset_dirs: ["assets_"],
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -91,6 +96,8 @@
         "resa/res.png",
         "resb/res.png",
     ]`,
+				"assets":           `["assets_/asset.png"]`,
+				"assets_dir":       `"assets_"`,
 				"custom_package":   `"com.google"`,
 				"deps":             `[":static_lib_dep"]`,
 				"java_version":     `"7"`,
diff --git a/java/aar.go b/java/aar.go
index 1e38efc..308a48c 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -23,6 +23,7 @@
 	"android/soong/android"
 	"android/soong/bazel"
 	"android/soong/dexpreopt"
+	"android/soong/ui/metrics/bp2build_metrics_proto"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -1228,6 +1229,8 @@
 type bazelAapt struct {
 	Manifest       bazel.Label
 	Resource_files bazel.LabelListAttribute
+	Assets_dir     bazel.StringAttribute
+	Assets         bazel.LabelListAttribute
 }
 
 type bazelAndroidLibrary struct {
@@ -1242,7 +1245,7 @@
 	Sdk_version bazel.StringAttribute
 }
 
-func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) *bazelAapt {
+func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) (*bazelAapt, bool) {
 	manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
 
 	resourceFiles := bazel.LabelList{
@@ -1252,10 +1255,30 @@
 		files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
 		resourceFiles.Includes = append(resourceFiles.Includes, files...)
 	}
+
+	assetsDir := bazel.StringAttribute{}
+	var assets bazel.LabelList
+	for i, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets") {
+		if i > 0 {
+			ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "multiple asset_dirs")
+			return &bazelAapt{}, false
+		}
+		// Assets_dirs are relative to the module dir when specified, but if the default in used in
+		// PathsWithOptionalDefaultForModuleSrc, then dir is relative to the top.
+		assetsRelDir, error := filepath.Rel(ctx.ModuleDir(), dir.Rel())
+		if error != nil {
+			assetsRelDir = dir.Rel()
+		}
+		assetsDir.Value = proptools.StringPtr(assetsRelDir)
+		assets = bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir)))
+
+	}
 	return &bazelAapt{
 		android.BazelLabelForModuleSrcSingle(ctx, manifest),
 		bazel.MakeLabelListAttribute(resourceFiles),
-	}
+		assetsDir,
+		bazel.MakeLabelListAttribute(assets),
+	}, true
 }
 
 func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
@@ -1328,6 +1351,10 @@
 	name := a.Name()
 	props := AndroidLibraryBazelTargetModuleProperties()
 
+	aaptAttrs, supported := a.convertAaptAttrsWithBp2Build(ctx)
+	if !supported {
+		return
+	}
 	ctx.CreateBazelTargetModule(
 		props,
 		android.CommonAttributes{Name: name},
@@ -1337,7 +1364,7 @@
 				Deps:                 deps,
 				Exports:              depLabels.StaticDeps,
 			},
-			a.convertAaptAttrsWithBp2Build(ctx),
+			aaptAttrs,
 		},
 	)
 
diff --git a/java/app.go b/java/app.go
index e277aed..1d1ea97 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1628,8 +1628,10 @@
 	deps := depLabels.Deps
 	deps.Append(depLabels.StaticDeps)
 
-	aapt := a.convertAaptAttrsWithBp2Build(ctx)
-
+	aapt, supported := a.convertAaptAttrsWithBp2Build(ctx)
+	if !supported {
+		return
+	}
 	certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate)
 
 	manifestValues := &manifestValueAttribute{}
diff --git a/python/proto.go b/python/proto.go
index 400e72c..ad2b786 100644
--- a/python/proto.go
+++ b/python/proto.go
@@ -19,7 +19,8 @@
 )
 
 func genProto(ctx android.ModuleContext, protoFile android.Path, flags android.ProtoFlags) android.Path {
-	srcsZipFile := android.PathForModuleGen(ctx, protoFile.Base()+".srcszip")
+	// Using protoFile.Base() would generate duplicate source errors in some cases, so we use Rel() instead
+	srcsZipFile := android.PathForModuleGen(ctx, protoFile.Rel()+".srcszip")
 
 	outDir := srcsZipFile.ReplaceExtension(ctx, "tmp")
 	depFile := srcsZipFile.ReplaceExtension(ctx, "srcszip.d")