Merge "Stem name should be fixed the same was as masterFile" into rvc-dev
diff --git a/android/module.go b/android/module.go
index 0bf48d5..5bccb79 100644
--- a/android/module.go
+++ b/android/module.go
@@ -819,6 +819,10 @@
 	return m.Os().Class == Host || m.Os().Class == HostCross
 }
 
+func (m *ModuleBase) Device() bool {
+	return m.Os().Class == Device
+}
+
 func (m *ModuleBase) Arch() Arch {
 	return m.Target().Arch
 }
diff --git a/android/neverallow.go b/android/neverallow.go
index 8563ebd..2eba4a9 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -253,6 +253,10 @@
 			continue
 		}
 
+		if !n.appliesToBootclasspathJar(ctx) {
+			continue
+		}
+
 		ctx.ModuleErrorf("violates " + n.String())
 	}
 }
@@ -311,6 +315,18 @@
 	return ".regexp(" + m.re.String() + ")"
 }
 
+type notInListMatcher struct {
+	allowed []string
+}
+
+func (m *notInListMatcher) Test(value string) bool {
+	return !InList(value, m.allowed)
+}
+
+func (m *notInListMatcher) String() string {
+	return ".not-in-list(" + strings.Join(m.allowed, ",") + ")"
+}
+
 type isSetMatcher struct{}
 
 func (m *isSetMatcher) Test(value string) bool {
@@ -342,6 +358,8 @@
 
 	NotModuleType(types ...string) Rule
 
+	BootclasspathJar() Rule
+
 	With(properties, value string) Rule
 
 	WithMatcher(properties string, matcher ValueMatcher) Rule
@@ -369,6 +387,8 @@
 
 	props       []ruleProperty
 	unlessProps []ruleProperty
+
+	onlyBootclasspathJar bool
 }
 
 // Create a new NeverAllow rule.
@@ -444,6 +464,11 @@
 	return r
 }
 
+func (r *rule) BootclasspathJar() Rule {
+	r.onlyBootclasspathJar = true
+	return r
+}
+
 func (r *rule) String() string {
 	s := "neverallow"
 	for _, v := range r.paths {
@@ -470,6 +495,9 @@
 	for _, v := range r.osClasses {
 		s += " os:" + v.String()
 	}
+	if r.onlyBootclasspathJar {
+		s += " inBcp"
+	}
 	if len(r.reason) != 0 {
 		s += " which is restricted because " + r.reason
 	}
@@ -498,6 +526,14 @@
 	return matches
 }
 
+func (r *rule) appliesToBootclasspathJar(ctx BottomUpMutatorContext) bool {
+	if !r.onlyBootclasspathJar {
+		return true
+	}
+
+	return InList(ctx.ModuleName(), ctx.Config().BootJars())
+}
+
 func (r *rule) appliesToOsClass(osClass OsClass) bool {
 	if len(r.osClasses) == 0 {
 		return true
@@ -534,6 +570,10 @@
 	return &regexMatcher{r}
 }
 
+func NotInList(allowed []string) ValueMatcher {
+	return &notInListMatcher{allowed}
+}
+
 // assorted utils
 
 func cleanPaths(paths []string) []string {
diff --git a/apex/apex.go b/apex/apex.go
index 994a051..a63a8d6 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -688,6 +688,55 @@
 	return m
 }
 
+// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
+// Adding code to the bootclasspath in new packages will cause issues on module update.
+func qModulesPackages() map[string][]string {
+	return map[string][]string{
+		"com.android.conscrypt": []string{
+			"android.net.ssl",
+			"com.android.org.conscrypt",
+		},
+		"com.android.media": []string{
+			"android.media",
+		},
+	}
+}
+
+// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
+// Adding code to the bootclasspath in new packages will cause issues on module update.
+func rModulesPackages() map[string][]string {
+	return map[string][]string{
+		"com.android.mediaprovider": []string{
+			"android.provider",
+		},
+		"com.android.permission": []string{
+			"android.permission",
+			"android.app.role",
+			"com.android.permission",
+			"com.android.role",
+		},
+		"com.android.sdkext": []string{
+			"android.os.ext",
+		},
+		"com.android.os.statsd": []string{
+			"android.app",
+			"android.os",
+			"android.util",
+			"com.android.internal.statsd",
+			"com.android.server.stats",
+		},
+		"com.android.wifi": []string{
+			"com.android.server.wifi",
+			"com.android.wifi.x",
+			"android.hardware.wifi",
+			"android.net.wifi",
+		},
+		"com.android.tethering": []string{
+			"android.net",
+		},
+	}
+}
+
 func init() {
 	android.RegisterModuleType("apex", BundleFactory)
 	android.RegisterModuleType("apex_test", testApexBundleFactory)
@@ -705,6 +754,24 @@
 		sort.Strings(*apexFileContextsInfos)
 		ctx.Strict("APEX_FILE_CONTEXTS_INFOS", strings.Join(*apexFileContextsInfos, " "))
 	})
+
+	android.AddNeverAllowRules(createApexPermittedPackagesRules(qModulesPackages())...)
+	android.AddNeverAllowRules(createApexPermittedPackagesRules(rModulesPackages())...)
+}
+
+func createApexPermittedPackagesRules(modules_packages map[string][]string) []android.Rule {
+	rules := make([]android.Rule, 0, len(modules_packages))
+	for module_name, module_packages := range modules_packages {
+		permitted_packages_rule := android.NeverAllow().
+			BootclasspathJar().
+			With("apex_available", module_name).
+			WithMatcher("permitted_packages", android.NotInList(module_packages)).
+			Because("jars that are part of the " + module_name +
+				" module may only allow these packages: " + strings.Join(module_packages, ",") +
+				". Please jarjar or move code around.")
+		rules = append(rules, permitted_packages_rule)
+	}
+	return rules
 }
 
 func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
@@ -1031,9 +1098,6 @@
 	// List of providing APEXes' names so that this APEX can depend on provided shared libraries.
 	Uses []string
 
-	// A txt file containing list of files that are allowed to be included in this APEX.
-	Allowed_files *string
-
 	// package format of this apex variant; could be non-flattened, flattened, or zip.
 	// imageApex, zipApex or flattened
 	ApexType apexPackaging `blueprint:"mutated"`
@@ -1106,6 +1170,9 @@
 	// Apex Container Package Name.
 	// Override value for attribute package:name in AndroidManifest.xml
 	Package_name string
+
+	// A txt file containing list of files that are allowed to be included in this APEX.
+	Allowed_files *string `android:"path"`
 }
 
 type apexPackaging int
@@ -1510,6 +1577,9 @@
 }
 
 func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
+	if a.overridableProperties.Allowed_files != nil {
+		android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
+	}
 	ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
 		androidAppTag, a.overridableProperties.Apps...)
 }
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e2cc104..8803a5f 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -4855,6 +4855,141 @@
 	testNoUpdatableJarsInBootImage(t, "", bp, transform)
 }
 
+func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJars []string, rules []android.Rule) {
+	t.Helper()
+	android.ClearApexDependency()
+	bp += `
+	apex_key {
+		name: "myapex.key",
+		public_key: "testkey.avbpubkey",
+		private_key: "testkey.pem",
+	}`
+	fs := map[string][]byte{
+		"lib1/src/A.java": nil,
+		"lib2/src/B.java": nil,
+		"system/sepolicy/apex/myapex-file_contexts": nil,
+	}
+
+	ctx := android.NewTestArchContext()
+	ctx.RegisterModuleType("apex", BundleFactory)
+	ctx.RegisterModuleType("apex_key", ApexKeyFactory)
+	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+	cc.RegisterRequiredBuildComponentsForTest(ctx)
+	java.RegisterJavaBuildComponents(ctx)
+	java.RegisterSystemModulesBuildComponents(ctx)
+	java.RegisterDexpreoptBootJarsComponents(ctx)
+	ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
+	ctx.PreDepsMutators(RegisterPreDepsMutators)
+	ctx.PostDepsMutators(RegisterPostDepsMutators)
+	ctx.PostDepsMutators(android.RegisterNeverallowMutator)
+
+	config := android.TestArchConfig(buildDir, nil, bp, fs)
+	android.SetTestNeverallowRules(config, rules)
+	updatableBootJars := make([]string, 0, len(apexBootJars))
+	for _, apexBootJar := range apexBootJars {
+		updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
+	}
+	config.TestProductVariables.UpdatableBootJars = updatableBootJars
+
+	ctx.Register(config)
+
+	_, errs := ctx.ParseBlueprintsFiles("Android.bp")
+	android.FailIfErrored(t, errs)
+
+	_, errs = ctx.PrepareBuildActions(config)
+	if errmsg == "" {
+		android.FailIfErrored(t, errs)
+	} else if len(errs) > 0 {
+		android.FailIfNoMatchingErrors(t, errmsg, errs)
+		return
+	} else {
+		t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
+	}
+}
+
+func TestApexPermittedPackagesRules(t *testing.T) {
+	testcases := []struct {
+		name            string
+		expectedError   string
+		bp              string
+		bootJars        []string
+		modulesPackages map[string][]string
+	}{
+
+		{
+			name:          "Non-Bootclasspath apex jar not satisfying allowed module packages.",
+			expectedError: "",
+			bp: `
+				java_library {
+					name: "bcp_lib1",
+					srcs: ["lib1/src/*.java"],
+					permitted_packages: ["foo.bar"],
+					apex_available: ["myapex"],
+					sdk_version: "none",
+					system_modules: "none",
+				}
+				java_library {
+					name: "nonbcp_lib2",
+					srcs: ["lib2/src/*.java"],
+					apex_available: ["myapex"],
+					permitted_packages: ["a.b"],
+					sdk_version: "none",
+					system_modules: "none",
+				}
+				apex {
+					name: "myapex",
+					key: "myapex.key",
+					java_libs: ["bcp_lib1", "nonbcp_lib2"],
+				}`,
+			bootJars: []string{"bcp_lib1"},
+			modulesPackages: map[string][]string{
+				"myapex": []string{
+					"foo.bar",
+				},
+			},
+		},
+		{
+			name:          "Bootclasspath apex jar not satisfying allowed module packages.",
+			expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar. Please jarjar or move code around.`,
+			bp: `
+				java_library {
+					name: "bcp_lib1",
+					srcs: ["lib1/src/*.java"],
+					apex_available: ["myapex"],
+					permitted_packages: ["foo.bar"],
+					sdk_version: "none",
+					system_modules: "none",
+				}
+				java_library {
+					name: "bcp_lib2",
+					srcs: ["lib2/src/*.java"],
+					apex_available: ["myapex"],
+					permitted_packages: ["foo.bar", "bar.baz"],
+					sdk_version: "none",
+					system_modules: "none",
+				}
+				apex {
+					name: "myapex",
+					key: "myapex.key",
+					java_libs: ["bcp_lib1", "bcp_lib2"],
+				}
+			`,
+			bootJars: []string{"bcp_lib1", "bcp_lib2"},
+			modulesPackages: map[string][]string{
+				"myapex": []string{
+					"foo.bar",
+				},
+			},
+		},
+	}
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			rules := createApexPermittedPackagesRules(tc.modulesPackages)
+			testApexPermittedPackagesRules(t, tc.expectedError, tc.bp, tc.bootJars, rules)
+		})
+	}
+}
+
 func TestTestFor(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
@@ -4991,6 +5126,61 @@
 	ensureContains(t, content, `name="myapex.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`)
 }
 
+func TestAllowedFiles(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			apps: ["app"],
+			allowed_files: "allowed.txt",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		android_app {
+			name: "app",
+			srcs: ["foo/bar/MyClass.java"],
+			package_name: "foo",
+			sdk_version: "none",
+			system_modules: "none",
+			apex_available: [ "myapex" ],
+		}
+	`, withFiles(map[string][]byte{
+		"sub/Android.bp": []byte(`
+			override_apex {
+				name: "override_myapex",
+				base: "myapex",
+				apps: ["override_app"],
+				allowed_files: ":allowed",
+			}
+			// Overridable "path" property should be referenced indirectly
+			filegroup {
+				name: "allowed",
+				srcs: ["allowed.txt"],
+			}
+			override_android_app {
+				name: "override_app",
+				base: "app",
+				package_name: "bar",
+			}
+			`),
+	}))
+
+	rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("diffApexContentRule")
+	if expected, actual := "allowed.txt", rule.Args["allowed_files_file"]; expected != actual {
+		t.Errorf("allowed_files_file: expected %q but got %q", expected, actual)
+	}
+
+	rule2 := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image").Rule("diffApexContentRule")
+	if expected, actual := "sub/allowed.txt", rule2.Args["allowed_files_file"]; expected != actual {
+		t.Errorf("allowed_files_file: expected %q but got %q", expected, actual)
+	}
+}
+
 func TestMain(m *testing.M) {
 	run := func() int {
 		setUp()
diff --git a/apex/builder.go b/apex/builder.go
index 1f3066e..e1b2dab 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -369,7 +369,7 @@
 	emitCommands = append(emitCommands, "sort -o "+imageContentFile.String()+" "+imageContentFile.String())
 	implicitInputs = append(implicitInputs, a.manifestPbOut)
 
-	if a.properties.Allowed_files != nil {
+	if a.overridableProperties.Allowed_files != nil {
 		ctx.Build(pctx, android.BuildParams{
 			Rule:        emitApexContentRule,
 			Implicits:   implicitInputs,
@@ -380,7 +380,7 @@
 			},
 		})
 		implicitInputs = append(implicitInputs, imageContentFile)
-		allowedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.Allowed_files))
+		allowedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.overridableProperties.Allowed_files))
 
 		phonyOutput := android.PathForModuleOut(ctx, a.Name()+"-diff-phony-output")
 		ctx.Build(pctx, android.BuildParams{
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 76b4e38..f73e021 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -430,6 +430,40 @@
 	checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil)
 }
 
+func TestVndkWithHostSupported(t *testing.T) {
+	ctx := testCc(t, `
+		cc_library {
+			name: "libvndk_host_supported",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			host_supported: true,
+		}
+
+		cc_library {
+			name: "libvndk_host_supported_but_disabled_on_device",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			host_supported: true,
+			enabled: false,
+			target: {
+				host: {
+					enabled: true,
+				}
+			}
+		}
+
+		vndk_libraries_txt {
+			name: "vndkcore.libraries.txt",
+		}
+	`)
+
+	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk_host_supported.so"})
+}
+
 func TestVndkLibrariesTxtAndroidMk(t *testing.T) {
 	bp := `
 		vndk_libraries_txt {
diff --git a/cc/vndk.go b/cc/vndk.go
index ef33c1a..a060869 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -334,16 +334,24 @@
 	}
 }
 
-func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
+// Sanity check for modules that mustn't be VNDK
+func shouldSkipVndkMutator(m *Module) bool {
 	if !m.Enabled() {
-		return false
+		return true
 	}
-
-	if !mctx.Device() {
-		return false
+	if !m.Device() {
+		// Skip non-device modules
+		return true
 	}
-
 	if m.Target().NativeBridge == android.NativeBridgeEnabled {
+		// Skip native_bridge modules
+		return true
+	}
+	return false
+}
+
+func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
+	if shouldSkipVndkMutator(m) {
 		return false
 	}
 
@@ -377,11 +385,8 @@
 	if !ok {
 		return
 	}
-	if !m.Enabled() {
-		return
-	}
-	if m.Target().NativeBridge == android.NativeBridgeEnabled {
-		// Skip native_bridge modules
+
+	if shouldSkipVndkMutator(m) {
 		return
 	}