Merge "Skip version mutator for host/ramdisk/recovery" into rvc-dev
diff --git a/README.md b/README.md
index 3eac87b..8b028a8 100644
--- a/README.md
+++ b/README.md
@@ -421,6 +421,7 @@
     config_namespace: "acme",
     variables: ["board"],
     bool_variables: ["feature"],
+    value_variables: ["width"],
     properties: ["cflags", "srcs"],
 }
 
@@ -431,8 +432,9 @@
 ```
 
 This example describes a new `acme_cc_defaults` module type that extends the
-`cc_defaults` module type, with two additional conditionals based on variables
-`board` and `feature`, which can affect properties `cflags` and `srcs`.
+`cc_defaults` module type, with three additional conditionals based on
+variables `board`, `feature` and `width`, which can affect properties `cflags`
+and `srcs`.
 
 The values of the variables can be set from a product's `BoardConfig.mk` file:
 ```
@@ -443,6 +445,7 @@
 
 SOONG_CONFIG_acme_board := soc_a
 SOONG_CONFIG_acme_feature := true
+SOONG_CONFIG_acme_width := 200
 ```
 
 The `acme_cc_defaults` module type can be used anywhere after the definition in
@@ -471,6 +474,9 @@
         feature: {
             cflags: ["-DFEATURE"],
         },
+        width: {
+            cflags: ["-DWIDTH=%s"],
+        },
     },
 }
 
@@ -482,7 +488,7 @@
 ```
 
 With the `BoardConfig.mk` snippet above, libacme_foo would build with
-cflags "-DGENERIC -DSOC_A -DFEATURE".
+cflags "-DGENERIC -DSOC_A -DFEATURE -DWIDTH=200".
 
 `soong_config_module_type` modules will work best when used to wrap defaults
 modules (`cc_defaults`, `java_defaults`, etc.), which can then be referenced
diff --git a/android/mutator.go b/android/mutator.go
index a46d4be..10a815a 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -103,7 +103,7 @@
 	registerPathDepsMutator,
 	RegisterPrebuiltsPostDepsMutators,
 	RegisterVisibilityRuleEnforcer,
-	registerNeverallowMutator,
+	RegisterNeverallowMutator,
 	RegisterOverridePostDepsMutators,
 }
 
diff --git a/android/neverallow.go b/android/neverallow.go
index 8fcfb8a..4d3a16f 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -17,6 +17,7 @@
 import (
 	"path/filepath"
 	"reflect"
+	"regexp"
 	"strconv"
 	"strings"
 
@@ -41,7 +42,7 @@
 //     counts as a match
 // - it has none of the "Without" properties matched (same rules as above)
 
-func registerNeverallowMutator(ctx RegisterMutatorsContext) {
+func RegisterNeverallowMutator(ctx RegisterMutatorsContext) {
 	ctx.BottomUp("neverallow", neverallowMutator).Parallel()
 }
 
@@ -146,7 +147,8 @@
 	rules := []Rule{
 		NeverAllow().
 			NotIn(coreLibraryProjects...).
-			With("sdk_version", "none"),
+			With("sdk_version", "none").
+			WithoutMatcher("name", Regexp("^android_.*stubs_current$")),
 	}
 
 	return rules
@@ -213,7 +215,7 @@
 }
 
 type ValueMatcher interface {
-	test(string) bool
+	Test(string) bool
 	String() string
 }
 
@@ -221,7 +223,7 @@
 	expected string
 }
 
-func (m *equalMatcher) test(value string) bool {
+func (m *equalMatcher) Test(value string) bool {
 	return m.expected == value
 }
 
@@ -232,7 +234,7 @@
 type anyMatcher struct {
 }
 
-func (m *anyMatcher) test(value string) bool {
+func (m *anyMatcher) Test(value string) bool {
 	return true
 }
 
@@ -246,7 +248,7 @@
 	prefix string
 }
 
-func (m *startsWithMatcher) test(value string) bool {
+func (m *startsWithMatcher) Test(value string) bool {
 	return strings.HasPrefix(value, m.prefix)
 }
 
@@ -254,6 +256,18 @@
 	return ".starts-with(" + m.prefix + ")"
 }
 
+type regexMatcher struct {
+	re *regexp.Regexp
+}
+
+func (m *regexMatcher) Test(value string) bool {
+	return m.re.MatchString(value)
+}
+
+func (m *regexMatcher) String() string {
+	return ".regexp(" + m.re.String() + ")"
+}
+
 type ruleProperty struct {
 	fields  []string // e.x.: Vndk.Enabled
 	matcher ValueMatcher
@@ -457,6 +471,14 @@
 	return &startsWithMatcher{prefix}
 }
 
+func Regexp(re string) ValueMatcher {
+	r, err := regexp.Compile(re)
+	if err != nil {
+		panic(err)
+	}
+	return &regexMatcher{r}
+}
+
 // assorted utils
 
 func cleanPaths(paths []string) []string {
@@ -507,7 +529,7 @@
 		}
 
 		check := func(value string) bool {
-			return prop.matcher.test(value)
+			return prop.matcher.Test(value)
 		}
 
 		if matchValue(propertiesValue, check) {
@@ -564,6 +586,6 @@
 // Overrides the default neverallow rules for the supplied config.
 //
 // For testing only.
-func setTestNeverallowRules(config Config, testRules []Rule) {
+func SetTestNeverallowRules(config Config, testRules []Rule) {
 	config.Once(neverallowRulesKey, func() interface{} { return testRules })
 }
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 6f07a4a..83b2250 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -227,6 +227,16 @@
 		},
 	},
 	{
+		name: "sdk_version: \"none\" on android_*stubs_current stub",
+		fs: map[string][]byte{
+			"frameworks/base/Android.bp": []byte(`
+				java_library {
+					name: "android_stubs_current",
+					sdk_version: "none",
+				}`),
+		},
+	},
+	{
 		name: "sdk_version: \"none\" outside core libraries",
 		fs: map[string][]byte{
 			"Android.bp": []byte(`
@@ -259,7 +269,7 @@
 		t.Run(test.name, func(t *testing.T) {
 			// If the test has its own rules then use them instead of the default ones.
 			if test.rules != nil {
-				setTestNeverallowRules(config, test.rules)
+				SetTestNeverallowRules(config, test.rules)
 			}
 			_, errs := testNeverallow(config)
 			CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
@@ -273,7 +283,7 @@
 	ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
 	ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
 	ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
-	ctx.PostDepsMutators(registerNeverallowMutator)
+	ctx.PostDepsMutators(RegisterNeverallowMutator)
 	ctx.Register(config)
 
 	_, errs := ctx.ParseBlueprintsFiles("Android.bp")
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index fa1e204..619cf86 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -73,6 +73,9 @@
 //             feature: {
 //                 cflags: ["-DFEATURE"],
 //             },
+//             width: {
+//                 cflags: ["-DWIDTH=%s"],
+//             },
 //         },
 //     }
 //
@@ -90,6 +93,7 @@
 //         config_namespace: "acme",
 //         variables: ["board"],
 //         bool_variables: ["feature"],
+//         value_variables: ["width"],
 //         properties: ["cflags", "srcs"],
 //     }
 //
@@ -107,8 +111,9 @@
 //
 //     SOONG_CONFIG_acme_board := soc_a
 //     SOONG_CONFIG_acme_feature := true
+//     SOONG_CONFIG_acme_width := 200
 //
-// Then libacme_foo would build with cflags "-DGENERIC -DSOC_A -DFEATURE".
+// Then libacme_foo would build with cflags "-DGENERIC -DSOC_A -DFEATURE -DWIDTH=200".
 func soongConfigModuleTypeImportFactory() Module {
 	module := &soongConfigModuleTypeImport{}
 
@@ -122,7 +127,10 @@
 }
 
 func (m *soongConfigModuleTypeImport) Name() string {
-	return "soong_config_module_type_import_" + soongconfig.CanonicalizeToProperty(m.properties.From)
+	// The generated name is non-deterministic, but it does not
+	// matter because this module does not emit any rules.
+	return soongconfig.CanonicalizeToProperty(m.properties.From) +
+		"soong_config_module_type_import_" + fmt.Sprintf("%p", m)
 }
 
 func (*soongConfigModuleTypeImport) Nameless()                                 {}
@@ -148,6 +156,7 @@
 //         config_namespace: "acme",
 //         variables: ["board"],
 //         bool_variables: ["feature"],
+//         value_variables: ["width"],
 //         properties: ["cflags", "srcs"],
 //     }
 //
@@ -171,6 +180,9 @@
 //             feature: {
 //                 cflags: ["-DFEATURE"],
 //             },
+//             width: {
+//	               cflags: ["-DWIDTH=%s"],
+//             },
 //         },
 //     }
 //
@@ -189,6 +201,7 @@
 //
 //     SOONG_CONFIG_acme_board := soc_a
 //     SOONG_CONFIG_acme_feature := true
+//     SOONG_CONFIG_acme_width := 200
 //
 // Then libacme_foo would build with cflags "-DGENERIC -DSOC_A -DFEATURE".
 func soongConfigModuleTypeFactory() Module {
@@ -349,7 +362,12 @@
 
 			AddLoadHook(module, func(ctx LoadHookContext) {
 				config := ctx.Config().VendorConfig(moduleType.ConfigNamespace)
-				for _, ps := range soongconfig.PropertiesToApply(moduleType, conditionalProps, config) {
+				newProps, err := soongconfig.PropertiesToApply(moduleType, conditionalProps, config)
+				if err != nil {
+					ctx.ModuleErrorf("%s", err)
+					return
+				}
+				for _, ps := range newProps {
 					ctx.AppendProperties(ps)
 				}
 			})
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index 1cf060d..f905b1a 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -45,6 +45,7 @@
 			config_namespace: "acme",
 			variables: ["board", "feature1", "FEATURE3"],
 			bool_variables: ["feature2"],
+			value_variables: ["size"],
 			properties: ["cflags", "srcs"],
 		}
 
@@ -82,6 +83,9 @@
 						cflags: ["-DSOC_B"],
 					},
 				},
+				size: {
+					cflags: ["-DSIZE=%s"],
+				},
 				feature1: {
 					cflags: ["-DFEATURE1"],
 				},
@@ -101,6 +105,7 @@
 		config.TestProductVariables.VendorVars = map[string]map[string]string{
 			"acme": map[string]string{
 				"board":    "soc_a",
+				"size":     "42",
 				"feature1": "true",
 				"feature2": "false",
 				// FEATURE3 unset
@@ -121,7 +126,7 @@
 		FailIfErrored(t, errs)
 
 		foo := ctx.ModuleForTests("foo", "").Module().(*soongConfigTestModule)
-		if g, w := foo.props.Cflags, []string{"-DGENERIC", "-DSOC_A", "-DFEATURE1"}; !reflect.DeepEqual(g, w) {
+		if g, w := foo.props.Cflags, []string{"-DGENERIC", "-DSIZE=42", "-DSOC_A", "-DFEATURE1"}; !reflect.DeepEqual(g, w) {
 			t.Errorf("wanted foo cflags %q, got %q", w, g)
 		}
 	}
diff --git a/android/soongconfig/modules.go b/android/soongconfig/modules.go
index 2d6063d..142a813 100644
--- a/android/soongconfig/modules.go
+++ b/android/soongconfig/modules.go
@@ -112,6 +112,10 @@
 	// the list of boolean SOONG_CONFIG variables that this module type will read
 	Bool_variables []string
 
+	// the list of SOONG_CONFIG variables that this module type will read. The value will be
+	// inserted into the properties with %s substitution.
+	Value_variables []string
+
 	// the list of properties that this module type will extend.
 	Properties []string
 }
@@ -161,6 +165,18 @@
 		})
 	}
 
+	for _, name := range props.Value_variables {
+		if name == "" {
+			return []error{fmt.Errorf("value_variables entry must not be blank")}
+		}
+
+		mt.Variables = append(mt.Variables, &valueVariable{
+			baseVariable: baseVariable{
+				variable: name,
+			},
+		})
+	}
+
 	return nil
 }
 
@@ -404,15 +420,17 @@
 
 // PropertiesToApply returns the applicable properties from a ModuleType that should be applied
 // based on SoongConfig values.
-func PropertiesToApply(moduleType *ModuleType, props reflect.Value, config SoongConfig) []interface{} {
+func PropertiesToApply(moduleType *ModuleType, props reflect.Value, config SoongConfig) ([]interface{}, error) {
 	var ret []interface{}
 	props = props.Elem().FieldByName(soongConfigProperty)
 	for i, c := range moduleType.Variables {
-		if ps := c.PropertiesToApply(config, props.Field(i)); ps != nil {
+		if ps, err := c.PropertiesToApply(config, props.Field(i)); err != nil {
+			return nil, err
+		} else if ps != nil {
 			ret = append(ret, ps)
 		}
 	}
-	return ret
+	return ret, nil
 }
 
 type ModuleType struct {
@@ -438,7 +456,7 @@
 
 	// PropertiesToApply should return one of the interface{} values set by initializeProperties to be applied
 	// to the module.
-	PropertiesToApply(config SoongConfig, values reflect.Value) interface{}
+	PropertiesToApply(config SoongConfig, values reflect.Value) (interface{}, error)
 }
 
 type baseVariable struct {
@@ -473,14 +491,14 @@
 	}
 }
 
-func (s *stringVariable) PropertiesToApply(config SoongConfig, values reflect.Value) interface{} {
+func (s *stringVariable) PropertiesToApply(config SoongConfig, values reflect.Value) (interface{}, error) {
 	for j, v := range s.values {
 		if config.String(s.variable) == v {
-			return values.Field(j).Interface()
+			return values.Field(j).Interface(), nil
 		}
 	}
 
-	return nil
+	return nil, nil
 }
 
 type boolVariable struct {
@@ -495,11 +513,83 @@
 	v.Set(reflect.Zero(typ))
 }
 
-func (b boolVariable) PropertiesToApply(config SoongConfig, values reflect.Value) interface{} {
+func (b boolVariable) PropertiesToApply(config SoongConfig, values reflect.Value) (interface{}, error) {
 	if config.Bool(b.variable) {
-		return values.Interface()
+		return values.Interface(), nil
 	}
 
+	return nil, nil
+}
+
+type valueVariable struct {
+	baseVariable
+}
+
+func (s *valueVariable) variableValuesType() reflect.Type {
+	return emptyInterfaceType
+}
+
+func (s *valueVariable) initializeProperties(v reflect.Value, typ reflect.Type) {
+	v.Set(reflect.Zero(typ))
+}
+
+func (s *valueVariable) PropertiesToApply(config SoongConfig, values reflect.Value) (interface{}, error) {
+	if !config.IsSet(s.variable) {
+		return nil, nil
+	}
+	configValue := config.String(s.variable)
+
+	propStruct := values.Elem().Elem()
+	for i := 0; i < propStruct.NumField(); i++ {
+		field := propStruct.Field(i)
+		kind := field.Kind()
+		if kind == reflect.Ptr {
+			if field.IsNil() {
+				continue
+			}
+			field = field.Elem()
+		}
+		switch kind {
+		case reflect.String:
+			err := printfIntoProperty(field, configValue)
+			if err != nil {
+				return nil, fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, propStruct.Type().Field(i).Name, err)
+			}
+		case reflect.Slice:
+			for j := 0; j < field.Len(); j++ {
+				err := printfIntoProperty(field.Index(j), configValue)
+				if err != nil {
+					return nil, fmt.Errorf("soong_config_variables.%s.%s: %s", s.variable, propStruct.Type().Field(i).Name, err)
+				}
+			}
+		case reflect.Bool:
+			// Nothing to do
+		default:
+			return nil, fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, propStruct.Type().Field(i).Name, kind)
+		}
+	}
+
+	return values.Interface(), nil
+}
+
+func printfIntoProperty(propertyValue reflect.Value, configValue string) error {
+	s := propertyValue.String()
+
+	count := strings.Count(s, "%")
+	if count == 0 {
+		return nil
+	}
+
+	if count > 1 {
+		return fmt.Errorf("value variable properties only support a single '%%'")
+	}
+
+	if !strings.Contains(s, "%s") {
+		return fmt.Errorf("unsupported %% in value variable property")
+	}
+
+	propertyValue.Set(reflect.ValueOf(fmt.Sprintf(s, configValue)))
+
 	return nil
 }
 
diff --git a/apex/apex.go b/apex/apex.go
index 3f790dc..f394068 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -74,27 +74,9 @@
 	// Module separator
 	//
 	m["com.android.adbd"] = []string{
-		"adbd",
-		"bcm_object",
-		"fmtlib",
-		"libadbconnection_server",
-		"libadbd",
 		"libadbd_auth",
-		"libadbd_core",
-		"libadbd_services",
-		"libasyncio",
-		"libbacktrace_headers",
-		"libbase",
-		"libbase_headers",
 		"libbuildversion",
-		"libc++",
 		"libcap",
-		"libcrypto",
-		"libcrypto_utils",
-		"libcutils",
-		"libcutils_headers",
-		"libdiagnose_usb",
-		"liblog_headers",
 		"libmdnssd",
 		"libminijail",
 		"libminijail_gen_constants",
@@ -105,9 +87,6 @@
 		"libpackagelistparser",
 		"libpcre2",
 		"libprocessgroup_headers",
-		"libqemu_pipe",
-		"libsystem_headers",
-		"libutils_headers",
 	}
 	//
 	// Module separator
@@ -116,7 +95,6 @@
 		"art_cmdlineparser_headers",
 		"art_disassembler_headers",
 		"art_libartbase_headers",
-		"bcm_object",
 		"bionic_libc_platform_headers",
 		"core-repackaged-icu4j",
 		"cpp-define-generator-asm-support",
@@ -128,9 +106,7 @@
 		"conscrypt.module.intra.core.api.stubs",
 		"dex2oat_headers",
 		"dt_fd_forward_export",
-		"fmtlib",
 		"icu4c_extra_headers",
-		"jacocoagent",
 		"javavm_headers",
 		"jni_platform_headers",
 		"libPlatformProperties",
@@ -140,15 +116,6 @@
 		"libart_runtime_headers_ndk",
 		"libartd-disassembler",
 		"libasync_safe",
-		"libbacktrace",
-		"libbase",
-		"libbase_headers",
-		"libc++",
-		"libc++_static",
-		"libc++abi",
-		"libc++demangle",
-		"libc_headers",
-		"libcrypto",
 		"libdexfile_all_headers",
 		"libdexfile_external_headers",
 		"libdexfile_support",
@@ -161,7 +128,6 @@
 		"libicuuc_headers",
 		"libicuuc_stubdata",
 		"libjdwp_headers",
-		"liblog_headers",
 		"liblz4",
 		"liblzma",
 		"libmeminfo",
@@ -172,7 +138,6 @@
 		"libopenjdkjvmti_headers",
 		"libperfetto_client_experimental",
 		"libprocinfo",
-		"libprotobuf-cpp-lite",
 		"libunwind_llvm",
 		"libunwindstack",
 		"libv8",
@@ -207,13 +172,10 @@
 		"android.hidl.token@1.0-utils",
 		"avrcp-target-service",
 		"avrcp_headers",
-		"bcm_object",
 		"bluetooth-protos-lite",
 		"bluetooth.mapsapi",
 		"com.android.vcard",
 		"dnsresolver_aidl_interface-V2-java",
-		"fmtlib",
-		"guava",
 		"ipmemorystore-aidl-interfaces-V5-java",
 		"ipmemorystore-aidl-interfaces-java",
 		"internal_include_headers",
@@ -223,9 +185,6 @@
 		"libFraunhoferAAC",
 		"libaudio-a2dp-hw-utils",
 		"libaudio-hearing-aid-hw-utils",
-		"libbacktrace_headers",
-		"libbase",
-		"libbase_headers",
 		"libbinder_headers",
 		"libbluetooth",
 		"libbluetooth-types",
@@ -247,38 +206,23 @@
 		"libbtdevice",
 		"libbte",
 		"libbtif",
-		"libc++",
 		"libchrome",
-		"libcrypto",
-		"libcutils",
-		"libcutils_headers",
 		"libevent",
 		"libfmq",
 		"libg722codec",
 		"libgtest_prod",
 		"libgui_headers",
-		"libhidlbase",
-		"libhidlbase-impl-internal",
-		"libhidltransport-impl-internal",
-		"libhwbinder-impl-internal",
-		"libjsoncpp",
-		"liblog_headers",
 		"libmedia_headers",
 		"libmodpb64",
 		"libosi",
 		"libprocessgroup",
 		"libprocessgroup_headers",
-		"libprotobuf-cpp-lite",
-		"libprotobuf-java-lite",
-		"libprotobuf-java-micro",
 		"libstagefright_foundation_headers",
 		"libstagefright_headers",
 		"libstatslog",
 		"libstatssocket",
-		"libsystem_headers",
 		"libtinyxml2",
 		"libudrv-uipc",
-		"libutils_headers",
 		"libz",
 		"media_plugin_headers",
 		"net-utils-services-common",
@@ -298,12 +242,8 @@
 	// Module separator
 	//
 	m["com.android.conscrypt"] = []string{
-		"bcm_object",
 		"boringssl_self_test",
-		"libc++",
-		"libcrypto",
 		"libnativehelper_header_only",
-		"libssl",
 		"unsupportedappusage",
 	}
 	//
@@ -343,44 +283,13 @@
 		"android.hidl.memory.token@1.0",
 		"android.hidl.memory@1.0",
 		"android.hidl.safe_union@1.0",
-		"bcm_object",
-		"fmtlib",
-		"gemmlowp_headers",
 		"libarect",
-		"libbacktrace_headers",
-		"libbase",
-		"libbase_headers",
 		"libbuildversion",
-		"libc++",
-		"libcrypto",
-		"libcrypto_static",
-		"libcutils",
-		"libcutils_headers",
-		"libeigen",
-		"libfmq",
-		"libhidlbase",
-		"libhidlbase-impl-internal",
-		"libhidlmemory",
-		"libhidltransport-impl-internal",
-		"libhwbinder-impl-internal",
-		"libjsoncpp",
-		"liblog_headers",
 		"libmath",
-		"libneuralnetworks_common",
-		"libneuralnetworks_headers",
 		"libprocessgroup",
 		"libprocessgroup_headers",
 		"libprocpartition",
 		"libsync",
-		"libsystem_headers",
-		"libtextclassifier_hash",
-		"libtextclassifier_hash_headers",
-		"libtextclassifier_hash_static",
-		"libtflite_kernel_utils",
-		"libutils_headers",
-		"philox_random",
-		"philox_random_headers",
-		"tensorflow_headers",
 	}
 	//
 	// Module separator
@@ -409,9 +318,7 @@
 		"android.hidl.memory@1.0",
 		"android.hidl.token@1.0",
 		"android.hidl.token@1.0-utils",
-		"bcm_object",
 		"bionic_libc_platform_headers",
-		"fmtlib",
 		"gl_headers",
 		"libEGL",
 		"libEGL_blobCache",
@@ -433,23 +340,14 @@
 		"libaudiopolicy",
 		"libaudioutils",
 		"libaudioutils_fixedfft",
-		"libbacktrace",
-		"libbacktrace_headers",
-		"libbase",
-		"libbase_headers",
 		"libbinder_headers",
 		"libbluetooth-types-header",
 		"libbufferhub",
 		"libbufferhub_headers",
 		"libbufferhubqueue",
-		"libc++",
-		"libc_headers",
 		"libc_malloc_debug_backtrace",
 		"libcamera_client",
 		"libcamera_metadata",
-		"libcrypto",
-		"libcutils",
-		"libcutils_headers",
 		"libdexfile_external_headers",
 		"libdexfile_support",
 		"libdvr_headers",
@@ -461,14 +359,7 @@
 		"libgui",
 		"libgui_headers",
 		"libhardware_headers",
-		"libhidlbase",
-		"libhidlbase-impl-internal",
-		"libhidlmemory",
-		"libhidltransport-impl-internal",
-		"libhwbinder-impl-internal",
 		"libinput",
-		"libjsoncpp",
-		"liblog_headers",
 		"liblzma",
 		"libmath",
 		"libmedia",
@@ -516,11 +407,9 @@
 		"libstagefright_mpeg2extractor",
 		"libstagefright_mpeg2support",
 		"libsync",
-		"libsystem_headers",
 		"libui",
 		"libui_headers",
 		"libunwindstack",
-		"libutils_headers",
 		"libvibrator",
 		"libvorbisidec",
 		"libwavextractor",
@@ -562,7 +451,6 @@
 		"android.hidl.safe_union@1.0",
 		"android.hidl.token@1.0",
 		"android.hidl.token@1.0-utils",
-		"fmtlib",
 		"libEGL",
 		"libFLAC",
 		"libFLAC-config",
@@ -579,15 +467,10 @@
 		"libavcenc",
 		"libavservices_minijail",
 		"libavservices_minijail",
-		"libbacktrace",
-		"libbacktrace_headers",
-		"libbase",
-		"libbase_headers",
 		"libbinder_headers",
 		"libbinderthreadstateutils",
 		"libbluetooth-types-header",
 		"libbufferhub_headers",
-		"libc++",
 		"libc_scudo",
 		"libcap",
 		"libcodec2",
@@ -627,8 +510,6 @@
 		"libcodec2_soft_vp9dec",
 		"libcodec2_soft_vp9enc",
 		"libcodec2_vndk",
-		"libcutils",
-		"libcutils_headers",
 		"libdexfile_support",
 		"libdvr_headers",
 		"libfmq",
@@ -644,15 +525,8 @@
 		"libhardware_headers",
 		"libhevcdec",
 		"libhevcenc",
-		"libhidlbase",
-		"libhidlbase-impl-internal",
-		"libhidlmemory",
-		"libhidltransport-impl-internal",
-		"libhwbinder-impl-internal",
 		"libion",
 		"libjpeg",
-		"libjsoncpp",
-		"liblog_headers",
 		"liblzma",
 		"libmath",
 		"libmedia_codecserviceregistrant",
@@ -691,11 +565,9 @@
 		"libstagefright_m4vh263enc",
 		"libstagefright_mp3dec",
 		"libsync",
-		"libsystem_headers",
 		"libui",
 		"libui_headers",
 		"libunwindstack",
-		"libutils_headers",
 		"libvorbisidec",
 		"libvpx",
 		"libyuv",
@@ -711,7 +583,6 @@
 		"MediaProvider",
 		"MediaProviderGoogle",
 		"fmtlib_ndk",
-		"guava",
 		"libbase_ndk",
 		"libfuse",
 		"libfuse_jni",
@@ -735,7 +606,6 @@
 		"kotlinx-coroutines-android-nodeps",
 		"kotlinx-coroutines-core",
 		"kotlinx-coroutines-core-nodeps",
-		"libprotobuf-java-lite",
 		"permissioncontroller-statsd",
 		"GooglePermissionController",
 		"PermissionController",
@@ -745,14 +615,9 @@
 	//
 	m["com.android.runtime"] = []string{
 		"bionic_libc_platform_headers",
-		"fmtlib",
 		"libarm-optimized-routines-math",
 		"libasync_safe",
 		"libasync_safe_headers",
-		"libbacktrace_headers",
-		"libbase",
-		"libbase_headers",
-		"libc++",
 		"libc_aeabi",
 		"libc_bionic",
 		"libc_bionic_ndk",
@@ -766,7 +631,6 @@
 		"libc_freebsd",
 		"libc_freebsd_large_stack",
 		"libc_gdtoa",
-		"libc_headers",
 		"libc_init_dynamic",
 		"libc_init_static",
 		"libc_jemalloc_wrapper",
@@ -781,8 +645,6 @@
 		"libc_syscalls",
 		"libc_tzcode",
 		"libc_unwind_static",
-		"libcutils",
-		"libcutils_headers",
 		"libdebuggerd",
 		"libdebuggerd_common_headers",
 		"libdebuggerd_handler_core",
@@ -795,7 +657,6 @@
 		"libjemalloc5",
 		"liblinker_main",
 		"liblinker_malloc",
-		"liblog_headers",
 		"liblz4",
 		"liblzma",
 		"libprocessgroup_headers",
@@ -803,11 +664,9 @@
 		"libpropertyinfoparser",
 		"libscudo",
 		"libstdc++",
-		"libsystem_headers",
 		"libsystemproperties",
 		"libtombstoned_client_static",
 		"libunwindstack",
-		"libutils_headers",
 		"libz",
 		"libziparchive",
 	}
@@ -815,34 +674,19 @@
 	// Module separator
 	//
 	m["com.android.resolv"] = []string{
-		"bcm_object",
 		"dnsresolver_aidl_interface-unstable-ndk_platform",
-		"fmtlib",
-		"libbacktrace_headers",
-		"libbase",
-		"libbase_headers",
-		"libc++",
-		"libcrypto",
-		"libcutils",
-		"libcutils_headers",
 		"libgtest_prod",
-		"libjsoncpp",
-		"liblog_headers",
 		"libnativehelper_header_only",
 		"libnetd_client_headers",
 		"libnetd_resolv",
 		"libnetdutils",
 		"libprocessgroup",
 		"libprocessgroup_headers",
-		"libprotobuf-cpp-lite",
-		"libssl",
 		"libstatslog_resolv",
 		"libstatspush_compat",
 		"libstatssocket",
 		"libstatssocket_headers",
-		"libsystem_headers",
 		"libsysutils",
-		"libutils_headers",
 		"netd_event_listener_interface-ndk_platform",
 		"server_configurable_flags",
 		"stats_proto",
@@ -851,28 +695,13 @@
 	// Module separator
 	//
 	m["com.android.tethering"] = []string{
-		"libbase",
-		"libc++",
 		"libnativehelper_compat_libc++",
 		"android.hardware.tetheroffload.config@1.0",
-		"fmtlib",
-		"libbacktrace_headers",
-		"libbase_headers",
 		"libcgrouprc",
 		"libcgrouprc_format",
-		"libcutils",
-		"libcutils_headers",
-		"libhidlbase",
-		"libhidlbase-impl-internal",
-		"libhidltransport-impl-internal",
-		"libhwbinder-impl-internal",
-		"libjsoncpp",
-		"liblog_headers",
 		"libprocessgroup",
 		"libprocessgroup_headers",
-		"libsystem_headers",
 		"libtetherutilsjni",
-		"libutils_headers",
 		"libvndksupport",
 		"tethering-aidl-interfaces-java",
 	}
@@ -908,20 +737,9 @@
 		"ipmemorystore-aidl-interfaces-V3-java",
 		"ipmemorystore-aidl-interfaces-java",
 		"ksoap2",
-		"libbacktrace_headers",
-		"libbase",
-		"libbase_headers",
-		"libc++",
-		"libcutils",
-		"libcutils_headers",
-		"liblog_headers",
 		"libnanohttpd",
 		"libprocessgroup",
 		"libprocessgroup_headers",
-		"libprotobuf-java-lite",
-		"libprotobuf-java-nano",
-		"libsystem_headers",
-		"libutils_headers",
 		"libwifi-jni",
 		"net-utils-services-common",
 		"netd_aidl_interface-V2-java",
@@ -949,34 +767,14 @@
 	// Module separator
 	//
 	m["com.android.os.statsd"] = []string{
-		"libbacktrace_headers",
-		"libbase_headers",
-		"libc++",
-		"libcutils",
-		"libcutils_headers",
-		"liblog_headers",
 		"libprocessgroup_headers",
 		"libstatssocket",
-		"libsystem_headers",
-		"libutils_headers",
 	}
 	//
 	// Module separator
 	//
 	m["//any"] = []string{
-		"crtbegin_dynamic",
-		"crtbegin_dynamic1",
-		"crtbegin_so",
-		"crtbegin_so1",
-		"crtbegin_static",
-		"crtbrand",
-		"crtend_android",
-		"crtend_so",
 		"libatomic",
-		"libc++_static",
-		"libc++abi",
-		"libc++demangle",
-		"libc_headers",
 		"libclang_rt",
 		"libgcc_stripped",
 		"libprofile-clang-extras",
@@ -984,22 +782,6 @@
 		"libprofile-extras",
 		"libprofile-extras_ndk",
 		"libunwind_llvm",
-		"ndk_crtbegin_dynamic.27",
-		"ndk_crtbegin_so.16",
-		"ndk_crtbegin_so.19",
-		"ndk_crtbegin_so.21",
-		"ndk_crtbegin_so.24",
-		"ndk_crtbegin_so.27",
-		"ndk_crtend_android.27",
-		"ndk_crtend_so.16",
-		"ndk_crtend_so.19",
-		"ndk_crtend_so.21",
-		"ndk_crtend_so.24",
-		"ndk_crtend_so.27",
-		"ndk_libandroid_support",
-		"ndk_libc++_static",
-		"ndk_libc++abi",
-		"ndk_libunwind",
 	}
 	return m
 }
@@ -2014,6 +1796,13 @@
 		return
 	}
 
+	// Coverage build adds additional dependencies for the coverage-only runtime libraries.
+	// Requiring them and their transitive depencies with apex_available is not right
+	// because they just add noise.
+	if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
+		return
+	}
+
 	a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
 		apexName := ctx.ModuleName()
 		fromName := ctx.OtherModuleName(from)
diff --git a/apex/vndk.go b/apex/vndk.go
index 2a0d5b0..f948d76 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -16,6 +16,7 @@
 
 import (
 	"path/filepath"
+	"strconv"
 	"strings"
 	"sync"
 
@@ -121,10 +122,13 @@
 	// When all hard-coded references are fixed, remove symbolic links
 	// Note that  we should keep following symlinks for older VNDKs (<=29)
 	// Since prebuilt vndk libs still depend on system/lib/vndk path
-	if strings.HasPrefix(name, vndkApexName) {
-		vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
-		if strings.HasPrefix(name, vndkApexNamePrefix) {
-			vndkVersion = strings.TrimPrefix(name, vndkApexNamePrefix)
+	if strings.HasPrefix(name, vndkApexNamePrefix) {
+		vndkVersion := strings.TrimPrefix(name, vndkApexNamePrefix)
+		if numVer, err := strconv.Atoi(vndkVersion); err != nil {
+			ctx.ModuleErrorf("apex_vndk should be named as %v<ver:number>: %s", vndkApexNamePrefix, name)
+			return
+		} else if numVer > android.SdkVersion_Android10 {
+			return
 		}
 		// the name of vndk apex is formatted "com.android.vndk.v" + version
 		apexName := vndkApexNamePrefix + vndkVersion
diff --git a/cc/androidmk.go b/cc/androidmk.go
index ef695b0..1c90aaf 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -248,6 +248,10 @@
 			entries.SubName = "." + library.stubsVersion()
 		}
 		entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+			// Note library.skipInstall() has a special case to get here for static
+			// libraries that otherwise would have skipped installation and hence not
+			// have executed AndroidMkEntries at all. The reason is to ensure they get
+			// a NOTICE file make target which other libraries might depend on.
 			entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
 			if library.buildStubs() {
 				entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
diff --git a/cc/cc.go b/cc/cc.go
index c7639bf..be6ab4d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -377,6 +377,7 @@
 	inSanitizerDir() bool
 	hostToolPath() android.OptionalPath
 	relativeInstallPath() string
+	skipInstall(mod *Module)
 }
 
 type xref interface {
@@ -2587,6 +2588,14 @@
 	return c.InRecovery()
 }
 
+func (c *Module) SkipInstall() {
+	if c.installer == nil {
+		c.ModuleBase.SkipInstall()
+		return
+	}
+	c.installer.skipInstall(c)
+}
+
 func (c *Module) HostToolPath() android.OptionalPath {
 	if c.installer == nil {
 		return android.OptionalPath{}
diff --git a/cc/config/global.go b/cc/config/global.go
index 29020ab..5611a96 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -127,8 +127,8 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r377782c"
-	ClangDefaultShortVersion = "10.0.5"
+	ClangDefaultVersion      = "clang-r377782d"
+	ClangDefaultShortVersion = "10.0.6"
 
 	// Directories with warnings from Android.bp files.
 	WarningAllowedProjects = []string{
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index 43e8c85..cd0a508 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -58,8 +58,11 @@
 		"-Wl,--dynamicbase",
 		"-Wl,--nxcompat",
 	}
+	windowsLldflags = []string{
+		"-Wl,--Xlink=-Brepro", // Enable deterministic build
+	}
 	windowsClangLdflags  = append(ClangFilterUnknownCflags(windowsLdflags), []string{}...)
-	windowsClangLldflags = ClangFilterUnknownLldflags(windowsClangLdflags)
+	windowsClangLldflags = append(ClangFilterUnknownLldflags(windowsClangLdflags), windowsLldflags...)
 
 	windowsX86Cflags = []string{
 		"-m32",
diff --git a/cc/installer.go b/cc/installer.go
index 2f55ac5..13a4119 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -101,3 +101,7 @@
 func (installer *baseInstaller) relativeInstallPath() string {
 	return String(installer.Properties.Relative_install_path)
 }
+
+func (installer *baseInstaller) skipInstall(mod *Module) {
+	mod.ModuleBase.SkipInstall()
+}
diff --git a/cc/library.go b/cc/library.go
index 46cccb0..3bed8a0 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1303,6 +1303,18 @@
 	return android.CheckAvailableForApex(what, list)
 }
 
+func (library *libraryDecorator) skipInstall(mod *Module) {
+	if library.static() && library.buildStatic() && !library.buildStubs() {
+		// If we're asked to skip installation of a static library (in particular
+		// when it's not //apex_available:platform) we still want an AndroidMk entry
+		// for it to ensure we get the relevant NOTICE file targets (cf.
+		// notice_files.mk) that other libraries might depend on. AndroidMkEntries
+		// always sets LOCAL_UNINSTALLABLE_MODULE for these entries.
+		return
+	}
+	mod.ModuleBase.SkipInstall()
+}
+
 var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList")
 
 func versioningMacroNamesList(config android.Config) *map[string]string {
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index e849aee..3a630d2 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -90,6 +90,11 @@
 	return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
 }
 
+func (*ndkPrebuiltObjectLinker) availableFor(what string) bool {
+	// ndk prebuilt objects are available to everywhere
+	return true
+}
+
 type ndkPrebuiltStlLinker struct {
 	*libraryDecorator
 }
@@ -103,6 +108,11 @@
 	return deps
 }
 
+func (*ndkPrebuiltStlLinker) availableFor(what string) bool {
+	// ndk prebuilt objects are available to everywhere
+	return true
+}
+
 // ndk_prebuilt_shared_stl exports a precompiled ndk shared standard template
 // library (stl) library for linking operation. The soong's module name format
 // is ndk_<NAME>.so where the library is located under
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index b0cf489..4f77d41 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -134,6 +134,10 @@
 	p.properties.Srcs = nil
 }
 
+func (p *prebuiltLibraryLinker) skipInstall(mod *Module) {
+	mod.ModuleBase.SkipInstall()
+}
+
 func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
 	module, library := NewLibrary(hod)
 	module.compiler = nil
@@ -142,6 +146,7 @@
 		libraryDecorator: library,
 	}
 	module.linker = prebuilt
+	module.installer = prebuilt
 
 	module.AddProperties(&prebuilt.properties)
 
diff --git a/cc/testing.go b/cc/testing.go
index e5be7da..ed1ab7d 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -227,6 +227,10 @@
 			stl: "none",
 			vendor_available: true,
 			recovery_available: true,
+			apex_available: [
+				"//apex_available:platform",
+				"//apex_available:anyapex",
+			],
 		}
 		cc_library {
 			name: "libc++",
@@ -254,6 +258,10 @@
 			host_supported: false,
 			vendor_available: true,
 			recovery_available: true,
+			apex_available: [
+				"//apex_available:platform",
+				"//apex_available:anyapex",
+			],
 		}
 		cc_library {
 			name: "libunwind_llvm",
@@ -265,8 +273,21 @@
 			recovery_available: true,
 		}
 
+		cc_defaults {
+			name: "crt_defaults",
+			recovery_available: true,
+			vendor_available: true,
+			native_bridge_supported: true,
+			stl: "none",
+			apex_available: [
+				"//apex_available:platform",
+				"//apex_available:anyapex",
+			],
+		}
+
 		cc_object {
 			name: "crtbegin_so",
+			defaults: ["crt_defaults"],
 			recovery_available: true,
 			vendor_available: true,
 			native_bridge_supported: true,
@@ -275,6 +296,7 @@
 
 		cc_object {
 			name: "crtbegin_dynamic",
+			defaults: ["crt_defaults"],
 			recovery_available: true,
 			vendor_available: true,
 			native_bridge_supported: true,
@@ -283,6 +305,7 @@
 
 		cc_object {
 			name: "crtbegin_static",
+			defaults: ["crt_defaults"],
 			recovery_available: true,
 			vendor_available: true,
 			native_bridge_supported: true,
@@ -291,6 +314,7 @@
 
 		cc_object {
 			name: "crtend_so",
+			defaults: ["crt_defaults"],
 			recovery_available: true,
 			vendor_available: true,
 			native_bridge_supported: true,
@@ -299,6 +323,7 @@
 
 		cc_object {
 			name: "crtend_android",
+			defaults: ["crt_defaults"],
 			recovery_available: true,
 			vendor_available: true,
 			native_bridge_supported: true,
diff --git a/cc/vndk.go b/cc/vndk.go
index 29af9a7..8eab8ba 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -309,6 +309,10 @@
 		panic(err)
 	}
 
+	if m.HasStubsVariants() {
+		mctx.PropertyErrorf("vndk.enabled", "This library provides stubs. Shouldn't be VNDK. Consider making it as LLNDK")
+	}
+
 	vndkLibrariesLock.Lock()
 	defer vndkLibrariesLock.Unlock()
 
diff --git a/java/androidmk.go b/java/androidmk.go
index 136bb36..d8a3884 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -472,34 +472,6 @@
 				if ddoc.Javadoc.stubsSrcJar != nil {
 					entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", ddoc.Javadoc.stubsSrcJar)
 				}
-				apiFilePrefix := "INTERNAL_PLATFORM_"
-				if String(ddoc.properties.Api_tag_name) != "" {
-					apiFilePrefix += String(ddoc.properties.Api_tag_name) + "_"
-				}
-				if ddoc.apiFile != nil {
-					entries.SetPath(apiFilePrefix+"API_FILE", ddoc.apiFile)
-				}
-				if ddoc.dexApiFile != nil {
-					entries.SetPath(apiFilePrefix+"DEX_API_FILE", ddoc.dexApiFile)
-				}
-				if ddoc.privateApiFile != nil {
-					entries.SetPath(apiFilePrefix+"PRIVATE_API_FILE", ddoc.privateApiFile)
-				}
-				if ddoc.privateDexApiFile != nil {
-					entries.SetPath(apiFilePrefix+"PRIVATE_DEX_API_FILE", ddoc.privateDexApiFile)
-				}
-				if ddoc.removedApiFile != nil {
-					entries.SetPath(apiFilePrefix+"REMOVED_API_FILE", ddoc.removedApiFile)
-				}
-				if ddoc.removedDexApiFile != nil {
-					entries.SetPath(apiFilePrefix+"REMOVED_DEX_API_FILE", ddoc.removedDexApiFile)
-				}
-				if ddoc.exactApiFile != nil {
-					entries.SetPath(apiFilePrefix+"EXACT_API_FILE", ddoc.exactApiFile)
-				}
-				if ddoc.proguardFile != nil {
-					entries.SetPath(apiFilePrefix+"PROGUARD_FILE", ddoc.proguardFile)
-				}
 			},
 		},
 		ExtraFooters: []android.AndroidMkExtraFootersFunc{
@@ -567,35 +539,18 @@
 				if dstubs.metadataZip != nil {
 					entries.SetPath("LOCAL_DROIDDOC_METADATA_ZIP", dstubs.metadataZip)
 				}
-				apiFilePrefix := "INTERNAL_PLATFORM_"
-				if String(dstubs.properties.Api_tag_name) != "" {
-					apiFilePrefix += String(dstubs.properties.Api_tag_name) + "_"
-				}
-				if dstubs.apiFile != nil {
-					entries.SetPath(apiFilePrefix+"API_FILE", dstubs.apiFile)
-				}
-				if dstubs.dexApiFile != nil {
-					entries.SetPath(apiFilePrefix+"DEX_API_FILE", dstubs.dexApiFile)
-				}
-				if dstubs.privateApiFile != nil {
-					entries.SetPath(apiFilePrefix+"PRIVATE_API_FILE", dstubs.privateApiFile)
-				}
-				if dstubs.privateDexApiFile != nil {
-					entries.SetPath(apiFilePrefix+"PRIVATE_DEX_API_FILE", dstubs.privateDexApiFile)
-				}
-				if dstubs.removedApiFile != nil {
-					entries.SetPath(apiFilePrefix+"REMOVED_API_FILE", dstubs.removedApiFile)
-				}
-				if dstubs.removedDexApiFile != nil {
-					entries.SetPath(apiFilePrefix+"REMOVED_DEX_API_FILE", dstubs.removedDexApiFile)
-				}
-				if dstubs.exactApiFile != nil {
-					entries.SetPath(apiFilePrefix+"EXACT_API_FILE", dstubs.exactApiFile)
-				}
 			},
 		},
 		ExtraFooters: []android.AndroidMkExtraFootersFunc{
 			func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
+				if dstubs.apiFile != nil {
+					fmt.Fprintf(w, ".PHONY: %s %s.txt\n", dstubs.Name(), dstubs.Name())
+					fmt.Fprintf(w, "%s %s.txt: %s\n", dstubs.Name(), dstubs.Name(), dstubs.apiFile)
+				}
+				if dstubs.removedApiFile != nil {
+					fmt.Fprintf(w, ".PHONY: %s %s.txt\n", dstubs.Name(), dstubs.Name())
+					fmt.Fprintf(w, "%s %s.txt: %s\n", dstubs.Name(), dstubs.Name(), dstubs.removedApiFile)
+				}
 				if dstubs.checkCurrentApiTimestamp != nil {
 					fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-current-api")
 					fmt.Fprintln(w, dstubs.Name()+"-check-current-api:",
@@ -622,14 +577,12 @@
 					fmt.Fprintln(w, dstubs.Name()+"-check-last-released-api:",
 						dstubs.checkLastReleasedApiTimestamp.String())
 
-					if dstubs.Name() != "android.car-system-stubs-docs" {
-						fmt.Fprintln(w, ".PHONY: checkapi")
-						fmt.Fprintln(w, "checkapi:",
-							dstubs.checkLastReleasedApiTimestamp.String())
+					fmt.Fprintln(w, ".PHONY: checkapi")
+					fmt.Fprintln(w, "checkapi:",
+						dstubs.checkLastReleasedApiTimestamp.String())
 
-						fmt.Fprintln(w, ".PHONY: droidcore")
-						fmt.Fprintln(w, "droidcore: checkapi")
-					}
+					fmt.Fprintln(w, ".PHONY: droidcore")
+					fmt.Fprintln(w, "droidcore: checkapi")
 				}
 				if dstubs.apiLintTimestamp != nil {
 					fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-api-lint")
diff --git a/java/app.go b/java/app.go
index c64f1f7..55a758f 100755
--- a/java/app.go
+++ b/java/app.go
@@ -110,6 +110,10 @@
 	PreventInstall    bool `blueprint:"mutated"`
 	HideFromMake      bool `blueprint:"mutated"`
 	IsCoverageVariant bool `blueprint:"mutated"`
+
+	// Whether this app is considered mainline updatable or not. When set to true, this will enforce
+	// additional rules for making sure that the APK is truly updatable. Default is false.
+	Updatable *bool
 }
 
 // android_app properties that can be overridden by override_android_app
@@ -242,11 +246,21 @@
 }
 
 func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	a.checkPlatformAPI(ctx)
-	a.checkSdkVersion(ctx)
+	a.checkAppSdkVersions(ctx)
 	a.generateAndroidBuildActions(ctx)
 }
 
+func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
+	if Bool(a.appProperties.Updatable) {
+		if !a.sdkVersion().stable() {
+			ctx.PropertyErrorf("sdk_version", "Updatable apps must use stable SDKs, found %v", a.sdkVersion())
+		}
+	}
+
+	a.checkPlatformAPI(ctx)
+	a.checkSdkVersions(ctx)
+}
+
 // Returns true if the native libraries should be stored in the APK uncompressed and the
 // extractNativeLibs application flag should be set to false in the manifest.
 func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool {
@@ -1345,6 +1359,12 @@
 	// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
 	// Defaults to sdk_version if not set.
 	Min_sdk_version *string
+
+	// list of android_library modules whose resources are extracted and linked against statically
+	Static_libs []string
+
+	// list of android_app modules whose resources are extracted and linked against
+	Resource_libs []string
 }
 
 func (r *RuntimeResourceOverlay) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -1357,6 +1377,9 @@
 	if cert != "" {
 		ctx.AddDependency(ctx.Module(), certificateTag, cert)
 	}
+
+	ctx.AddVariationDependencies(nil, staticLibTag, r.properties.Static_libs...)
+	ctx.AddVariationDependencies(nil, libTag, r.properties.Resource_libs...)
 }
 
 func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/java/app_test.go b/java/app_test.go
index 10503e7..4458d4e 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -264,6 +264,108 @@
 	`)
 }
 
+func TestUpdatableApps(t *testing.T) {
+	testCases := []struct {
+		name          string
+		bp            string
+		expectedError string
+	}{
+		{
+			name: "Stable public SDK",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "29",
+					updatable: true,
+				}`,
+		},
+		{
+			name: "Stable system SDK",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "system_29",
+					updatable: true,
+				}`,
+		},
+		{
+			name: "Current public SDK",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "current",
+					updatable: true,
+				}`,
+		},
+		{
+			name: "Current system SDK",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "system_current",
+					updatable: true,
+				}`,
+		},
+		{
+			name: "Current module SDK",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "module_current",
+					updatable: true,
+				}`,
+		},
+		{
+			name: "Current core SDK",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "core_current",
+					updatable: true,
+				}`,
+		},
+		{
+			name: "No Platform APIs",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					platform_apis: true,
+					updatable: true,
+				}`,
+			expectedError: "Updatable apps must use stable SDKs",
+		},
+		{
+			name: "No Core Platform APIs",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					sdk_version: "core_platform",
+					updatable: true,
+				}`,
+			expectedError: "Updatable apps must use stable SDKs",
+		},
+		{
+			name: "No unspecified APIs",
+			bp: `android_app {
+					name: "foo",
+					srcs: ["a.java"],
+					updatable: true,
+				}`,
+			expectedError: "Updatable apps must use stable SDK",
+		},
+	}
+
+	for _, test := range testCases {
+		t.Run(test.name, func(t *testing.T) {
+			if test.expectedError == "" {
+				testJava(t, test.bp)
+			} else {
+				testJavaError(t, test.expectedError, test.bp)
+			}
+		})
+	}
+}
+
 func TestResourceDirs(t *testing.T) {
 	testCases := []struct {
 		name      string
@@ -2342,11 +2444,17 @@
 }
 
 func TestRuntimeResourceOverlay(t *testing.T) {
-	ctx, config := testJava(t, `
+	fs := map[string][]byte{
+		"baz/res/res/values/strings.xml": nil,
+		"bar/res/res/values/strings.xml": nil,
+	}
+	bp := `
 		runtime_resource_overlay {
 			name: "foo",
 			certificate: "platform",
 			product_specific: true,
+			static_libs: ["bar"],
+			resource_libs: ["baz"],
 			aaptflags: ["--keep-raw-values"],
 		}
 
@@ -2356,7 +2464,21 @@
 			product_specific: true,
 			theme: "faza",
 		}
-		`)
+
+		android_library {
+			name: "bar",
+			resource_dirs: ["bar/res"],
+		}
+
+		android_app {
+			name: "baz",
+			sdk_version: "current",
+			resource_dirs: ["baz/res"],
+		}
+		`
+	config := testAppConfig(nil, bp, fs)
+	ctx := testContext()
+	run(t, ctx, config)
 
 	m := ctx.ModuleForTests("foo", "android_common")
 
@@ -2368,6 +2490,19 @@
 		t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags)
 	}
 
+	// Check overlay.list output for static_libs dependency.
+	overlayList := m.Output("aapt2/overlay.list").Inputs.Strings()
+	staticLibPackage := buildDir + "/.intermediates/bar/android_common/package-res.apk"
+	if !inList(staticLibPackage, overlayList) {
+		t.Errorf("Stactic lib res package %q missing in overlay list: %q", staticLibPackage, overlayList)
+	}
+
+	// Check AAPT2 link flags for resource_libs dependency.
+	resourceLibFlag := "-I " + buildDir + "/.intermediates/baz/android_common/package-res.apk"
+	if !strings.Contains(aapt2Flags, resourceLibFlag) {
+		t.Errorf("Resource lib flag %q missing in aapt2 link flags: %q", resourceLibFlag, aapt2Flags)
+	}
+
 	// Check cert signing flag.
 	signedApk := m.Output("signed/foo.apk")
 	signingFlag := signedApk.Args["certificates"]
diff --git a/java/builder.go b/java/builder.go
index f9b5367..f09cd98 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -146,7 +146,12 @@
 
 	jarjar = pctx.AndroidStaticRule("jarjar",
 		blueprint.RuleParams{
-			Command:     "${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.JarjarCmd} process $rulesFile $in $out",
+			Command: "${config.JavaCmd} ${config.JavaVmFlags}" +
+				// b/146418363 Enable Android specific jarjar transformer to drop compat annotations
+				// for newly repackaged classes. Dropping @UnsupportedAppUsage on repackaged classes
+				// avoids adding new hiddenapis after jarjar'ing.
+				" -DremoveAndroidCompatAnnotations=true" +
+				" -jar ${config.JarjarCmd} process $rulesFile $in $out",
 			CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
 		},
 		"rulesFile")
diff --git a/java/java.go b/java/java.go
index d67ff87..7956813 100644
--- a/java/java.go
+++ b/java/java.go
@@ -80,7 +80,7 @@
 	ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
 }
 
-func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
+func (j *Module) checkSdkVersions(ctx android.ModuleContext) {
 	if j.SocSpecific() || j.DeviceSpecific() ||
 		(j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
 		if sc, ok := ctx.Module().(sdkContext); ok {
@@ -90,6 +90,18 @@
 			}
 		}
 	}
+
+	ctx.VisitDirectDeps(func(module android.Module) {
+		tag := ctx.OtherModuleDependencyTag(module)
+		switch module.(type) {
+		// TODO(satayev): cover other types as well, e.g. imports
+		case *Library, *AndroidLibrary:
+			switch tag {
+			case bootClasspathTag, libTag, staticLibTag, java9LibTag:
+				checkLinkType(ctx, j, module.(linkTypeContext), tag.(dependencyTag))
+			}
+		}
+	})
 }
 
 func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
@@ -892,15 +904,7 @@
 			// Handled by AndroidApp.collectAppDeps
 			return
 		}
-		switch module.(type) {
-		case *Library, *AndroidLibrary:
-			if to, ok := module.(linkTypeContext); ok {
-				switch tag {
-				case bootClasspathTag, libTag, staticLibTag:
-					checkLinkType(ctx, j, to, tag.(dependencyTag))
-				}
-			}
-		}
+
 		switch dep := module.(type) {
 		case SdkLibraryDependency:
 			switch tag {
@@ -1817,7 +1821,7 @@
 }
 
 func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	j.checkSdkVersion(ctx)
+	j.checkSdkVersions(ctx)
 	j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
 	j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
 	j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
diff --git a/java/sdk.go b/java/sdk.go
index 4c9ba2b..be5e512 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -35,6 +35,7 @@
 
 var sdkVersionsKey = android.NewOnceKey("sdkVersionsKey")
 var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
+var nonUpdatableFrameworkAidlPathKey = android.NewOnceKey("nonUpdatableFrameworkAidlPathKey")
 var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")
 
 type sdkContext interface {
@@ -147,6 +148,10 @@
 	raw     string
 }
 
+func (s sdkSpec) String() string {
+	return fmt.Sprintf("%s_%s", s.kind, s.version)
+}
+
 // valid checks if this sdkSpec is well-formed. Note however that true doesn't mean that the
 // specified SDK actually exists.
 func (s sdkSpec) valid() bool {
@@ -158,6 +163,23 @@
 	return s.valid() && s.kind != sdkPrivate
 }
 
+// whether the API surface is managed and versioned, i.e. has .txt file that
+// get frozen on SDK freeze and changes get reviewed by API council.
+func (s sdkSpec) stable() bool {
+	if !s.specified() {
+		return false
+	}
+	switch s.kind {
+	case sdkCore, sdkPublic, sdkSystem, sdkModule, sdkSystemServer:
+		return true
+	case sdkNone, sdkCorePlatform, sdkTest, sdkPrivate:
+		return false
+	default:
+		panic(fmt.Errorf("unknown sdkKind=%v", s.kind))
+	}
+	return false
+}
+
 // prebuiltSdkAvailableForUnbundledBuilt tells whether this sdkSpec can have a prebuilt SDK
 // that can be used for unbundled builds.
 func (s sdkSpec) prebuiltSdkAvailableForUnbundledBuild() bool {
@@ -393,7 +415,7 @@
 		return toModule([]string{"core.current.stubs"}, "", nil)
 	case sdkModule:
 		// TODO(146757305): provide .apk and .aidl that have more APIs for modules
-		return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+		return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", nonUpdatableFrameworkAidlPath(ctx))
 	case sdkSystemServer:
 		// TODO(146757305): provide .apk and .aidl that have more APIs for modules
 		return toModule([]string{"android_system_server_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
@@ -452,6 +474,7 @@
 	}
 
 	createSdkFrameworkAidl(ctx)
+	createNonUpdatableFrameworkAidl(ctx)
 	createAPIFingerprint(ctx)
 }
 
@@ -463,6 +486,31 @@
 		"android_system_stubs_current",
 	}
 
+	combinedAidl := sdkFrameworkAidlPath(ctx)
+	tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
+
+	rule := createFrameworkAidl(stubsModules, tempPath, ctx)
+
+	commitChangeForRestat(rule, tempPath, combinedAidl)
+
+	rule.Build(pctx, ctx, "framework_aidl", "generate framework.aidl")
+}
+
+// Creates a version of framework.aidl for the non-updatable part of the platform.
+func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) {
+	stubsModules := []string{"android_module_lib_stubs_current"}
+
+	combinedAidl := nonUpdatableFrameworkAidlPath(ctx)
+	tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
+
+	rule := createFrameworkAidl(stubsModules, tempPath, ctx)
+
+	commitChangeForRestat(rule, tempPath, combinedAidl)
+
+	rule.Build(pctx, ctx, "framework_non_updatable_aidl", "generate framework_non_updatable.aidl")
+}
+
+func createFrameworkAidl(stubsModules []string, path android.OutputPath, ctx android.SingletonContext) *android.RuleBuilder {
 	stubsJars := make([]android.Paths, len(stubsModules))
 
 	ctx.VisitAllModules(func(module android.Module) {
@@ -482,8 +530,7 @@
 			if ctx.Config().AllowMissingDependencies() {
 				missingDeps = append(missingDeps, stubsModules[i])
 			} else {
-				ctx.Errorf("failed to find dex jar path for module %q",
-					stubsModules[i])
+				ctx.Errorf("failed to find dex jar path for module %q", stubsModules[i])
 			}
 		}
 	}
@@ -507,20 +554,15 @@
 		}
 	}
 
-	combinedAidl := sdkFrameworkAidlPath(ctx)
-	tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
-
 	rule.Command().
-		Text("rm -f").Output(tempPath)
+		Text("rm -f").Output(path)
 	rule.Command().
 		Text("cat").
 		Inputs(aidls).
 		Text("| sort -u >").
-		Output(tempPath)
+		Output(path)
 
-	commitChangeForRestat(rule, tempPath, combinedAidl)
-
-	rule.Build(pctx, ctx, "framework_aidl", "generate framework.aidl")
+	return rule
 }
 
 func sdkFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
@@ -529,6 +571,12 @@
 	}).(android.OutputPath)
 }
 
+func nonUpdatableFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
+	return ctx.Config().Once(nonUpdatableFrameworkAidlPathKey, func() interface{} {
+		return android.PathForOutput(ctx, "framework_non_updatable.aidl")
+	}).(android.OutputPath)
+}
+
 // Create api_fingerprint.txt
 func createAPIFingerprint(ctx android.SingletonContext) {
 	out := ApiFingerprintPath(ctx)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 52c9004..374a5e5 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -373,13 +373,6 @@
 	}
 }
 
-// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
-// api file for the current source
-// TODO: remove this when apicheck is done in soong
-func (module *SdkLibrary) apiTagName(apiScope *apiScope) string {
-	return strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1) + apiScope.apiFileMakeVariableSuffix
-}
-
 func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string {
 	return ":" + module.BaseModuleName() + ".api." + apiScope.name + ".latest"
 }
@@ -470,9 +463,6 @@
 		Libs                             []string
 		Arg_files                        []string
 		Args                             *string
-		Api_tag_name                     *string
-		Api_filename                     *string
-		Removed_api_filename             *string
 		Java_version                     *string
 		Merge_annotations_dirs           []string
 		Merge_inclusion_annotations_dirs []string
@@ -555,10 +545,6 @@
 	apiDir := module.getApiDir()
 	currentApiFileName = path.Join(apiDir, currentApiFileName)
 	removedApiFileName = path.Join(apiDir, removedApiFileName)
-	// TODO(jiyong): remove these three props
-	props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
-	props.Api_filename = proptools.StringPtr(currentApiFileName)
-	props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
 
 	// check against the not-yet-release API
 	props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 088db9e..8eb5ffb 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -217,7 +217,7 @@
 			bootclasspath:  []string{"android_module_lib_stubs_current", "core-lambda-stubs"},
 			system:         "core-current-stubs-system-modules",
 			java9classpath: []string{"android_module_lib_stubs_current"},
-			aidl:           "-p" + buildDir + "/framework.aidl",
+			aidl:           "-p" + buildDir + "/framework_non_updatable.aidl",
 		},
 		{
 			name:           "system_server_current",
diff --git a/python/androidmk.go b/python/androidmk.go
index 8e8e8ef..d293d52 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -100,5 +100,6 @@
 		fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
 		fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
 		fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(installer.androidMkSharedLibs, " "))
+		fmt.Fprintln(w, "LOCAL_CHECK_ELF_FILES := false")
 	})
 }