Merge "Run the metrics uploader in the background."
diff --git a/android/config.go b/android/config.go
index 0fe4a0c..a53f44a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1029,6 +1029,27 @@
 	return Bool(c.config.productVariables.SamplingPGO)
 }
 
+// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for
+// path. Coverage is enabled by default when the product variable
+// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is
+// enabled for any path which is part of this variable (and not part of the
+// JavaCoverageExcludePaths product variable). Value "*" in JavaCoveragePaths
+// represents any path.
+func (c *deviceConfig) JavaCoverageEnabledForPath(path string) bool {
+	coverage := false
+	if c.config.productVariables.JavaCoveragePaths == nil ||
+		InList("*", c.config.productVariables.JavaCoveragePaths) ||
+		HasAnyPrefix(path, c.config.productVariables.JavaCoveragePaths) {
+		coverage = true
+	}
+	if coverage && c.config.productVariables.JavaCoverageExcludePaths != nil {
+		if HasAnyPrefix(path, c.config.productVariables.JavaCoverageExcludePaths) {
+			coverage = false
+		}
+	}
+	return coverage
+}
+
 func (c *config) NativeLineCoverage() bool {
 	return Bool(c.productVariables.NativeLineCoverage)
 }
@@ -1041,15 +1062,20 @@
 	return Bool(c.config.productVariables.ClangCoverage)
 }
 
-func (c *deviceConfig) CoverageEnabledForPath(path string) bool {
+// NativeCoverageEnabledForPath returns whether (GCOV- or Clang-based) native
+// code coverage is enabled for path. By default, coverage is not enabled for a
+// given path unless it is part of the NativeCoveragePaths product variable (and
+// not part of the NativeCoverageExcludePaths product variable). Value "*" in
+// NativeCoveragePaths represents any path.
+func (c *deviceConfig) NativeCoverageEnabledForPath(path string) bool {
 	coverage := false
-	if c.config.productVariables.CoveragePaths != nil {
-		if InList("*", c.config.productVariables.CoveragePaths) || HasAnyPrefix(path, c.config.productVariables.CoveragePaths) {
+	if c.config.productVariables.NativeCoveragePaths != nil {
+		if InList("*", c.config.productVariables.NativeCoveragePaths) || HasAnyPrefix(path, c.config.productVariables.NativeCoveragePaths) {
 			coverage = true
 		}
 	}
-	if coverage && c.config.productVariables.CoverageExcludePaths != nil {
-		if HasAnyPrefix(path, c.config.productVariables.CoverageExcludePaths) {
+	if coverage && c.config.productVariables.NativeCoverageExcludePaths != nil {
+		if HasAnyPrefix(path, c.config.productVariables.NativeCoverageExcludePaths) {
 			coverage = false
 		}
 	}
diff --git a/android/variable.go b/android/variable.go
index b69d425..863fe5a 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -266,11 +266,14 @@
 
 	SamplingPGO *bool `json:",omitempty"`
 
-	NativeLineCoverage   *bool    `json:",omitempty"`
-	Native_coverage      *bool    `json:",omitempty"`
-	ClangCoverage        *bool    `json:",omitempty"`
-	CoveragePaths        []string `json:",omitempty"`
-	CoverageExcludePaths []string `json:",omitempty"`
+	JavaCoveragePaths        []string `json:",omitempty"`
+	JavaCoverageExcludePaths []string `json:",omitempty"`
+
+	NativeLineCoverage         *bool    `json:",omitempty"`
+	Native_coverage            *bool    `json:",omitempty"`
+	ClangCoverage              *bool    `json:",omitempty"`
+	NativeCoveragePaths        []string `json:",omitempty"`
+	NativeCoverageExcludePaths []string `json:",omitempty"`
 
 	SanitizeHost       []string `json:",omitempty"`
 	SanitizeDevice     []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 3fef1ee..4c8575d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -178,12 +178,6 @@
 	//
 	// Module separator
 	//
-	m["com.android.conscrypt"] = []string{
-		"libnativehelper_header_only",
-	}
-	//
-	// Module separator
-	//
 	m["com.android.neuralnetworks"] = []string{
 		"android.hardware.neuralnetworks@1.0",
 		"android.hardware.neuralnetworks@1.1",
@@ -479,7 +473,6 @@
 		"libbase_ndk",
 		"libfuse",
 		"libfuse_jni",
-		"libnativehelper_header_only",
 	}
 	//
 	// Module separator
@@ -561,7 +554,6 @@
 		"ipmemorystore-aidl-interfaces-java",
 		"libcgrouprc",
 		"libcgrouprc_format",
-		"libnativehelper_compat_libc++",
 		"libtetherutilsjni",
 		"libvndksupport",
 		"net-utils-framework-common",
@@ -1954,8 +1946,10 @@
 					fi := apexFileForNativeLibrary(ctx, c, handleSpecialLibs)
 					fi.isJniLib = isJniLib
 					filesInfo = append(filesInfo, fi)
-					// bootstrap bionic libs are treated as provided by system
-					if c.HasStubsVariants() && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
+					// Collect the list of stub-providing libs except:
+					// - VNDK libs are only for vendors
+					// - bootstrap bionic libs are treated as provided by system
+					if c.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
 						provideNativeLibs = append(provideNativeLibs, fi.Stem())
 					}
 					return true // track transitive dependencies
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 7159a45..6a832af 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2817,6 +2817,40 @@
 	})
 }
 
+func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: ":myapex-file_contexts",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libz",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			stubs: {
+				symbol_file: "libz.map.txt",
+				versions: ["30"],
+			}
+		}
+	`+vndkLibrariesTxtFiles("current"), withFiles(map[string][]byte{
+		"libz.map.txt": nil,
+	}))
+
+	apexManifestRule := ctx.ModuleForTests("myapex", "android_common_image").Rule("apexManifestRule")
+	provideNativeLibs := names(apexManifestRule.Args["provideNativeLibs"])
+	ensureListEmpty(t, provideNativeLibs)
+}
+
 func TestDependenciesInApexManifest(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
diff --git a/cc/coverage.go b/cc/coverage.go
index f885fcb..1a559a9 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -180,7 +180,7 @@
 
 		if needCoverageVariant {
 			// Coverage variant is actually built with coverage if enabled for its module path
-			needCoverageBuild = ctx.DeviceConfig().CoverageEnabledForPath(ctx.ModuleDir())
+			needCoverageBuild = ctx.DeviceConfig().NativeCoverageEnabledForPath(ctx.ModuleDir())
 		}
 	}
 
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index d79badb..5ef9a78 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -329,6 +329,7 @@
 		Description: "parse ndk api symbol file for api coverage: " + symbolFilePath.Rel(),
 		Outputs:     []android.WritablePath{parsedApiCoveragePath},
 		Input:       symbolFilePath,
+		Implicits:   []android.Path{apiLevelsJson},
 		Args: map[string]string{
 			"apiMap": apiLevelsJson.String(),
 		},
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 3440f8e..bc44b21 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -123,10 +123,10 @@
 	ProfileIsTextListing bool
 	ProfileBootListing   android.OptionalPath
 
-	EnforceUsesLibraries         bool
-	PresentOptionalUsesLibraries []string
-	UsesLibraries                []string
-	LibraryPaths                 LibraryPaths
+	EnforceUsesLibraries  bool
+	OptionalUsesLibraries []string
+	UsesLibraries         []string
+	LibraryPaths          LibraryPaths
 
 	Archs                   []android.ArchType
 	DexPreoptImages         []android.Path
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 57a9250..9cbe6e5 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -285,7 +285,7 @@
 
 	if module.EnforceUsesLibraries {
 		// Unconditional class loader context.
-		usesLibs := append(copyOf(module.UsesLibraries), module.PresentOptionalUsesLibraries...)
+		usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...)
 		classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...)
 
 		// Conditional class loader context for API version < 28.
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index d239993..ec31549 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -44,7 +44,7 @@
 		ProfileClassListing:             android.OptionalPath{},
 		ProfileIsTextListing:            false,
 		EnforceUsesLibraries:            false,
-		PresentOptionalUsesLibraries:    nil,
+		OptionalUsesLibraries:           nil,
 		UsesLibraries:                   nil,
 		LibraryPaths:                    nil,
 		Archs:                           []android.ArchType{android.Arm},
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index c33415e..7f1afd6 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -193,10 +193,10 @@
 		ProfileIsTextListing: profileIsTextListing,
 		ProfileBootListing:   profileBootListing,
 
-		EnforceUsesLibraries:         d.enforceUsesLibs,
-		PresentOptionalUsesLibraries: d.optionalUsesLibs,
-		UsesLibraries:                d.usesLibs,
-		LibraryPaths:                 d.libraryPaths,
+		EnforceUsesLibraries:  d.enforceUsesLibs,
+		OptionalUsesLibraries: d.optionalUsesLibs,
+		UsesLibraries:         d.usesLibs,
+		LibraryPaths:          d.libraryPaths,
 
 		Archs:                   archs,
 		DexPreoptImages:         images,
diff --git a/java/java.go b/java/java.go
index 1cdfbf1..ab8f859 100644
--- a/java/java.go
+++ b/java/java.go
@@ -601,7 +601,9 @@
 }
 
 func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
-	return j.properties.Instrument && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
+	return j.properties.Instrument &&
+		ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") &&
+		ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
 }
 
 func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
@@ -610,6 +612,21 @@
 			ctx.Config().UnbundledBuild())
 }
 
+func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool {
+	// Force enable the instrumentation for java code that is built for APEXes ...
+	// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
+	// doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true.
+	isJacocoAgent := ctx.ModuleName() == "jacocoagent"
+	if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() {
+		if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
+			return true
+		} else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+			return true
+		}
+	}
+	return false
+}
+
 func (j *Module) sdkVersion() sdkSpec {
 	return sdkSpecFrom(String(j.deviceProperties.Sdk_version))
 }
@@ -1543,11 +1560,7 @@
 		j.headerJarFile = j.implementationJarFile
 	}
 
-	// Force enable the instrumentation for java code that is built for APEXes ...
-	// except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
-	// doesn't make sense)
-	isJacocoAgent := ctx.ModuleName() == "jacocoagent"
-	if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() {
+	if j.shouldInstrumentInApex(ctx) {
 		j.properties.Instrument = true
 	}
 
diff --git a/java/java_test.go b/java/java_test.go
index 215070e..b74111b 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1448,6 +1448,38 @@
 		`)
 }
 
+func TestJavaSdkLibrary_ModuleLib(t *testing.T) {
+	testJava(t, `
+		java_sdk_library {
+			name: "foo",
+			srcs: ["a.java", "b.java"],
+			api_packages: ["foo"],
+			system: {
+				enabled: true,
+			},
+			module_lib: {
+				enabled: true,
+			},
+		}
+		`)
+}
+
+func TestJavaSdkLibrary_SystemServer(t *testing.T) {
+	testJava(t, `
+		java_sdk_library {
+			name: "foo",
+			srcs: ["a.java", "b.java"],
+			api_packages: ["foo"],
+			system: {
+				enabled: true,
+			},
+			system_server: {
+				enabled: true,
+			},
+		}
+		`)
+}
+
 func TestJavaSdkLibrary_MissingScope(t *testing.T) {
 	testJavaError(t, `requires api scope module-lib from foo but it only has \[\] available`, `
 		java_sdk_library {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index de5ee03..63ebe63 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -264,7 +264,7 @@
 	apiScopeModuleLib = initApiScope(&apiScope{
 		name:    "module-lib",
 		extends: apiScopeSystem,
-		// Module_lib scope is disabled by default in legacy mode.
+		// The module-lib scope is disabled by default in legacy mode.
 		//
 		// Enabling this would break existing usages.
 		legacyEnabledStatus: func(module *SdkLibrary) bool {
@@ -280,11 +280,34 @@
 			"--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\)",
 		},
 	})
+	apiScopeSystemServer = initApiScope(&apiScope{
+		name:    "system-server",
+		extends: apiScopePublic,
+		// The system-server scope is disabled by default in legacy mode.
+		//
+		// Enabling this would break existing usages.
+		legacyEnabledStatus: func(module *SdkLibrary) bool {
+			return false
+		},
+		scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
+			return &module.sdkLibraryProperties.System_server
+		},
+		apiFilePrefix: "system-server-",
+		moduleSuffix:  ".system_server",
+		sdkVersion:    "system_server_current",
+		droidstubsArgs: []string{
+			"--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\) ",
+			"--hide-annotation android.annotation.Hide",
+			// com.android.* classes are okay in this interface"
+			"--hide InternalClasses",
+		},
+	})
 	allApiScopes = apiScopes{
 		apiScopePublic,
 		apiScopeSystem,
 		apiScopeTest,
 		apiScopeModuleLib,
+		apiScopeSystemServer,
 	}
 )
 
@@ -429,12 +452,18 @@
 	// In non-legacy mode the test api scope is disabled by default.
 	Test ApiScopeProperties
 
-	// The properties specific to the module_lib api scope
+	// The properties specific to the module-lib api scope
 	//
-	// Unless explicitly specified by using test.enabled the module_lib api scope is
+	// Unless explicitly specified by using test.enabled the module-lib api scope is
 	// disabled by default.
 	Module_lib ApiScopeProperties
 
+	// The properties specific to the system-server api scope
+	//
+	// Unless explicitly specified by using test.enabled the module-lib api scope is
+	// disabled by default.
+	System_server ApiScopeProperties
+
 	// Determines if the stubs are preferred over the implementation library
 	// for linking, even when the client doesn't specify sdk_version. When this
 	// is set to true, such clients are provided with the widest API surface that
@@ -743,6 +772,8 @@
 		apiScope = apiScopeModuleLib
 	case sdkTest:
 		apiScope = apiScopeTest
+	case sdkSystemServer:
+		apiScope = apiScopeSystemServer
 	default:
 		apiScope = apiScopePublic
 	}
diff --git a/java/testing.go b/java/testing.go
index f34c64a..6fc10da 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -80,6 +80,13 @@
 		"prebuilts/sdk/30/test/api/bar-removed.txt":                nil,
 		"prebuilts/sdk/tools/core-lambda-stubs.jar":                nil,
 		"prebuilts/sdk/Android.bp":                                 []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`),
+
+		// For java_sdk_library
+		"api/module-lib-current.txt":                        nil,
+		"api/module-lib-removed.txt":                        nil,
+		"api/system-server-current.txt":                     nil,
+		"api/system-server-removed.txt":                     nil,
+		"build/soong/scripts/gen-java-current-api-files.sh": nil,
 	}
 
 	cc.GatherRequiredFilesForTest(mockFS)
diff --git a/rust/rust_test.go b/rust/rust_test.go
index d658ee2..fe21e3a 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -89,7 +89,7 @@
 
 	if coverage {
 		config.TestProductVariables.Native_coverage = proptools.BoolPtr(true)
-		config.TestProductVariables.CoveragePaths = []string{"*"}
+		config.TestProductVariables.NativeCoveragePaths = []string{"*"}
 	}
 
 	t.Helper()
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 56706c7..77a4e94 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -34,6 +34,8 @@
 		"api/test-removed.txt":                              nil,
 		"api/module-lib-current.txt":                        nil,
 		"api/module-lib-removed.txt":                        nil,
+		"api/system-server-current.txt":                     nil,
+		"api/system-server-removed.txt":                     nil,
 		"build/soong/scripts/gen-java-current-api-files.sh": nil,
 	}
 
@@ -61,6 +63,9 @@
 	name: "android_module_lib_stubs_current",
 }
 java_import {
+	name: "android_system_server_stubs_current",
+}
+java_import {
 	name: "core-lambda-stubs", 
 	sdk_version: "none",
 }
@@ -1398,6 +1403,93 @@
 	)
 }
 
+func TestSnapshotWithJavaSdkLibrary_SystemServer(t *testing.T) {
+	result := testSdkWithJava(t, `
+		sdk {
+			name: "mysdk",
+			java_sdk_libs: ["myjavalib"],
+		}
+
+		java_sdk_library {
+			name: "myjavalib",
+			apex_available: ["//apex_available:anyapex"],
+			srcs: ["Test.java"],
+			sdk_version: "current",
+			public: {
+				enabled: true,
+			},
+			system_server: {
+				enabled: true,
+			},
+		}
+	`)
+
+	result.CheckSnapshot("mysdk", "",
+		checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+    name: "mysdk_myjavalib@current",
+    sdk_member_name: "myjavalib",
+    apex_available: ["//apex_available:anyapex"],
+    shared_library: true,
+    public: {
+        jars: ["sdk_library/public/myjavalib-stubs.jar"],
+        stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+        current_api: "sdk_library/public/myjavalib.txt",
+        removed_api: "sdk_library/public/myjavalib-removed.txt",
+        sdk_version: "current",
+    },
+    system_server: {
+        jars: ["sdk_library/system-server/myjavalib-stubs.jar"],
+        stub_srcs: ["sdk_library/system-server/myjavalib_stub_sources"],
+        current_api: "sdk_library/system-server/myjavalib.txt",
+        removed_api: "sdk_library/system-server/myjavalib-removed.txt",
+        sdk_version: "system_server_current",
+    },
+}
+
+java_sdk_library_import {
+    name: "myjavalib",
+    prefer: false,
+    apex_available: ["//apex_available:anyapex"],
+    shared_library: true,
+    public: {
+        jars: ["sdk_library/public/myjavalib-stubs.jar"],
+        stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
+        current_api: "sdk_library/public/myjavalib.txt",
+        removed_api: "sdk_library/public/myjavalib-removed.txt",
+        sdk_version: "current",
+    },
+    system_server: {
+        jars: ["sdk_library/system-server/myjavalib-stubs.jar"],
+        stub_srcs: ["sdk_library/system-server/myjavalib_stub_sources"],
+        current_api: "sdk_library/system-server/myjavalib.txt",
+        removed_api: "sdk_library/system-server/myjavalib-removed.txt",
+        sdk_version: "system_server_current",
+    },
+}
+
+sdk_snapshot {
+    name: "mysdk@current",
+    java_sdk_libs: ["mysdk_myjavalib@current"],
+}
+`),
+		checkAllCopyRules(`
+.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.system_server/android_common/javac/myjavalib.stubs.system_server.jar -> sdk_library/system-server/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.system_server/android_common/myjavalib.stubs.source.system_server_api.txt -> sdk_library/system-server/myjavalib.txt
+.intermediates/myjavalib.stubs.source.system_server/android_common/myjavalib.stubs.source.system_server_removed.txt -> sdk_library/system-server/myjavalib-removed.txt
+`),
+		checkMergeZips(
+			".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
+			".intermediates/mysdk/common_os/tmp/sdk_library/system-server/myjavalib_stub_sources.zip",
+		),
+	)
+}
+
 func TestSnapshotWithJavaSdkLibrary_NamingScheme(t *testing.T) {
 	result := testSdkWithJava(t, `
 		sdk {