Merge "Add system server jars expressed in make in the system server classpath."
diff --git a/android/apex.go b/android/apex.go
index 17ec9b1..43a42df 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -19,6 +19,14 @@
 	"sync"
 )
 
+type ApexInfo struct {
+	// Name of the apex variant that this module is mutated into
+	ApexName string
+
+	// Whether this apex variant needs to target Android 10
+	LegacyAndroid10Support bool
+}
+
 // ApexModule is the interface that a module type is expected to implement if
 // the module has to be built differently depending on whether the module
 // is destined for an apex or not (installed to one of the regular partitions).
@@ -38,12 +46,12 @@
 	Module
 	apexModuleBase() *ApexModuleBase
 
-	// Marks that this module should be built for the APEXes of the specified names.
+	// Marks that this module should be built for the specified APEXes.
 	// Call this before apex.apexMutator is run.
-	BuildForApexes(apexNames []string)
+	BuildForApexes(apexes []ApexInfo)
 
-	// Returns the name of the APEXes that this modoule will be built for
-	ApexVariations() []string
+	// Returns the APEXes that this module will be built for
+	ApexVariations() []ApexInfo
 
 	// Returns the name of APEX that this module will be built for. Empty string
 	// is returned when 'IsForPlatform() == true'. Note that a module can be
@@ -72,10 +80,6 @@
 	// for an APEX marked via BuildForApexes().
 	CreateApexVariations(mctx BottomUpMutatorContext) []Module
 
-	// Sets the name of the apex variant of this module. Called inside
-	// CreateApexVariations.
-	setApexName(apexName string)
-
 	// Tests if this module is available for the specified APEX or ":platform"
 	AvailableFor(what string) bool
 
@@ -94,8 +98,7 @@
 	// Default is ["//apex_available:platform"].
 	Apex_available []string
 
-	// Name of the apex variant that this module is mutated into
-	ApexName string `blueprint:"mutated"`
+	Info ApexInfo `blueprint:"mutated"`
 }
 
 // Provides default implementation for the ApexModule interface. APEX-aware
@@ -106,37 +109,37 @@
 	canHaveApexVariants bool
 
 	apexVariationsLock sync.Mutex // protects apexVariations during parallel apexDepsMutator
-	apexVariations     []string
+	apexVariations     []ApexInfo
 }
 
 func (m *ApexModuleBase) apexModuleBase() *ApexModuleBase {
 	return m
 }
 
-func (m *ApexModuleBase) BuildForApexes(apexNames []string) {
+func (m *ApexModuleBase) BuildForApexes(apexes []ApexInfo) {
 	m.apexVariationsLock.Lock()
 	defer m.apexVariationsLock.Unlock()
-	for _, apexName := range apexNames {
-		if !InList(apexName, m.apexVariations) {
-			m.apexVariations = append(m.apexVariations, apexName)
+nextApex:
+	for _, apex := range apexes {
+		for _, v := range m.apexVariations {
+			if v.ApexName == apex.ApexName {
+				continue nextApex
+			}
 		}
+		m.apexVariations = append(m.apexVariations, apex)
 	}
 }
 
-func (m *ApexModuleBase) ApexVariations() []string {
+func (m *ApexModuleBase) ApexVariations() []ApexInfo {
 	return m.apexVariations
 }
 
 func (m *ApexModuleBase) ApexName() string {
-	return m.ApexProperties.ApexName
+	return m.ApexProperties.Info.ApexName
 }
 
 func (m *ApexModuleBase) IsForPlatform() bool {
-	return m.ApexProperties.ApexName == ""
-}
-
-func (m *ApexModuleBase) setApexName(apexName string) {
-	m.ApexProperties.ApexName = apexName
+	return m.ApexProperties.Info.ApexName == ""
 }
 
 func (m *ApexModuleBase) CanHaveApexVariants() bool {
@@ -185,25 +188,35 @@
 	}
 }
 
+type byApexName []ApexInfo
+
+func (a byApexName) Len() int           { return len(a) }
+func (a byApexName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byApexName) Less(i, j int) bool { return a[i].ApexName < a[j].ApexName }
+
 func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Module {
 	if len(m.apexVariations) > 0 {
 		m.checkApexAvailableProperty(mctx)
 
-		sort.Strings(m.apexVariations)
+		sort.Sort(byApexName(m.apexVariations))
 		variations := []string{}
 		variations = append(variations, "") // Original variation for platform
-		variations = append(variations, m.apexVariations...)
+		for _, apex := range m.apexVariations {
+			variations = append(variations, apex.ApexName)
+		}
 
 		defaultVariation := ""
 		mctx.SetDefaultDependencyVariation(&defaultVariation)
 
 		modules := mctx.CreateVariations(variations...)
-		for i, m := range modules {
+		for i, mod := range modules {
 			platformVariation := i == 0
-			if platformVariation && !mctx.Host() && !m.(ApexModule).AvailableFor(AvailableToPlatform) {
-				m.SkipInstall()
+			if platformVariation && !mctx.Host() && !mod.(ApexModule).AvailableFor(AvailableToPlatform) {
+				mod.SkipInstall()
 			}
-			m.(ApexModule).setApexName(variations[i])
+			if !platformVariation {
+				mod.(ApexModule).apexModuleBase().ApexProperties.Info = m.apexVariations[i-1]
+			}
 		}
 		return modules
 	}
@@ -230,16 +243,16 @@
 // depended on by the specified APEXes. Directly depending means that a module
 // is explicitly listed in the build definition of the APEX via properties like
 // native_shared_libs, java_libs, etc.
-func UpdateApexDependency(apexNames []string, moduleName string, directDep bool) {
+func UpdateApexDependency(apexes []ApexInfo, moduleName string, directDep bool) {
 	apexNamesMapMutex.Lock()
 	defer apexNamesMapMutex.Unlock()
-	for _, apexName := range apexNames {
+	for _, apex := range apexes {
 		apexesForModule, ok := apexNamesMap()[moduleName]
 		if !ok {
 			apexesForModule = make(map[string]bool)
 			apexNamesMap()[moduleName] = apexesForModule
 		}
-		apexesForModule[apexName] = apexesForModule[apexName] || directDep
+		apexesForModule[apex.ApexName] = apexesForModule[apex.ApexName] || directDep
 	}
 }
 
diff --git a/android/arch.go b/android/arch.go
index fb1accc..73a490d 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1521,12 +1521,7 @@
 
 // hasArmAbi returns true if arch has at least one arm ABI
 func hasArmAbi(arch Arch) bool {
-	for _, abi := range arch.Abi {
-		if strings.HasPrefix(abi, "arm") {
-			return true
-		}
-	}
-	return false
+	return PrefixInList(arch.Abi, "arm")
 }
 
 // hasArmArch returns true if targets has at least non-native_bridge arm Android arch
diff --git a/android/config.go b/android/config.go
index 9cf9662..1fe6f05 100644
--- a/android/config.go
+++ b/android/config.go
@@ -890,11 +890,7 @@
 func (c *config) EnforceRROExcludedOverlay(path string) bool {
 	excluded := c.productVariables.EnforceRROExcludedOverlays
 	if excluded != nil {
-		for _, exclude := range excluded {
-			if strings.HasPrefix(path, exclude) {
-				return true
-			}
-		}
+		return HasAnyPrefix(path, excluded)
 	}
 	return false
 }
@@ -1050,12 +1046,12 @@
 func (c *deviceConfig) CoverageEnabledForPath(path string) bool {
 	coverage := false
 	if c.config.productVariables.CoveragePaths != nil {
-		if InList("*", c.config.productVariables.CoveragePaths) || PrefixInList(path, c.config.productVariables.CoveragePaths) {
+		if InList("*", c.config.productVariables.CoveragePaths) || HasAnyPrefix(path, c.config.productVariables.CoveragePaths) {
 			coverage = true
 		}
 	}
 	if coverage && c.config.productVariables.CoverageExcludePaths != nil {
-		if PrefixInList(path, c.config.productVariables.CoverageExcludePaths) {
+		if HasAnyPrefix(path, c.config.productVariables.CoverageExcludePaths) {
 			coverage = false
 		}
 	}
@@ -1128,21 +1124,21 @@
 	if c.productVariables.IntegerOverflowExcludePaths == nil {
 		return false
 	}
-	return PrefixInList(path, c.productVariables.IntegerOverflowExcludePaths)
+	return HasAnyPrefix(path, c.productVariables.IntegerOverflowExcludePaths)
 }
 
 func (c *config) CFIDisabledForPath(path string) bool {
 	if c.productVariables.CFIExcludePaths == nil {
 		return false
 	}
-	return PrefixInList(path, c.productVariables.CFIExcludePaths)
+	return HasAnyPrefix(path, c.productVariables.CFIExcludePaths)
 }
 
 func (c *config) CFIEnabledForPath(path string) bool {
 	if c.productVariables.CFIIncludePaths == nil {
 		return false
 	}
-	return PrefixInList(path, c.productVariables.CFIIncludePaths)
+	return HasAnyPrefix(path, c.productVariables.CFIIncludePaths)
 }
 
 func (c *config) VendorConfig(name string) VendorConfig {
diff --git a/android/neverallow.go b/android/neverallow.go
index 48581df..0cb2029 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -407,8 +407,8 @@
 }
 
 func (r *rule) appliesToPath(dir string) bool {
-	includePath := len(r.paths) == 0 || hasAnyPrefix(dir, r.paths)
-	excludePath := hasAnyPrefix(dir, r.unlessPaths)
+	includePath := len(r.paths) == 0 || HasAnyPrefix(dir, r.paths)
+	excludePath := HasAnyPrefix(dir, r.unlessPaths)
 	return includePath && !excludePath
 }
 
@@ -474,15 +474,6 @@
 	return names
 }
 
-func hasAnyPrefix(s string, prefixes []string) bool {
-	for _, prefix := range prefixes {
-		if strings.HasPrefix(s, prefix) {
-			return true
-		}
-	}
-	return false
-}
-
 func hasAnyProperty(properties []interface{}, props []ruleProperty) bool {
 	for _, v := range props {
 		if hasProperty(properties, v) {
diff --git a/android/util.go b/android/util.go
index e985fc1..ade851e 100644
--- a/android/util.go
+++ b/android/util.go
@@ -122,7 +122,7 @@
 }
 
 // Returns true if the given string s is prefixed with any string in the given prefix list.
-func PrefixInList(s string, prefixList []string) bool {
+func HasAnyPrefix(s string, prefixList []string) bool {
 	for _, prefix := range prefixList {
 		if strings.HasPrefix(s, prefix) {
 			return true
@@ -132,7 +132,7 @@
 }
 
 // Returns true if any string in the given list has the given prefix.
-func PrefixedStringInList(list []string, prefix string) bool {
+func PrefixInList(list []string, prefix string) bool {
 	for _, s := range list {
 		if strings.HasPrefix(s, prefix) {
 			return true
diff --git a/android/util_test.go b/android/util_test.go
index 90fefee..1f9ca36 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -252,7 +252,7 @@
 
 	for _, testCase := range testcases {
 		t.Run(testCase.str, func(t *testing.T) {
-			out := PrefixInList(testCase.str, prefixes)
+			out := HasAnyPrefix(testCase.str, prefixes)
 			if out != testCase.expected {
 				t.Errorf("incorrect output:")
 				t.Errorf("       str: %#v", testCase.str)
diff --git a/apex/apex.go b/apex/apex.go
index 54a335a..002bf5b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1024,17 +1024,17 @@
 // Mark the direct and transitive dependencies of apex bundles so that they
 // can be built for the apex bundles.
 func apexDepsMutator(mctx android.TopDownMutatorContext) {
-	var apexBundleNames []string
+	var apexBundles []android.ApexInfo
 	var directDep bool
 	if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex {
-		apexBundleNames = []string{mctx.ModuleName()}
+		apexBundles = []android.ApexInfo{{mctx.ModuleName(), proptools.Bool(a.properties.Legacy_android10_support)}}
 		directDep = true
 	} else if am, ok := mctx.Module().(android.ApexModule); ok {
-		apexBundleNames = am.ApexVariations()
+		apexBundles = am.ApexVariations()
 		directDep = false
 	}
 
-	if len(apexBundleNames) == 0 {
+	if len(apexBundles) == 0 {
 		return
 	}
 
@@ -1042,8 +1042,8 @@
 		depName := mctx.OtherModuleName(child)
 		if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() &&
 			(directDep || am.DepIsInSameApex(mctx, child)) {
-			android.UpdateApexDependency(apexBundleNames, depName, directDep)
-			am.BuildForApexes(apexBundleNames)
+			android.UpdateApexDependency(apexBundles, depName, directDep)
+			am.BuildForApexes(apexBundles)
 		}
 	})
 }
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 0420586..5000c88 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3437,6 +3437,7 @@
 		apex {
 			name: "myapex",
 			key: "myapex.key",
+			native_shared_libs: ["mylib"],
 			legacy_android10_support: true,
 		}
 
@@ -3445,12 +3446,54 @@
 			public_key: "testkey.avbpubkey",
 			private_key: "testkey.pem",
 		}
-	`)
+
+		cc_library {
+			name: "mylib",
+			srcs: ["mylib.cpp"],
+			stl: "libc++",
+			system_shared_libs: [],
+			apex_available: [ "myapex" ],
+		}
+
+		cc_library {
+			name: "libc++",
+			srcs: ["mylib.cpp"],
+			stl: "none",
+			system_shared_libs: [],
+			apex_available: [ "myapex" ],
+		}
+
+		cc_library_static {
+			name: "libc++demangle",
+			srcs: ["mylib.cpp"],
+			stl: "none",
+			system_shared_libs: [],
+		}
+
+		cc_library_static {
+			name: "libunwind_llvm",
+			srcs: ["mylib.cpp"],
+			stl: "none",
+			system_shared_libs: [],
+		}
+	`, withUnbundledBuild)
 
 	module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
 	args := module.Rule("apexRule").Args
 	ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
 	ensureNotContains(t, args["opt_flags"], "--no_hashtree")
+
+	// The copies of the libraries in the apex should have one more dependency than
+	// the ones outside the apex, namely the unwinder. Ideally we should check
+	// the dependency names directly here but for some reason the names are blank in
+	// this test.
+	for _, lib := range []string{"libc++", "mylib"} {
+		apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_myapex").Rule("ld").Implicits
+		nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits
+		if len(apexImplicits) != len(nonApexImplicits)+1 {
+			t.Errorf("%q missing unwinder dep", lib)
+		}
+	}
 }
 
 func TestJavaSDKLibrary(t *testing.T) {
diff --git a/cc/builder.go b/cc/builder.go
index 3ecfe54..136263b 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -55,9 +55,9 @@
 		},
 		"ccCmd", "cFlags")
 
-	ccNoDeps = pctx.AndroidRemoteStaticRule("ccNoDeps", android.RemoteRuleSupports{Goma: true},
+	ccNoDeps = pctx.AndroidStaticRule("ccNoDeps",
 		blueprint.RuleParams{
-			Command:     "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -o $out $in",
+			Command:     "$relPwd $ccCmd -c $cFlags -o $out $in",
 			CommandDeps: []string{"$ccCmd"},
 		},
 		"ccCmd", "cFlags")
diff --git a/cc/cc.go b/cc/cc.go
index b70e55c..5af8459 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -95,6 +95,8 @@
 	HeaderLibs                                  []string
 	RuntimeLibs                                 []string
 
+	StaticUnwinderIfLegacy bool
+
 	ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
 
 	ObjFiles []string
@@ -385,6 +387,7 @@
 	lateSharedDepTag      = DependencyTag{Name: "late shared", Library: true, Shared: true}
 	staticExportDepTag    = DependencyTag{Name: "static", Library: true, ReexportFlags: true}
 	lateStaticDepTag      = DependencyTag{Name: "late static", Library: true}
+	staticUnwinderDepTag  = DependencyTag{Name: "static unwinder", Library: true}
 	wholeStaticDepTag     = DependencyTag{Name: "whole static", Library: true, ReexportFlags: true}
 	headerDepTag          = DependencyTag{Name: "header", Library: true}
 	headerExportDepTag    = DependencyTag{Name: "header", Library: true, ReexportFlags: true}
@@ -1788,6 +1791,12 @@
 		}, depTag, lib)
 	}
 
+	if deps.StaticUnwinderIfLegacy && ctx.Config().UnbundledBuild() {
+		actx.AddVariationDependencies([]blueprint.Variation{
+			{Mutator: "link", Variation: "static"},
+		}, staticUnwinderDepTag, staticUnwinder(actx))
+	}
+
 	for _, lib := range deps.LateStaticLibs {
 		actx.AddVariationDependencies([]blueprint.Variation{
 			{Mutator: "link", Variation: "static"},
@@ -2161,6 +2170,14 @@
 			}
 		}
 
+		if depTag == staticUnwinderDepTag {
+			if c.ApexProperties.Info.LegacyAndroid10Support {
+				depTag = StaticDepTag
+			} else {
+				return
+			}
+		}
+
 		// Extract ExplicitlyVersioned field from the depTag and reset it inside the struct.
 		// Otherwise, SharedDepTag and lateSharedDepTag with ExplicitlyVersioned set to true
 		// won't be matched to SharedDepTag and lateSharedDepTag.
diff --git a/cc/cflag_artifacts.go b/cc/cflag_artifacts.go
index b61f2a8..855ff25 100644
--- a/cc/cflag_artifacts.go
+++ b/cc/cflag_artifacts.go
@@ -41,12 +41,7 @@
 // filter.
 func allowedDir(subdir string) bool {
 	subdir += "/"
-	for _, prefix := range TrackedCFlagsDir {
-		if strings.HasPrefix(subdir, prefix) {
-			return true
-		}
-	}
-	return false
+	return android.HasAnyPrefix(subdir, TrackedCFlagsDir)
 }
 
 func (s *cflagArtifactsText) genFlagFilename(flag string) string {
diff --git a/cc/compiler.go b/cc/compiler.go
index 1ced451..c1a8d96 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -241,12 +241,7 @@
 // Return true if the module is in the WarningAllowedProjects.
 func warningsAreAllowed(subdir string) bool {
 	subdir += "/"
-	for _, prefix := range config.WarningAllowedProjects {
-		if strings.HasPrefix(subdir, prefix) {
-			return true
-		}
-	}
-	return false
+	return android.HasAnyPrefix(subdir, config.WarningAllowedProjects)
 }
 
 func addToModuleList(ctx ModuleContext, key android.OnceKey, module string) {
@@ -515,7 +510,7 @@
 
 	// Exclude directories from manual binder interface whitelisting.
 	//TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths.
-	if android.PrefixInList(ctx.ModuleDir(), allowedManualInterfacePaths) {
+	if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) {
 		flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
 	}
 
@@ -604,16 +599,12 @@
 func isThirdParty(path string) bool {
 	thirdPartyDirPrefixes := []string{"external/", "vendor/", "hardware/"}
 
-	for _, prefix := range thirdPartyDirPrefixes {
-		if strings.HasPrefix(path, prefix) {
-			for _, prefix := range thirdPartyDirPrefixExceptions {
-				if prefix.MatchString(path) {
-					return false
-				}
+	if android.HasAnyPrefix(path, thirdPartyDirPrefixes) {
+		for _, prefix := range thirdPartyDirPrefixExceptions {
+			if prefix.MatchString(path) {
+				return false
 			}
-			break
 		}
 	}
-
 	return true
 }
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 26a104b..0d03699 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -171,10 +171,8 @@
 		"-Wno-implicit-int-float-conversion",
 		// New warnings to be fixed after clang-r377782.
 		"-Wno-bitwise-conditional-parentheses", // http://b/148286937
-		"-Wno-bool-operation",                  // http://b/148287141
 		"-Wno-int-in-bool-context",             // http://b/148287349
 		"-Wno-sizeof-array-div",                // http://b/148815709
-		"-Wno-tautological-bitwise-compare",    // http://b/148831363
 		"-Wno-tautological-overlap-compare",    // http://b/148815696
 	}, " "))
 
diff --git a/cc/config/global.go b/cc/config/global.go
index 57a5852..d01dd84 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-r377782"
-	ClangDefaultShortVersion = "10.0.3"
+	ClangDefaultVersion      = "clang-r377782b"
+	ClangDefaultShortVersion = "10.0.4"
 
 	// Directories with warnings from Android.bp files.
 	WarningAllowedProjects = []string{
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 5cecbd6..8ad6a1d 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -19,24 +19,15 @@
 // has VndkUseCoreVariant set.
 var VndkMustUseVendorVariantList = []string{
 	"android.hardware.light-ndk_platform",
-	"android.hardware.nfc@1.2",
 	"android.hardware.power-ndk_platform",
 	"android.hardware.vibrator-ndk_platform",
 	"libbinder",
 	"libcrypto",
 	"libexpat",
-	"libgatekeeper",
 	"libgui",
-	"libhidlcache",
-	"libkeymaster_messages",
-	"libkeymaster_portable",
-	"libmedia_omx",
-	"libpuresoftkeymasterdevice",
 	"libselinux",
-	"libsoftkeymasterdevice",
 	"libsqlite",
 	"libssl",
-	"libstagefright_bufferpool@2.0",
 	"libstagefright_bufferqueue_helper",
 	"libstagefright_foundation",
 	"libstagefright_omx",
diff --git a/cc/library.go b/cc/library.go
index 0bddab5..bca9a96 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -281,11 +281,9 @@
 }
 
 func (f *flagExporter) reexportFlags(flags ...string) {
-	for _, flag := range flags {
-		if strings.HasPrefix(flag, "-I") || strings.HasPrefix(flag, "-isystem") {
-			panic(fmt.Errorf("Exporting invalid flag %q: "+
-				"use reexportDirs or reexportSystemDirs to export directories", flag))
-		}
+	if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") {
+		panic(fmt.Errorf("Exporting invalid flag %q: "+
+			"use reexportDirs or reexportSystemDirs to export directories", flag))
 	}
 	f.flags = append(f.flags, flags...)
 }
diff --git a/cc/stl.go b/cc/stl.go
index af015f9..eda8a4f 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -151,6 +151,14 @@
 	return version < 21
 }
 
+func staticUnwinder(ctx android.BaseModuleContext) string {
+	if ctx.Arch().ArchType == android.Arm {
+		return "libunwind_llvm"
+	} else {
+		return "libgcc_stripped"
+	}
+}
+
 func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
 	switch stl.Properties.SelectedStl {
 	case "libstdc++":
@@ -172,16 +180,16 @@
 		}
 		if ctx.toolchain().Bionic() {
 			if ctx.staticBinary() {
-				deps.StaticLibs = append(deps.StaticLibs, "libm", "libc")
-				if ctx.Arch().ArchType == android.Arm {
-					deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
-				} else {
-					deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped")
-				}
+				deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", staticUnwinder(ctx))
+			} else {
+				deps.StaticUnwinderIfLegacy = true
 			}
 		}
 	case "":
 		// None or error.
+		if ctx.toolchain().Bionic() && ctx.Module().Name() == "libc++" {
+			deps.StaticUnwinderIfLegacy = true
+		}
 	case "ndk_system":
 		// TODO: Make a system STL prebuilt for the NDK.
 		// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 9b0e7a5..6cb9873 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -426,7 +426,7 @@
 		cmd.FlagWithArg("--copy-dex-files=", "false")
 	}
 
-	if !anyHavePrefix(preoptFlags, "--compiler-filter=") {
+	if !android.PrefixInList(preoptFlags, "--compiler-filter=") {
 		var compilerFilter string
 		if contains(global.SystemServerJars, module.Name) {
 			// Jars of system server, use the product option if it is set, speed otherwise.
@@ -618,32 +618,4 @@
 	return false
 }
 
-// remove all elements in a from b, returning a new slice
-func filterOut(a []string, b []string) []string {
-	var ret []string
-	for _, x := range b {
-		if !contains(a, x) {
-			ret = append(ret, x)
-		}
-	}
-	return ret
-}
-
-func replace(l []string, from, to string) {
-	for i := range l {
-		if l[i] == from {
-			l[i] = to
-		}
-	}
-}
-
 var copyOf = android.CopyOf
-
-func anyHavePrefix(l []string, prefix string) bool {
-	for _, x := range l {
-		if strings.HasPrefix(x, prefix) {
-			return true
-		}
-	}
-	return false
-}
diff --git a/java/aar.go b/java/aar.go
index 24c5e7d..6e3b9e6 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -101,6 +101,7 @@
 	usesNonSdkApis          bool
 	sdkLibraries            []string
 	hasNoCode               bool
+	LoggingParent           string
 
 	splitNames []string
 	splits     []split
@@ -134,15 +135,8 @@
 	manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
 	resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
 
-	hasVersionCode := false
-	hasVersionName := false
-	for _, f := range a.aaptProperties.Aaptflags {
-		if strings.HasPrefix(f, "--version-code") {
-			hasVersionCode = true
-		} else if strings.HasPrefix(f, "--version-name") {
-			hasVersionName = true
-		}
-	}
+	hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code")
+	hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name")
 
 	// Flags specified in Android.bp
 	linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
@@ -241,7 +235,8 @@
 	manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
 
 	manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext, sdkLibraries,
-		a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode)
+		a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode,
+		a.LoggingParent)
 
 	// Add additional manifest files to transitive manifests.
 	additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
@@ -337,7 +332,7 @@
 
 	// Extract assets from the resource package output so that they can be used later in aapt2link
 	// for modules that depend on this one.
-	if android.PrefixedStringInList(linkFlags, "-A ") || len(assetPackages) > 0 {
+	if android.PrefixInList(linkFlags, "-A ") || len(assetPackages) > 0 {
 		assets := android.PathForModuleOut(ctx, "assets.zip")
 		ctx.Build(pctx, android.BuildParams{
 			Rule:        extractAssetsRule,
diff --git a/java/android_manifest.go b/java/android_manifest.go
index e3646f5..9a71be2 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -53,7 +53,7 @@
 
 // Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
 func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext, sdkLibraries []string,
-	isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool) android.Path {
+	isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool, loggingParent string) android.Path {
 
 	var args []string
 	if isLibrary {
@@ -91,6 +91,9 @@
 		args = append(args, "--has-no-code")
 	}
 
+	if loggingParent != "" {
+		args = append(args, "--logging-parent", loggingParent)
+	}
 	var deps android.Paths
 	targetSdkVersion, err := sdkContext.targetSdkVersion().effectiveVersionString(ctx)
 	if err != nil {
diff --git a/java/app.go b/java/app.go
index 02f3e7f..71bad68 100755
--- a/java/app.go
+++ b/java/app.go
@@ -111,6 +111,9 @@
 
 	// the package name of this app. The package name in the manifest file is used if one was not given.
 	Package_name *string
+
+	// the logging parent of this app.
+	Logging_parent *string
 }
 
 type AndroidApp struct {
@@ -273,13 +276,7 @@
 	aaptLinkFlags := []string{}
 
 	// Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided.
-	hasProduct := false
-	for _, f := range a.aaptProperties.Aaptflags {
-		if strings.HasPrefix(f, "--product") {
-			hasProduct = true
-			break
-		}
-	}
+	hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
 	if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
 		aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
 	}
@@ -309,7 +306,7 @@
 
 	a.aapt.splitNames = a.appProperties.Package_splits
 	a.aapt.sdkLibraries = a.exportedSdkLibs
-
+	a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
 	a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
 
 	// apps manifests are handled by aapt, don't let Module see them
diff --git a/java/app_test.go b/java/app_test.go
index c86b038..6d94160 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1181,6 +1181,7 @@
 			name: "bar",
 			base: "foo",
 			certificate: ":new_certificate",
+			logging_parent: "bah",
 		}
 
 		android_app_certificate {
@@ -1196,37 +1197,41 @@
 		`)
 
 	expectedVariants := []struct {
-		moduleName  string
-		variantName string
-		apkName     string
-		apkPath     string
-		signFlag    string
-		overrides   []string
-		aaptFlag    string
+		moduleName     string
+		variantName    string
+		apkName        string
+		apkPath        string
+		signFlag       string
+		overrides      []string
+		aaptFlag       string
+		logging_parent string
 	}{
 		{
-			moduleName:  "foo",
-			variantName: "android_common",
-			apkPath:     "/target/product/test_device/system/app/foo/foo.apk",
-			signFlag:    "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
-			overrides:   []string{"qux"},
-			aaptFlag:    "",
+			moduleName:     "foo",
+			variantName:    "android_common",
+			apkPath:        "/target/product/test_device/system/app/foo/foo.apk",
+			signFlag:       "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+			overrides:      []string{"qux"},
+			aaptFlag:       "",
+			logging_parent: "",
 		},
 		{
-			moduleName:  "bar",
-			variantName: "android_common_bar",
-			apkPath:     "/target/product/test_device/system/app/bar/bar.apk",
-			signFlag:    "cert/new_cert.x509.pem cert/new_cert.pk8",
-			overrides:   []string{"qux", "foo"},
-			aaptFlag:    "",
+			moduleName:     "bar",
+			variantName:    "android_common_bar",
+			apkPath:        "/target/product/test_device/system/app/bar/bar.apk",
+			signFlag:       "cert/new_cert.x509.pem cert/new_cert.pk8",
+			overrides:      []string{"qux", "foo"},
+			aaptFlag:       "",
+			logging_parent: "bah",
 		},
 		{
-			moduleName:  "baz",
-			variantName: "android_common_baz",
-			apkPath:     "/target/product/test_device/system/app/baz/baz.apk",
-			signFlag:    "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
-			overrides:   []string{"qux", "foo"},
-			aaptFlag:    "--rename-manifest-package org.dandroid.bp",
+			moduleName:     "baz",
+			variantName:    "android_common_baz",
+			apkPath:        "/target/product/test_device/system/app/baz/baz.apk",
+			signFlag:       "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+			overrides:      []string{"qux", "foo"},
+			aaptFlag:       "--rename-manifest-package org.dandroid.bp",
+			logging_parent: "",
 		},
 	}
 	for _, expected := range expectedVariants {
@@ -1260,6 +1265,13 @@
 				expected.overrides, mod.appProperties.Overrides)
 		}
 
+		// Test Overridable property: Logging_parent
+		logging_parent := mod.aapt.LoggingParent
+		if expected.logging_parent != logging_parent {
+			t.Errorf("Incorrect overrides property value for logging parent, expected: %q, got: %q",
+				expected.logging_parent, logging_parent)
+		}
+
 		// Check the package renaming flag, if exists.
 		res := variant.Output("package-res.apk")
 		aapt2Flags := res.Args["flags"]
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 959f1c7..6b39314 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -605,11 +605,8 @@
 				continue
 			}
 			packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
-			for _, pkg := range filterPackages {
-				if strings.HasPrefix(packageName, pkg) {
-					filtered = append(filtered, src)
-					break
-				}
+			if android.HasAnyPrefix(packageName, filterPackages) {
+				filtered = append(filtered, src)
 			}
 		}
 		return filtered
diff --git a/java/java.go b/java/java.go
index ceedd89..c3e2c96 100644
--- a/java/java.go
+++ b/java/java.go
@@ -807,6 +807,7 @@
 	javaSdk
 	javaSystem
 	javaModule
+	javaSystemServer
 	javaPlatform
 )
 
@@ -840,6 +841,10 @@
 		return javaModule, true
 	case ver.kind == sdkModule:
 		return javaModule, false
+	case name == "services-stubs":
+		return javaSystemServer, true
+	case ver.kind == sdkSystemServer:
+		return javaSystemServer, false
 	case ver.kind == sdkPrivate || ver.kind == sdkNone || ver.kind == sdkCorePlatform:
 		return javaPlatform, false
 	case !ver.valid():
@@ -875,17 +880,23 @@
 		}
 		break
 	case javaSystem:
-		if otherLinkType == javaPlatform || otherLinkType == javaModule {
+		if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer {
 			ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
 				ctx.OtherModuleName(to))
 		}
 		break
 	case javaModule:
-		if otherLinkType == javaPlatform {
+		if otherLinkType == javaPlatform || otherLinkType == javaSystemServer {
 			ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage,
 				ctx.OtherModuleName(to))
 		}
 		break
+	case javaSystemServer:
+		if otherLinkType == javaPlatform {
+			ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage,
+				ctx.OtherModuleName(to))
+		}
+		break
 	case javaPlatform:
 		// no restriction on link-type
 		break
diff --git a/java/sdk.go b/java/sdk.go
index 1c047a3..1e60d67 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -72,6 +72,7 @@
 	sdkSystem
 	sdkTest
 	sdkModule
+	sdkSystemServer
 	sdkPrivate
 )
 
@@ -94,6 +95,8 @@
 		return "core_platform"
 	case sdkModule:
 		return "module"
+	case sdkSystemServer:
+		return "system_server"
 	default:
 		return "invalid"
 	}
@@ -261,6 +264,8 @@
 			kind = sdkTest
 		case "module":
 			kind = sdkModule
+		case "system_server":
+			kind = sdkSystemServer
 		default:
 			return sdkSpec{sdkInvalid, sdkVersionNone, str}
 		}
@@ -324,13 +329,13 @@
 		}
 	}
 
-	toModule := func(m, r string, aidl android.Path) sdkDep {
+	toModule := func(modules []string, res string, aidl android.Path) sdkDep {
 		return sdkDep{
 			useModule:          true,
-			bootclasspath:      []string{m, config.DefaultLambdaStubsLibrary},
+			bootclasspath:      append(modules, config.DefaultLambdaStubsLibrary),
 			systemModules:      "core-current-stubs-system-modules",
-			java9Classpath:     []string{m},
-			frameworkResModule: r,
+			java9Classpath:     modules,
+			frameworkResModule: res,
 			aidl:               android.OptionalPathForPath(aidl),
 		}
 	}
@@ -380,16 +385,19 @@
 			noFrameworksLibs:   true,
 		}
 	case sdkPublic:
-		return toModule("android_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
+		return toModule([]string{"android_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
 	case sdkSystem:
-		return toModule("android_system_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
+		return toModule([]string{"android_system_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
 	case sdkTest:
-		return toModule("android_test_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
+		return toModule([]string{"android_test_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
 	case sdkCore:
-		return toModule("core.current.stubs", "", nil)
+		return toModule([]string{"core.current.stubs"}, "", nil)
 	case sdkModule:
 		// TODO(146757305): provide .apk and .aidl that have more APIs for modules
-		return toModule("android_module_lib_stubs_current", "framework-res", sdkFrameworkAidlPath(ctx))
+		return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+	case sdkSystemServer:
+		// TODO(146757305): provide .apk and .aidl that have more APIs for modules
+		return toModule([]string{"android_module_lib_stubs_current", "services-stubs"}, "framework-res", sdkFrameworkAidlPath(ctx))
 	default:
 		panic(fmt.Errorf("invalid sdk %q", sdkVersion.raw))
 	}
diff --git a/java/sdk_test.go b/java/sdk_test.go
index c815fe3..ea6733d 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -212,7 +212,6 @@
 			aidl:           "-pprebuilts/sdk/29/public/framework.aidl",
 		},
 		{
-
 			name:           "module_current",
 			properties:     `sdk_version: "module_current",`,
 			bootclasspath:  []string{"android_module_lib_stubs_current", "core-lambda-stubs"},
@@ -220,6 +219,14 @@
 			java9classpath: []string{"android_module_lib_stubs_current"},
 			aidl:           "-p" + buildDir + "/framework.aidl",
 		},
+		{
+			name:           "system_server_current",
+			properties:     `sdk_version: "system_server_current",`,
+			bootclasspath:  []string{"android_module_lib_stubs_current", "services-stubs", "core-lambda-stubs"},
+			system:         "core-current-stubs-system-modules",
+			java9classpath: []string{"android_module_lib_stubs_current", "services-stubs"},
+			aidl:           "-p" + buildDir + "/framework.aidl",
+		},
 	}
 
 	for _, testcase := range classpathTestcases {
diff --git a/java/testing.go b/java/testing.go
index 8f979c7..3111109 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -147,6 +147,7 @@
 		"android_system_stubs_current",
 		"android_test_stubs_current",
 		"android_module_lib_stubs_current",
+		"services-stubs",
 		"core.current.stubs",
 		"core.platform.api.stubs",
 		"kotlin-stdlib",
diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py
index 945bc18..c59732b 100755
--- a/scripts/manifest_fixer.py
+++ b/scripts/manifest_fixer.py
@@ -51,6 +51,9 @@
                       help='specify additional <uses-library> tag to add. android:requred is set to false')
   parser.add_argument('--uses-non-sdk-api', dest='uses_non_sdk_api', action='store_true',
                       help='manifest is for a package built against the platform')
+  parser.add_argument('--logging-parent', dest='logging_parent', default='',
+                      help=('specify logging parent as an additional <meta-data> tag. '
+                            'This value is ignored if the logging_parent meta-data tag is present.'))
   parser.add_argument('--use-embedded-dex', dest='use_embedded_dex', action='store_true',
                       help=('specify if the app wants to use embedded dex and avoid extracted,'
                             'locally compiled code. Must not conflict if already declared '
@@ -124,6 +127,52 @@
     element.setAttributeNode(target_attr)
 
 
+def add_logging_parent(doc, logging_parent_value):
+  """Add logging parent as an additional <meta-data> tag.
+
+  Args:
+    doc: The XML document. May be modified by this function.
+    logging_parent_value: A string representing the logging
+      parent value.
+  Raises:
+    RuntimeError: Invalid manifest
+  """
+  manifest = parse_manifest(doc)
+
+  logging_parent_key = 'android.content.pm.LOGGING_PARENT'
+  elems = get_children_with_tag(manifest, 'application')
+  application = elems[0] if len(elems) == 1 else None
+  if len(elems) > 1:
+    raise RuntimeError('found multiple <application> tags')
+  elif not elems:
+    application = doc.createElement('application')
+    indent = get_indent(manifest.firstChild, 1)
+    first = manifest.firstChild
+    manifest.insertBefore(doc.createTextNode(indent), first)
+    manifest.insertBefore(application, first)
+
+  indent = get_indent(application.firstChild, 2)
+
+  last = application.lastChild
+  if last is not None and last.nodeType != minidom.Node.TEXT_NODE:
+    last = None
+
+  if not find_child_with_attribute(application, 'meta-data', android_ns,
+                                   'name', logging_parent_key):
+    ul = doc.createElement('meta-data')
+    ul.setAttributeNS(android_ns, 'android:name', logging_parent_key)
+    ul.setAttributeNS(android_ns, 'android:value', logging_parent_value)
+    application.insertBefore(doc.createTextNode(indent), last)
+    application.insertBefore(ul, last)
+    last = application.lastChild
+
+  # align the closing tag with the opening tag if it's not
+  # indented
+  if last and last.nodeType != minidom.Node.TEXT_NODE:
+    indent = get_indent(application.previousSibling, 1)
+    application.appendChild(doc.createTextNode(indent))
+
+
 def add_uses_libraries(doc, new_uses_libraries, required):
   """Add additional <uses-library> tags
 
@@ -291,6 +340,9 @@
     if args.uses_non_sdk_api:
       add_uses_non_sdk_api(doc)
 
+    if args.logging_parent:
+      add_logging_parent(doc, args.logging_parent)
+
     if args.use_embedded_dex:
       add_use_embedded_dex(doc)
 
diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py
index ea8095e..d6e7f26 100755
--- a/scripts/manifest_fixer_test.py
+++ b/scripts/manifest_fixer_test.py
@@ -226,6 +226,47 @@
     self.assertEqual(output, expected)
 
 
+class AddLoggingParentTest(unittest.TestCase):
+  """Unit tests for add_logging_parent function."""
+
+  def add_logging_parent_test(self, input_manifest, logging_parent=None):
+    doc = minidom.parseString(input_manifest)
+    if logging_parent:
+      manifest_fixer.add_logging_parent(doc, logging_parent)
+    output = StringIO.StringIO()
+    manifest_fixer.write_xml(output, doc)
+    return output.getvalue()
+
+  manifest_tmpl = (
+      '<?xml version="1.0" encoding="utf-8"?>\n'
+      '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
+      '%s'
+      '</manifest>\n')
+
+  def uses_logging_parent(self, logging_parent=None):
+    attrs = ''
+    if logging_parent:
+      meta_text = ('<meta-data android:name="android.content.pm.LOGGING_PARENT" '
+                   'android:value="%s"/>\n') % (logging_parent)
+      attrs += '    <application>\n        %s    </application>\n' % (meta_text)
+
+    return attrs
+
+  def test_no_logging_parent(self):
+    """Tests manifest_fixer with no logging_parent."""
+    manifest_input = self.manifest_tmpl % ''
+    expected = self.manifest_tmpl % self.uses_logging_parent()
+    output = self.add_logging_parent_test(manifest_input)
+    self.assertEqual(output, expected)
+
+  def test_logging_parent(self):
+    """Tests manifest_fixer with no logging_parent."""
+    manifest_input = self.manifest_tmpl % ''
+    expected = self.manifest_tmpl % self.uses_logging_parent('FOO')
+    output = self.add_logging_parent_test(manifest_input, 'FOO')
+    self.assertEqual(output, expected)
+
+
 class AddUsesLibrariesTest(unittest.TestCase):
   """Unit tests for add_uses_libraries function."""