Bp2Build converter for android_library_import and android_library.

Minor refactor of android_app converted to account for common attributes
between library and app.

Test: go test
Test: ../bazel/ci/bp2build.sh
Change-Id: I60b06eef6d2b9bc2d91f8b83522747ebbe76bbb6
Bug: 215230093
Bug: 215230095
diff --git a/java/aar.go b/java/aar.go
index a59ecb8..d5996ba 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -21,6 +21,7 @@
 	"strings"
 
 	"android/soong/android"
+	"android/soong/bazel"
 	"android/soong/dexpreopt"
 
 	"github.com/google/blueprint"
@@ -490,6 +491,7 @@
 type AndroidLibrary struct {
 	Library
 	aapt
+	android.BazelModuleBase
 
 	androidLibraryProperties androidLibraryProperties
 
@@ -605,6 +607,7 @@
 
 	android.InitApexModule(module)
 	InitJavaModule(module, android.DeviceSupported)
+	android.InitBazelModule(module)
 	return module
 }
 
@@ -643,6 +646,7 @@
 	android.ModuleBase
 	android.DefaultableModuleBase
 	android.ApexModuleBase
+	android.BazelModuleBase
 	prebuilt android.Prebuilt
 
 	// Functionality common to Module and Import.
@@ -973,5 +977,96 @@
 	android.InitPrebuiltModule(module, &module.properties.Aars)
 	android.InitApexModule(module)
 	InitJavaModuleMultiTargets(module, android.DeviceSupported)
+	android.InitBazelModule(module)
 	return module
 }
+
+type bazelAapt struct {
+	Manifest       bazel.Label
+	Resource_files bazel.LabelListAttribute
+}
+
+type bazelAndroidLibrary struct {
+	*javaLibraryAttributes
+	*bazelAapt
+}
+
+type bazelAndroidLibraryImport struct {
+	Aar     bazel.Label
+	Deps    bazel.LabelListAttribute
+	Exports bazel.LabelListAttribute
+}
+
+func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) *bazelAapt {
+	manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
+
+	resourceFiles := bazel.LabelList{
+		Includes: []bazel.Label{},
+	}
+	for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") {
+		files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
+		resourceFiles.Includes = append(resourceFiles.Includes, files...)
+	}
+	return &bazelAapt{
+		android.BazelLabelForModuleSrcSingle(ctx, manifest),
+		bazel.MakeLabelListAttribute(resourceFiles),
+	}
+}
+
+func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+	aars := android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Aars, []string{})
+	exportableStaticLibs := []string{}
+	// TODO(b/240716882): investigate and handle static_libs deps that are not imports. They are not supported for export by Bazel.
+	for _, depName := range a.properties.Static_libs {
+		if dep, ok := ctx.ModuleFromName(depName); ok {
+			switch dep.(type) {
+			case *AARImport, *Import:
+				exportableStaticLibs = append(exportableStaticLibs, depName)
+			}
+		}
+	}
+	name := android.RemoveOptionalPrebuiltPrefix(a.Name())
+	deps := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(append(a.properties.Static_libs, a.properties.Libs...))))
+	exports := android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(exportableStaticLibs))
+
+	ctx.CreateBazelTargetModule(
+		bazel.BazelTargetModuleProperties{
+			Rule_class:        "aar_import",
+			Bzl_load_location: "@rules_android//rules:rules.bzl",
+		},
+		android.CommonAttributes{Name: name},
+		&bazelAndroidLibraryImport{
+			Aar:     aars.Includes[0],
+			Deps:    bazel.MakeLabelListAttribute(deps),
+			Exports: bazel.MakeLabelListAttribute(exports),
+		},
+	)
+
+}
+
+func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+	commonAttrs, depLabels := a.convertLibraryAttrsBp2Build(ctx)
+
+	deps := depLabels.Deps
+	if !commonAttrs.Srcs.IsEmpty() {
+		deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
+	} else if !depLabels.Deps.IsEmpty() {
+		ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
+	}
+
+	ctx.CreateBazelTargetModule(
+		bazel.BazelTargetModuleProperties{
+			Rule_class:        "android_library",
+			Bzl_load_location: "@rules_android//rules:rules.bzl",
+		},
+		android.CommonAttributes{Name: a.Name()},
+		&bazelAndroidLibrary{
+			&javaLibraryAttributes{
+				javaCommonAttributes: commonAttrs,
+				Deps:                 deps,
+				Exports:              depLabels.StaticDeps,
+			},
+			a.convertAaptAttrsWithBp2Build(ctx),
+		},
+	)
+}
diff --git a/java/app.go b/java/app.go
index c369978..7b5efc7 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1444,10 +1444,9 @@
 
 type bazelAndroidAppAttributes struct {
 	*javaCommonAttributes
+	*bazelAapt
 	Deps             bazel.LabelListAttribute
-	Manifest         bazel.Label
 	Custom_package   *string
-	Resource_files   bazel.LabelListAttribute
 	Certificate      *bazel.Label
 	Certificate_name *string
 }
@@ -1457,23 +1456,9 @@
 	commonAttrs, depLabels := a.convertLibraryAttrsBp2Build(ctx)
 
 	deps := depLabels.Deps
-	if !commonAttrs.Srcs.IsEmpty() {
-		deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
-	} else if !deps.IsEmpty() || !depLabels.StaticDeps.IsEmpty() {
-		ctx.ModuleErrorf("android_app has dynamic or static dependencies but no sources." +
-			" Bazel does not allow direct dependencies without sources nor exported" +
-			" dependencies on android_binary rule.")
-	}
+	deps.Append(depLabels.StaticDeps)
 
-	manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
-
-	resourceFiles := bazel.LabelList{
-		Includes: []bazel.Label{},
-	}
-	for _, dir := range android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") {
-		files := android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir))
-		resourceFiles.Includes = append(resourceFiles.Includes, files...)
-	}
+	aapt := a.convertAaptAttrsWithBp2Build(ctx)
 
 	var certificate *bazel.Label
 	certificateNamePtr := a.overridableAppProperties.Certificate
@@ -1484,14 +1469,12 @@
 		certificate = &c
 		certificateNamePtr = nil
 	}
-
 	attrs := &bazelAndroidAppAttributes{
 		commonAttrs,
+		aapt,
 		deps,
-		android.BazelLabelForModuleSrcSingle(ctx, manifest),
 		// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
 		a.overridableAppProperties.Package_name,
-		bazel.MakeLabelListAttribute(resourceFiles),
 		certificate,
 		certificateNamePtr,
 	}
@@ -1500,7 +1483,6 @@
 		Rule_class:        "android_binary",
 		Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
 	}
-
 	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs)
 
 }
diff --git a/java/java.go b/java/java.go
index f4ec04e..481c625 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2333,12 +2333,12 @@
 
 	var deps bazel.LabelList
 	if m.properties.Libs != nil {
-		deps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Libs))
+		deps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Libs))))
 	}
 
 	var staticDeps bazel.LabelList
 	if m.properties.Static_libs != nil {
-		staticDeps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Static_libs))
+		staticDeps.Append(android.BazelLabelForModuleDeps(ctx, android.LastUniqueStrings(android.CopyOf(m.properties.Static_libs))))
 	}
 
 	protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition])