Merge "Rename utils.bzl to android_product.bzl"
diff --git a/README.md b/README.md
index 85e24c6..70311cb 100644
--- a/README.md
+++ b/README.md
@@ -105,31 +105,35 @@
 
 ### Types
 
-Variables and properties are strongly typed, variables dynamically based on the
-first assignment, and properties statically by the module type.  The supported
-types are:
+Variables and properties are strongly typed. Variables are dynamically typed
+based on the first assignment, and properties are statically typed by the
+module type.  The supported types are:
 * Bool (`true` or `false`)
 * Integers (`int`)
 * Strings (`"string"`)
 * Lists of strings (`["string1", "string2"]`)
 * Maps (`{key1: "value1", key2: ["value2"]}`)
 
-Maps may values of any type, including nested maps.  Lists and maps may have
-trailing commas after the last value.
+Maps may contain values of any type, including nested maps. Lists and maps may
+have trailing commas after the last value.
 
 Strings can contain double quotes using `\"`, for example `"cat \"a b\""`.
 
 ### Operators
 
-Strings, lists of strings, and maps can be appended using the `+` operator.
-Integers can be summed up using the `+` operator. Appending a map produces the
-union of keys in both maps, appending the values of any keys that are present
-in both maps.
+The `+` operator:
+* Sums integers.
+* Concatenates strings and lists.
+* Produces the union of maps.
+
+Concatenating maps produces a map whose keys are the union of the given maps'
+keys, and whose mapped values are the union of the given maps' corresponding
+mapped values.
 
 ### Defaults modules
 
-A defaults module can be used to repeat the same properties in multiple modules.
-For example:
+A `defaults` module can be used to repeat the same properties in multiple
+modules. For example:
 
 ```
 cc_defaults {
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 57bc761..33655d0 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -281,6 +281,7 @@
 		"packages/modules/adb/proto":                         Bp2BuildDefaultTrueRecursively,
 		"packages/modules/adb/tls":                           Bp2BuildDefaultTrueRecursively,
 		"packages/modules/NetworkStack/common/captiveportal": Bp2BuildDefaultTrue,
+		"packages/modules/NeuralNetworks/apex":               Bp2BuildDefaultTrue,
 		"packages/providers/MediaProvider/tools/dialogs":     Bp2BuildDefaultFalse, // TODO(b/242834374)
 		"packages/screensavers/Basic":                        Bp2BuildDefaultTrue,
 		"packages/services/Car/tests/SampleRearViewCamera":   Bp2BuildDefaultFalse, // TODO(b/242834321)
@@ -433,10 +434,6 @@
 		"com.android.media.swcodec-mediaswcodec.rc",
 		"com.android.media.swcodec.certificate",
 		"com.android.media.swcodec.key",
-		"com.android.neuralnetworks",
-		"com.android.neuralnetworks-androidManifest",
-		"com.android.neuralnetworks.certificate",
-		"com.android.neuralnetworks.key",
 		"flatbuffer_headers",
 		"framework-connectivity-protos",
 		"gemmlowp_headers",
diff --git a/android/filegroup.go b/android/filegroup.go
index 278d46d..38de855 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -118,6 +118,7 @@
 	// If the module has a mixed bag of AIDL and non-AIDL files, split the filegroup manually
 	// and then convert
 	if fg.ShouldConvertToAidlLibrary(ctx) {
+		tags := []string{"apex_available=//apex_available:anyapex"}
 		attrs := &bazelAidlLibraryAttributes{
 			Srcs:                srcs,
 			Strip_import_prefix: fg.properties.Path,
@@ -128,17 +129,25 @@
 			Bzl_load_location: "//build/bazel/rules/aidl:library.bzl",
 		}
 
-		ctx.CreateBazelTargetModule(props, CommonAttributes{Name: fg.Name()}, attrs)
+		ctx.CreateBazelTargetModule(
+			props,
+			CommonAttributes{
+				Name: fg.Name(),
+				Tags: bazel.MakeStringListAttribute(tags),
+			},
+			attrs)
 	} else {
 		if fg.ShouldConvertToProtoLibrary(ctx) {
-			// TODO(b/246997908): we can remove this tag if we could figure out a
-			// solution for this bug.
 			attrs := &ProtoAttrs{
 				Srcs:                srcs,
 				Strip_import_prefix: fg.properties.Path,
 			}
 
-			tags := []string{"manual"}
+			tags := []string{
+				"apex_available=//apex_available:anyapex",
+				// TODO(b/246997908): we can remove this tag if we could figure out a solution for this bug.
+				"manual",
+			}
 			ctx.CreateBazelTargetModule(
 				bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
 				CommonAttributes{
diff --git a/apex/builder.go b/apex/builder.go
index 45c5267..e3b6f8e 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -1167,7 +1167,7 @@
 	if a.properties.Canned_fs_config != nil {
 		cmd.Text("cat").Input(android.PathForModuleSrc(ctx, *a.properties.Canned_fs_config))
 	}
-	cmd.Text(") | LC_ALL=C sort ").FlagWithOutput("> ", cannedFsConfig)
+	cmd.Text(")").FlagWithOutput("> ", cannedFsConfig)
 	builder.Build("generateFsConfig", fmt.Sprintf("Generating canned fs config for %s", a.BaseModuleName()))
 
 	return cannedFsConfig.OutputPath
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 48e93cd..d2c463d 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -2425,7 +2425,10 @@
 				"whole_archive_deps": `[":a_cc_proto_lite"]`,
 			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
-				"tags": `["manual"]`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
 			}), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 			}),
@@ -2464,7 +2467,10 @@
 				"whole_archive_deps": `[":a_cc_proto_lite"]`,
 			}), MakeBazelTargetNoRestrictions("proto_library", "a_fg_proto_bp2build_converted", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
-				"tags": `["manual"]`,
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
 			}), MakeBazelTargetNoRestrictions("filegroup", "a_fg_proto", AttrNameToString{
 				"srcs": `["a_fg.proto"]`,
 			}),
@@ -3032,6 +3038,7 @@
 		},
 	},
 	bazel_module: { bp2build_available: true },
+	apex_available: ["foo"],
 }`,
 		ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{
 			"implementation_dynamic_deps": `select({
@@ -3039,6 +3046,7 @@
         "//conditions:default": [":barlib"],
     })`,
 			"local_includes": `["."]`,
+			"tags":           `["apex_available=foo"]`,
 		}),
 	})
 }
@@ -3072,6 +3080,7 @@
 	},
 	include_build_directory: false,
 	bazel_module: { bp2build_available: true },
+	apex_available: ["foo"],
 }`,
 		ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{
 			"implementation_dynamic_deps": `select({
@@ -3096,6 +3105,7 @@
             ":quxlib",
         ],
     })`,
+			"tags": `["apex_available=foo"]`,
 		}),
 	})
 }
@@ -3322,6 +3332,7 @@
 			MakeBazelTargetNoRestrictions("aidl_library", "A_aidl", AttrNameToString{
 				"srcs":                `["aidl/A.aidl"]`,
 				"strip_import_prefix": `"aidl"`,
+				"tags":                `["apex_available=//apex_available:anyapex"]`,
 			}),
 			MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
 				"srcs": `["B.aidl"]`,
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index b685a2c..8e0a728 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -556,6 +556,151 @@
 	})
 }
 
+func TestCcLibrarySharedStubs_UseImplementationInSameApex(t *testing.T) {
+	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library_shared stubs",
+		ModuleTypeUnderTest:        "cc_library_shared",
+		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+		Blueprint: soongCcLibrarySharedPreamble + `
+cc_library_shared {
+	name: "a",
+	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
+	bazel_module: { bp2build_available: false },
+	include_build_directory: false,
+	apex_available: ["made_up_apex"],
+}
+cc_library_shared {
+	name: "b",
+	shared_libs: [":a"],
+	include_build_directory: false,
+	apex_available: ["made_up_apex"],
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
+				"implementation_dynamic_deps": `[":a"]`,
+				"tags":                        `["apex_available=made_up_apex"]`,
+			}),
+		},
+	})
+}
+
+func TestCcLibrarySharedStubs_UseStubsInDifferentApex(t *testing.T) {
+	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library_shared stubs",
+		ModuleTypeUnderTest:        "cc_library_shared",
+		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+		Blueprint: soongCcLibrarySharedPreamble + `
+cc_library_shared {
+	name: "a",
+	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
+	bazel_module: { bp2build_available: false },
+	include_build_directory: false,
+	apex_available: ["apex_a"],
+}
+cc_library_shared {
+	name: "b",
+	shared_libs: [":a"],
+	include_build_directory: false,
+	apex_available: ["apex_b"],
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
+				"implementation_dynamic_deps": `select({
+        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"],
+        "//conditions:default": [":a"],
+    })`,
+				"tags": `["apex_available=apex_b"]`,
+			}),
+		},
+	})
+}
+
+func TestCcLibrarySharedStubs_IgnorePlatformAvailable(t *testing.T) {
+	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library_shared stubs",
+		ModuleTypeUnderTest:        "cc_library_shared",
+		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+		Blueprint: soongCcLibrarySharedPreamble + `
+cc_library_shared {
+	name: "a",
+	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
+	bazel_module: { bp2build_available: false },
+	include_build_directory: false,
+	apex_available: ["//apex_available:platform", "apex_a"],
+}
+cc_library_shared {
+	name: "b",
+	shared_libs: [":a"],
+	include_build_directory: false,
+	apex_available: ["//apex_available:platform", "apex_b"],
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
+				"implementation_dynamic_deps": `select({
+        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"],
+        "//conditions:default": [":a"],
+    })`,
+				"tags": `[
+        "apex_available=//apex_available:platform",
+        "apex_available=apex_b",
+    ]`,
+			}),
+		},
+	})
+}
+
+func TestCcLibrarySharedStubs_MultipleApexAvailable(t *testing.T) {
+	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+		ModuleTypeUnderTest:        "cc_library_shared",
+		ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+		Blueprint: soongCcLibrarySharedPreamble + `
+cc_library_shared {
+	name: "a",
+	stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
+	bazel_module: { bp2build_available: false },
+	include_build_directory: false,
+	apex_available: ["//apex_available:platform", "apex_a", "apex_b"],
+}
+cc_library_shared {
+	name: "b",
+	shared_libs: [":a"],
+	include_build_directory: false,
+	apex_available: ["//apex_available:platform", "apex_b"],
+}
+
+cc_library_shared {
+	name: "c",
+	shared_libs: [":a"],
+	include_build_directory: false,
+	apex_available: ["//apex_available:platform", "apex_a", "apex_b"],
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_shared", "b", AttrNameToString{
+				"implementation_dynamic_deps": `select({
+        "//build/bazel/rules/apex:android-in_apex": ["@api_surfaces//module-libapi/current:a"],
+        "//conditions:default": [":a"],
+    })`,
+				"tags": `[
+        "apex_available=//apex_available:platform",
+        "apex_available=apex_b",
+    ]`,
+			}),
+			MakeBazelTarget("cc_library_shared", "c", AttrNameToString{
+				"implementation_dynamic_deps": `[":a"]`,
+				"tags": `[
+        "apex_available=//apex_available:platform",
+        "apex_available=apex_a",
+        "apex_available=apex_b",
+    ]`,
+			}),
+		},
+	})
+}
+
 func TestCcLibrarySharedSystemSharedLibsSharedEmpty(t *testing.T) {
 	runCcLibrarySharedTestCase(t, Bp2buildTestCase{
 		Description:                "cc_library_shared system_shared_libs empty shared default",
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 7c18037..cd4cf51 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1517,12 +1517,14 @@
         },
     },
     include_build_directory: false,
+    apex_available: ["foo"],
 }
 
 cc_library_static {
     name: "all",
     shared_libs: ["libc"],
     include_build_directory: false,
+    apex_available: ["foo"],
 }
 
 cc_library_static {
@@ -1530,12 +1532,14 @@
     shared_libs: ["libc"],
     system_shared_libs: [],
     include_build_directory: false,
+    apex_available: ["foo"],
 }
 
 cc_library_static {
     name: "used_with_stubs",
     shared_libs: ["libm"],
     include_build_directory: false,
+    apex_available: ["foo"],
 }
 
 cc_library_static {
@@ -1543,13 +1547,17 @@
     shared_libs: ["libm"],
     system_shared_libs: [],
     include_build_directory: false,
+    apex_available: ["foo"],
 }
 `,
 		ExpectedBazelTargets: []string{
-			MakeBazelTarget("cc_library_static", "all", AttrNameToString{}),
+			MakeBazelTarget("cc_library_static", "all", AttrNameToString{
+				"tags": `["apex_available=foo"]`,
+			}),
 			MakeBazelTarget("cc_library_static", "keep_for_empty_system_shared_libs", AttrNameToString{
 				"implementation_dynamic_deps": `[":libc"]`,
 				"system_dynamic_deps":         `[]`,
+				"tags":                        `["apex_available=foo"]`,
 			}),
 			MakeBazelTarget("cc_library_static", "keep_with_stubs", AttrNameToString{
 				"implementation_dynamic_deps": `select({
@@ -1557,9 +1565,14 @@
         "//conditions:default": [":libm"],
     })`,
 				"system_dynamic_deps": `[]`,
+				"tags":                `["apex_available=foo"]`,
 			}),
-			MakeBazelTarget("cc_library_static", "used_in_bionic_oses", AttrNameToString{}),
-			MakeBazelTarget("cc_library_static", "used_with_stubs", AttrNameToString{}),
+			MakeBazelTarget("cc_library_static", "used_in_bionic_oses", AttrNameToString{
+				"tags": `["apex_available=foo"]`,
+			}),
+			MakeBazelTarget("cc_library_static", "used_with_stubs", AttrNameToString{
+				"tags": `["apex_available=foo"]`,
+			}),
 		},
 	})
 }
diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go
index e978fb3..7ce559d 100644
--- a/bp2build/filegroup_conversion_test.go
+++ b/bp2build/filegroup_conversion_test.go
@@ -74,6 +74,7 @@
 			expectedBazelAttrs: AttrNameToString{
 				"srcs":                `["aidl/foo.aidl"]`,
 				"strip_import_prefix": `"aidl"`,
+				"tags":                `["apex_available=//apex_available:anyapex"]`,
 			},
 		},
 		{
@@ -85,18 +86,21 @@
 	}`,
 			expectedBazelAttrs: AttrNameToString{
 				"srcs": `["aidl/foo.aidl"]`,
+				"tags": `["apex_available=//apex_available:anyapex"]`,
 			},
 		},
 	}
 
 	for _, test := range testcases {
-		expectedBazelTargets := []string{
-			MakeBazelTargetNoRestrictions("aidl_library", "foo", test.expectedBazelAttrs),
-		}
-		runFilegroupTestCase(t, Bp2buildTestCase{
-			Description:          test.name,
-			Blueprint:            test.bp,
-			ExpectedBazelTargets: expectedBazelTargets,
+		t.Run(test.name, func(t *testing.T) {
+			expectedBazelTargets := []string{
+				MakeBazelTargetNoRestrictions("aidl_library", "foo", test.expectedBazelAttrs),
+			}
+			runFilegroupTestCase(t, Bp2buildTestCase{
+				Description:          test.name,
+				Blueprint:            test.bp,
+				ExpectedBazelTargets: expectedBazelTargets,
+			})
 		})
 	}
 }
@@ -136,7 +140,11 @@
 			MakeBazelTargetNoRestrictions("proto_library", "foo_bp2build_converted", AttrNameToString{
 				"srcs":                `["proto/foo.proto"]`,
 				"strip_import_prefix": `"proto"`,
-				"tags":                `["manual"]`}),
+				"tags": `[
+        "apex_available=//apex_available:anyapex",
+        "manual",
+    ]`,
+			}),
 			MakeBazelTargetNoRestrictions("filegroup", "foo", AttrNameToString{
 				"srcs": `["proto/foo.proto"]`}),
 		}})
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index e3c4857..69d0db9 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -493,6 +493,7 @@
         "a.aidl",
         "b.aidl",
     ]`,
+				"tags": `["apex_available=//apex_available:anyapex"]`,
 			}),
 			MakeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
 				"deps": `[":aidl_files"]`,
diff --git a/bp2build/testing.go b/bp2build/testing.go
index ee2ab08..856b6ee 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -228,6 +228,7 @@
 //
 // If ignoreUnexpected=true then it will ignore directories for which there are no expected targets.
 func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, description string, expectedTargets map[string][]string, ignoreUnexpected bool) {
+	t.Helper()
 	actualTargets := b.buildFileToTargets
 
 	// Generate the sorted set of directories to check.
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 03d9de8..7c817a2 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -65,6 +65,8 @@
 
 	Native_coverage *bool
 
+	Apex_available []string
+
 	sdkAttributes
 
 	tidyAttributes
@@ -220,7 +222,7 @@
 }
 
 // Parses properties common to static and shared libraries. Also used for prebuilt libraries.
-func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, _ *libraryDecorator, isStatic bool) staticOrSharedAttributes {
+func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
 	attrs := staticOrSharedAttributes{}
 
 	setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
@@ -244,13 +246,16 @@
 	//    empty list -> no values specified
 	attrs.System_dynamic_deps.ForceSpecifyEmptyList = true
 
+	var apexAvailable []string
 	if isStatic {
+		apexAvailable = lib.StaticProperties.Static.Apex_available
 		bp2BuildPropParseHelper(ctx, module, &StaticProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
 			if staticOrSharedProps, ok := props.(*StaticProperties); ok {
 				setAttrs(axis, config, staticOrSharedProps.Static)
 			}
 		})
 	} else {
+		apexAvailable = lib.SharedProperties.Shared.Apex_available
 		bp2BuildPropParseHelper(ctx, module, &SharedProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
 			if staticOrSharedProps, ok := props.(*SharedProperties); ok {
 				setAttrs(axis, config, staticOrSharedProps.Shared)
@@ -263,6 +268,8 @@
 	attrs.Srcs_c = partitionedSrcs[cSrcPartition]
 	attrs.Srcs_as = partitionedSrcs[asSrcPartition]
 
+	attrs.Apex_available = android.ConvertApexAvailableToTags(apexAvailable)
+
 	if !partitionedSrcs[protoSrcPartition].IsEmpty() {
 		// TODO(b/208815215): determine whether this is used and add support if necessary
 		ctx.ModuleErrorf("Migrating static/shared only proto srcs is not currently supported")
@@ -732,7 +739,7 @@
 			if baseLinkerProps, ok := archVariantLinkerProps[axis][cfg].(*BaseLinkerProperties); ok {
 				exportHdrs = baseLinkerProps.Export_generated_headers
 
-				(&linkerAttrs).bp2buildForAxisAndConfig(ctx, module.Binary(), axis, cfg, baseLinkerProps)
+				(&linkerAttrs).bp2buildForAxisAndConfig(ctx, module, axis, cfg, baseLinkerProps)
 			}
 			headers := maybePartitionExportedAndImplementationsDeps(ctx, !module.Binary(), allHdrs, exportHdrs, android.BazelLabelForModuleDeps)
 			implementationHdrs.SetSelectValue(axis, cfg, headers.implementation)
@@ -900,6 +907,9 @@
 			return false
 		})
 
+		apexAvailableTags := android.ApexAvailableTags(ctx.Module())
+		sdkAttrs := bp2BuildParseSdkAttributes(m)
+
 		if !aidlSrcs.IsEmpty() {
 			aidlLibName := m.Name() + "_aidl_library"
 			ctx.CreateBazelTargetModule(
@@ -910,6 +920,7 @@
 				android.CommonAttributes{Name: aidlLibName},
 				&aidlLibraryAttributes{
 					Srcs: aidlSrcs,
+					Tags: apexAvailableTags,
 				},
 			)
 			aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}})
@@ -934,6 +945,8 @@
 					Deps:                        aidlLibs,
 					Implementation_deps:         *implementationDeps,
 					Implementation_dynamic_deps: *implementationDynamicDeps,
+					Tags:                        apexAvailableTags,
+					sdkAttributes:               sdkAttrs,
 				},
 			)
 			label := &bazel.LabelAttribute{
@@ -1008,7 +1021,8 @@
 	la.implementationDeps.Append(staticExcludesLabelList)
 }
 
-func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, isBinary bool, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) {
+func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, module *Module, axis bazel.ConfigurationAxis, config string, props *BaseLinkerProperties) {
+	isBinary := module.Binary()
 	// Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module
 	var axisFeatures []string
 
@@ -1092,8 +1106,9 @@
 		// dependencies in NoConfigAxis and OsConfigurationAxis/OsAndroid are grouped by
 		// having stubs or not, so Bazel select() statement can be used to choose
 		// source/stub variants of them.
-		setStubsForDynamicDeps(ctx, axis, config, sharedDeps.export, &la.dynamicDeps, 0)
-		setStubsForDynamicDeps(ctx, axis, config, sharedDeps.implementation, &la.implementationDynamicDeps, 1)
+		apexAvailable := module.ApexAvailable()
+		setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, 0)
+		setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, 1)
 	}
 
 	if !BoolDefault(props.Pack_relocations, packRelocationsDefault) {
@@ -1154,13 +1169,25 @@
 	apiSurfaceModuleLibCurrentPackage = "@api_surfaces//" + android.ModuleLibApi.String() + "/current:"
 )
 
+func availableToSameApexes(a, b []string) bool {
+	if len(a) == 0 && len(b) == 0 {
+		return true
+	}
+	differ, _, _ := android.ListSetDifference(a, b)
+	return !differ
+}
+
 func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis,
-	config string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int) {
+	config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int) {
+
 	depsWithStubs := []bazel.Label{}
 	for _, l := range dynamicLibs.Includes {
 		dep, _ := ctx.ModuleFromName(l.OriginalModuleName)
-		if m, ok := dep.(*Module); ok && m.HasStubsVariants() {
-			depsWithStubs = append(depsWithStubs, l)
+		if d, ok := dep.(*Module); ok && d.HasStubsVariants() {
+			depApexAvailable := d.ApexAvailable()
+			if !availableToSameApexes(apexAvailable, depApexAvailable) {
+				depsWithStubs = append(depsWithStubs, l)
+			}
 		}
 	}
 	if len(depsWithStubs) > 0 {
@@ -1170,7 +1197,7 @@
 		stubLibLabels := []bazel.Label{}
 		for _, l := range depsWithStubs {
 			stubLabelInApiSurfaces := bazel.Label{
-				Label: apiSurfaceModuleLibCurrentPackage + l.OriginalModuleName,
+				Label: apiSurfaceModuleLibCurrentPackage + strings.TrimPrefix(l.OriginalModuleName, ":"),
 			}
 			stubLibLabels = append(stubLibLabels, stubLabelInApiSurfaces)
 		}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index b02e037..b986511 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3572,6 +3572,114 @@
 	}
 }
 
+func TestStubsForLibraryInMultipleApexes(t *testing.T) {
+	// TODO(b/275313114): Test exposes non-determinism which should be corrected and the test
+	// reenabled.
+	t.Skip()
+	t.Parallel()
+	ctx := testCc(t, `
+		cc_library_shared {
+			name: "libFoo",
+			srcs: ["foo.c"],
+			stubs: {
+				symbol_file: "foo.map.txt",
+				versions: ["current"],
+			},
+			apex_available: ["bar", "a1"],
+		}
+
+		cc_library_shared {
+			name: "libBar",
+			srcs: ["bar.c"],
+			shared_libs: ["libFoo"],
+			apex_available: ["a1"],
+		}
+
+		cc_library_shared {
+			name: "libA1",
+			srcs: ["a1.c"],
+			shared_libs: ["libFoo"],
+			apex_available: ["a1"],
+		}
+
+		cc_library_shared {
+			name: "libBarA1",
+			srcs: ["bara1.c"],
+			shared_libs: ["libFoo"],
+			apex_available: ["bar", "a1"],
+		}
+
+		cc_library_shared {
+			name: "libAnyApex",
+			srcs: ["anyApex.c"],
+			shared_libs: ["libFoo"],
+			apex_available: ["//apex_available:anyapex"],
+		}
+
+		cc_library_shared {
+			name: "libBaz",
+			srcs: ["baz.c"],
+			shared_libs: ["libFoo"],
+			apex_available: ["baz"],
+		}
+
+		cc_library_shared {
+			name: "libQux",
+			srcs: ["qux.c"],
+			shared_libs: ["libFoo"],
+			apex_available: ["qux", "bar"],
+		}`)
+
+	variants := ctx.ModuleVariantsForTests("libFoo")
+	expectedVariants := []string{
+		"android_arm64_armv8-a_shared",
+		"android_arm64_armv8-a_shared_current",
+		"android_arm_armv7-a-neon_shared",
+		"android_arm_armv7-a-neon_shared_current",
+	}
+	variantsMismatch := false
+	if len(variants) != len(expectedVariants) {
+		variantsMismatch = true
+	} else {
+		for _, v := range expectedVariants {
+			if !inList(v, variants) {
+				variantsMismatch = false
+			}
+		}
+	}
+	if variantsMismatch {
+		t.Errorf("variants of libFoo expected:\n")
+		for _, v := range expectedVariants {
+			t.Errorf("%q\n", v)
+		}
+		t.Errorf(", but got:\n")
+		for _, v := range variants {
+			t.Errorf("%q\n", v)
+		}
+	}
+
+	linkAgainstFoo := []string{"libBarA1"}
+	linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"}
+
+	libFooPath := "libFoo/android_arm64_armv8-a_shared/libFoo.so"
+	for _, lib := range linkAgainstFoo {
+		libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
+		libFlags := libLinkRule.Args["libFlags"]
+		if !strings.Contains(libFlags, libFooPath) {
+			t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags)
+		}
+	}
+
+	libFooStubPath := "libFoo/android_arm64_armv8-a_shared_current/libFoo.so"
+	for _, lib := range linkAgainstFooStubs {
+		libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
+		libFlags := libLinkRule.Args["libFlags"]
+		if !strings.Contains(libFlags, libFooStubPath) {
+			t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags)
+		}
+	}
+}
+
 func TestVersioningMacro(t *testing.T) {
 	t.Parallel()
 	for _, tc := range []struct{ moduleName, expected string }{
diff --git a/cc/library.go b/cc/library.go
index 1b579cd..a9ada97 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -264,12 +264,15 @@
 type aidlLibraryAttributes struct {
 	Srcs        bazel.LabelListAttribute
 	Include_dir *string
+	Tags        bazel.StringListAttribute
 }
 
 type ccAidlLibraryAttributes struct {
 	Deps                        bazel.LabelListAttribute
 	Implementation_deps         bazel.LabelListAttribute
 	Implementation_dynamic_deps bazel.LabelListAttribute
+	Tags                        bazel.StringListAttribute
+	sdkAttributes
 }
 
 type stripAttributes struct {
@@ -428,8 +431,10 @@
 	if compilerAttrs.stubsSymbolFile == nil && len(compilerAttrs.stubsVersions.Value) == 0 {
 		tagsForStaticVariant = android.ApexAvailableTags(m)
 	}
+	tagsForStaticVariant.Append(bazel.StringListAttribute{Value: staticAttrs.Apex_available})
 
 	tagsForSharedVariant := android.ApexAvailableTags(m)
+	tagsForSharedVariant.Append(bazel.StringListAttribute{Value: sharedAttrs.Apex_available})
 
 	ctx.CreateBazelTargetModuleWithRestrictions(staticProps,
 		android.CommonAttributes{
diff --git a/cc/sysprop.go b/cc/sysprop.go
index 2b1e354..0df290a 100644
--- a/cc/sysprop.go
+++ b/cc/sysprop.go
@@ -22,11 +22,13 @@
 // TODO(b/240463568): Additional properties will be added for API validation
 type bazelSyspropLibraryAttributes struct {
 	Srcs bazel.LabelListAttribute
+	Tags bazel.StringListAttribute
 }
 
 type bazelCcSyspropLibraryAttributes struct {
 	Dep             bazel.LabelAttribute
 	Min_sdk_version *string
+	Tags            bazel.StringListAttribute
 }
 
 type SyspropLibraryLabels struct {
@@ -36,6 +38,7 @@
 }
 
 func Bp2buildSysprop(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLabels, srcs bazel.LabelListAttribute, minSdkVersion *string) {
+	apexAvailableTags := android.ApexAvailableTags(ctx.Module())
 	ctx.CreateBazelTargetModule(
 		bazel.BazelTargetModuleProperties{
 			Rule_class:        "sysprop_library",
@@ -44,11 +47,14 @@
 		android.CommonAttributes{Name: labels.SyspropLibraryLabel},
 		&bazelSyspropLibraryAttributes{
 			Srcs: srcs,
-		})
+			Tags: apexAvailableTags,
+		},
+	)
 
 	attrs := &bazelCcSyspropLibraryAttributes{
 		Dep:             *bazel.MakeLabelAttribute(":" + labels.SyspropLibraryLabel),
 		Min_sdk_version: minSdkVersion,
+		Tags:            apexAvailableTags,
 	}
 
 	if labels.SharedLibraryLabel != "" {
diff --git a/java/java.go b/java/java.go
index 2a7e4e1..3707815 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2625,10 +2625,12 @@
 
 type aidlLibraryAttributes struct {
 	Srcs bazel.LabelListAttribute
+	Tags bazel.StringListAttribute
 }
 
 type javaAidlLibraryAttributes struct {
 	Deps bazel.LabelListAttribute
+	Tags bazel.StringListAttribute
 }
 
 // bp2BuildJavaInfo has information needed for the conversion of  java*_modules
@@ -2700,6 +2702,8 @@
 			return android.IsConvertedToAidlLibrary(ctx, src.OriginalModuleName)
 		})
 
+		apexAvailableTags := android.ApexAvailableTags(ctx.Module())
+
 		if !aidlSrcs.IsEmpty() {
 			aidlLibName := m.Name() + "_aidl_library"
 			ctx.CreateBazelTargetModule(
@@ -2710,6 +2714,7 @@
 				android.CommonAttributes{Name: aidlLibName},
 				&aidlLibraryAttributes{
 					Srcs: aidlSrcs,
+					Tags: apexAvailableTags,
 				},
 			)
 			aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}})
@@ -2724,6 +2729,7 @@
 			android.CommonAttributes{Name: javaAidlLibName},
 			&javaAidlLibraryAttributes{
 				Deps: aidlLibs,
+				Tags: apexAvailableTags,
 			},
 		)