diff --git a/android/api_levels.go b/android/api_levels.go index b6296d815..087206633 100644 --- a/android/api_levels.go +++ b/android/api_levels.go @@ -73,6 +73,7 @@ func getApiLevelsMap(config Config) map[string]int { "O-MR1": 27, "P": 28, "Q": 29, + "R": 30, } for i, codename := range config.PlatformVersionActiveCodenames() { apiLevelsMap[codename] = baseApiLevel + i diff --git a/android/module.go b/android/module.go index 17bc205e0..32d49fb72 100644 --- a/android/module.go +++ b/android/module.go @@ -247,6 +247,7 @@ type Module interface { Disable() Enabled() bool Target() Target + Owner() string InstallInData() bool InstallInTestcases() bool InstallInSanitizerDir() bool diff --git a/android/neverallow.go b/android/neverallow.go index aaea920cc..8b8e1accf 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -199,6 +199,7 @@ func createCcSdkVariantRules() []Rule { "prebuilts/ndk", "tools/test/graphicsbenchmark/apps/sample_app", "tools/test/graphicsbenchmark/functional_tests/java", + "vendor/xts/gts-tests/hostsidetests/gamedevicecert/apps/javatests", } platformVariantPropertiesAllowedList := []string{ @@ -274,6 +275,10 @@ func neverallowMutator(ctx BottomUpMutatorContext) { continue } + if !n.appliesToBootclasspathJar(ctx) { + continue + } + ctx.ModuleErrorf("violates " + n.String()) } } @@ -332,6 +337,18 @@ func (m *regexMatcher) String() string { return ".regexp(" + m.re.String() + ")" } +type notInListMatcher struct { + allowed []string +} + +func (m *notInListMatcher) Test(value string) bool { + return !InList(value, m.allowed) +} + +func (m *notInListMatcher) String() string { + return ".not-in-list(" + strings.Join(m.allowed, ",") + ")" +} + type isSetMatcher struct{} func (m *isSetMatcher) Test(value string) bool { @@ -363,6 +380,8 @@ type Rule interface { NotModuleType(types ...string) Rule + BootclasspathJar() Rule + With(properties, value string) Rule WithMatcher(properties string, matcher ValueMatcher) Rule @@ -390,6 +409,8 @@ type rule struct { props []ruleProperty unlessProps []ruleProperty + + onlyBootclasspathJar bool } // Create a new NeverAllow rule. @@ -465,6 +486,11 @@ func (r *rule) Because(reason string) Rule { return r } +func (r *rule) BootclasspathJar() Rule { + r.onlyBootclasspathJar = true + return r +} + func (r *rule) String() string { s := "neverallow" for _, v := range r.paths { @@ -491,6 +517,9 @@ func (r *rule) String() string { for _, v := range r.osClasses { s += " os:" + v.String() } + if r.onlyBootclasspathJar { + s += " inBcp" + } if len(r.reason) != 0 { s += " which is restricted because " + r.reason } @@ -519,6 +548,14 @@ func (r *rule) appliesToDirectDeps(ctx BottomUpMutatorContext) bool { return matches } +func (r *rule) appliesToBootclasspathJar(ctx BottomUpMutatorContext) bool { + if !r.onlyBootclasspathJar { + return true + } + + return InList(ctx.ModuleName(), ctx.Config().BootJars()) +} + func (r *rule) appliesToOsClass(osClass OsClass) bool { if len(r.osClasses) == 0 { return true @@ -555,6 +592,10 @@ func Regexp(re string) ValueMatcher { return ®exMatcher{r} } +func NotInList(allowed []string) ValueMatcher { + return ¬InListMatcher{allowed} +} + // assorted utils func cleanPaths(paths []string) []string { diff --git a/apex/androidmk.go b/apex/androidmk.go index 5c6d6ccfe..af2ec3d2a 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -108,6 +108,9 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) } fmt.Fprintln(w, "LOCAL_MODULE :=", moduleName) + if fi.module != nil && fi.module.Owner() != "" { + fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", fi.module.Owner()) + } // /apex//{lib|framework|...} pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir) var modulePath string diff --git a/apex/apex.go b/apex/apex.go index 0d8b960b5..1b995c3f2 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -98,6 +98,13 @@ func makeApexAvailableBaseline() map[string][]string { // // Module separator // + m["com.android.appsearch"] = []string{ + "icing-java-proto-lite", + "libprotobuf-java-lite", + } + // + // Module separator + // m["com.android.bluetooth.updatable"] = []string{ "android.hardware.audio.common@5.0", "android.hardware.bluetooth.a2dp@1.0", @@ -180,6 +187,19 @@ func makeApexAvailableBaseline() map[string][]string { // // Module separator // + m["com.android.extservices"] = []string{ + "error_prone_annotations", + "ExtServices-core", + "ExtServices", + "libtextclassifier-java", + "libz_current", + "textclassifier-statsd", + "TextClassifierNotificationLibNoManifest", + "TextClassifierServiceLibNoManifest", + } + // + // Module separator + // m["com.android.neuralnetworks"] = []string{ "android.hardware.neuralnetworks@1.0", "android.hardware.neuralnetworks@1.1", @@ -295,7 +315,6 @@ func makeApexAvailableBaseline() map[string][]string { "libpdx_headers", "libpdx_uds", "libprocinfo", - "libsonivox", "libspeexresampler", "libspeexresampler", "libstagefright_esds", @@ -332,6 +351,7 @@ func makeApexAvailableBaseline() map[string][]string { "android.hardware.configstore@1.1", "android.hardware.graphics.allocator@2.0", "android.hardware.graphics.allocator@3.0", + "android.hardware.graphics.allocator@4.0", "android.hardware.graphics.bufferqueue@1.0", "android.hardware.graphics.bufferqueue@2.0", "android.hardware.graphics.common-ndk_platform", @@ -344,6 +364,7 @@ func makeApexAvailableBaseline() map[string][]string { "android.hardware.graphics.mapper@4.0", "android.hardware.media.bufferpool@2.0", "android.hardware.media.c2@1.0", + "android.hardware.media.c2@1.1", "android.hardware.media.omx@1.0", "android.hardware.media@1.0", "android.hardware.media@1.0", @@ -437,6 +458,7 @@ func makeApexAvailableBaseline() map[string][]string { "libpdx_headers", "libscudo_wrapper", "libsfplugin_ccodec_utils", + "libspeexresampler", "libstagefright_amrnb_common", "libstagefright_amrnbdec", "libstagefright_amrnbenc", @@ -479,6 +501,8 @@ func makeApexAvailableBaseline() map[string][]string { // Module separator // m["com.android.permission"] = []string{ + "car-ui-lib", + "iconloader", "kotlin-annotations", "kotlin-stdlib", "kotlin-stdlib-jdk7", @@ -488,6 +512,17 @@ func makeApexAvailableBaseline() map[string][]string { "kotlinx-coroutines-core", "kotlinx-coroutines-core-nodeps", "permissioncontroller-statsd", + "GooglePermissionController", + "PermissionController", + "SettingsLibActionBarShadow", + "SettingsLibAppPreference", + "SettingsLibBarChartPreference", + "SettingsLibLayoutPreference", + "SettingsLibProgressBar", + "SettingsLibSearchWidget", + "SettingsLibSettingsTheme", + "SettingsLibRestrictedLockUtils", + "SettingsLibHelpUtils", } // // Module separator @@ -646,6 +681,55 @@ func makeApexAvailableBaseline() map[string][]string { return m } +// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART. +// Adding code to the bootclasspath in new packages will cause issues on module update. +func qModulesPackages() map[string][]string { + return map[string][]string{ + "com.android.conscrypt": []string{ + "android.net.ssl", + "com.android.org.conscrypt", + }, + "com.android.media": []string{ + "android.media", + }, + } +} + +// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART. +// Adding code to the bootclasspath in new packages will cause issues on module update. +func rModulesPackages() map[string][]string { + return map[string][]string{ + "com.android.mediaprovider": []string{ + "android.provider", + }, + "com.android.permission": []string{ + "android.permission", + "android.app.role", + "com.android.permission", + "com.android.role", + }, + "com.android.sdkext": []string{ + "android.os.ext", + }, + "com.android.os.statsd": []string{ + "android.app", + "android.os", + "android.util", + "com.android.internal.statsd", + "com.android.server.stats", + }, + "com.android.wifi": []string{ + "com.android.server.wifi", + "com.android.wifi.x", + "android.hardware.wifi", + "android.net.wifi", + }, + "com.android.tethering": []string{ + "android.net", + }, + } +} + func init() { android.RegisterModuleType("apex", BundleFactory) android.RegisterModuleType("apex_test", testApexBundleFactory) @@ -663,6 +747,24 @@ func init() { sort.Strings(*apexFileContextsInfos) ctx.Strict("APEX_FILE_CONTEXTS_INFOS", strings.Join(*apexFileContextsInfos, " ")) }) + + android.AddNeverAllowRules(createApexPermittedPackagesRules(qModulesPackages())...) + android.AddNeverAllowRules(createApexPermittedPackagesRules(rModulesPackages())...) +} + +func createApexPermittedPackagesRules(modules_packages map[string][]string) []android.Rule { + rules := make([]android.Rule, 0, len(modules_packages)) + for module_name, module_packages := range modules_packages { + permitted_packages_rule := android.NeverAllow(). + BootclasspathJar(). + With("apex_available", module_name). + WithMatcher("permitted_packages", android.NotInList(module_packages)). + Because("jars that are part of the " + module_name + + " module may only allow these packages: " + strings.Join(module_packages, ",") + + ". Please jarjar or move code around.") + rules = append(rules, permitted_packages_rule) + } + return rules } func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) { @@ -1963,13 +2065,6 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext return false } - // TODO(jiyong) remove this check when R is published to AOSP. Currently, libstatssocket - // is capable of providing a stub variant, but is being statically linked from the bluetooth - // APEX. - if toName == "libstatssocket" { - return false - } - // The dynamic linker and crash_dump tool in the runtime APEX is the only exception to this rule. // It can't make the static dependencies dynamic because it can't // do the dynamic linking for itself. diff --git a/apex/apex_test.go b/apex/apex_test.go index e9843fc1a..f7e02e338 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -5704,6 +5704,141 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) { }) } +func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJars []string, rules []android.Rule) { + t.Helper() + android.ClearApexDependency() + bp += ` + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + }` + fs := map[string][]byte{ + "lib1/src/A.java": nil, + "lib2/src/B.java": nil, + "system/sepolicy/apex/myapex-file_contexts": nil, + } + + ctx := android.NewTestArchContext() + ctx.RegisterModuleType("apex", BundleFactory) + ctx.RegisterModuleType("apex_key", ApexKeyFactory) + ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) + cc.RegisterRequiredBuildComponentsForTest(ctx) + java.RegisterJavaBuildComponents(ctx) + java.RegisterSystemModulesBuildComponents(ctx) + java.RegisterDexpreoptBootJarsComponents(ctx) + ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators) + ctx.PreDepsMutators(RegisterPreDepsMutators) + ctx.PostDepsMutators(RegisterPostDepsMutators) + ctx.PostDepsMutators(android.RegisterNeverallowMutator) + + config := android.TestArchConfig(buildDir, nil, bp, fs) + android.SetTestNeverallowRules(config, rules) + updatableBootJars := make([]string, 0, len(apexBootJars)) + for _, apexBootJar := range apexBootJars { + updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar) + } + config.TestProductVariables.UpdatableBootJars = updatableBootJars + + ctx.Register(config) + + _, errs := ctx.ParseBlueprintsFiles("Android.bp") + android.FailIfErrored(t, errs) + + _, errs = ctx.PrepareBuildActions(config) + if errmsg == "" { + android.FailIfErrored(t, errs) + } else if len(errs) > 0 { + android.FailIfNoMatchingErrors(t, errmsg, errs) + return + } else { + t.Fatalf("missing expected error %q (0 errors are returned)", errmsg) + } +} + +func TestApexPermittedPackagesRules(t *testing.T) { + testcases := []struct { + name string + expectedError string + bp string + bootJars []string + modulesPackages map[string][]string + }{ + + { + name: "Non-Bootclasspath apex jar not satisfying allowed module packages.", + expectedError: "", + bp: ` + java_library { + name: "bcp_lib1", + srcs: ["lib1/src/*.java"], + permitted_packages: ["foo.bar"], + apex_available: ["myapex"], + sdk_version: "none", + system_modules: "none", + } + java_library { + name: "nonbcp_lib2", + srcs: ["lib2/src/*.java"], + apex_available: ["myapex"], + permitted_packages: ["a.b"], + sdk_version: "none", + system_modules: "none", + } + apex { + name: "myapex", + key: "myapex.key", + java_libs: ["bcp_lib1", "nonbcp_lib2"], + }`, + bootJars: []string{"bcp_lib1"}, + modulesPackages: map[string][]string{ + "myapex": []string{ + "foo.bar", + }, + }, + }, + { + name: "Bootclasspath apex jar not satisfying allowed module packages.", + expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar. Please jarjar or move code around.`, + bp: ` + java_library { + name: "bcp_lib1", + srcs: ["lib1/src/*.java"], + apex_available: ["myapex"], + permitted_packages: ["foo.bar"], + sdk_version: "none", + system_modules: "none", + } + java_library { + name: "bcp_lib2", + srcs: ["lib2/src/*.java"], + apex_available: ["myapex"], + permitted_packages: ["foo.bar", "bar.baz"], + sdk_version: "none", + system_modules: "none", + } + apex { + name: "myapex", + key: "myapex.key", + java_libs: ["bcp_lib1", "bcp_lib2"], + } + `, + bootJars: []string{"bcp_lib1", "bcp_lib2"}, + modulesPackages: map[string][]string{ + "myapex": []string{ + "foo.bar", + }, + }, + }, + } + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + rules := createApexPermittedPackagesRules(tc.modulesPackages) + testApexPermittedPackagesRules(t, tc.expectedError, tc.bp, tc.bootJars, rules) + }) + } +} + func TestTestFor(t *testing.T) { ctx, _ := testApex(t, ` apex { @@ -5771,8 +5906,10 @@ func TestApexSet(t *testing.T) { } `, func(fs map[string][]byte, config android.Config) { config.TestProductVariables.Platform_sdk_version = intPtr(30) - config.TestProductVariables.DeviceArch = proptools.StringPtr("arm") - config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm64") + config.Targets[android.Android] = []android.Target{ + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}}, + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}}, + } }) m := ctx.ModuleForTests("myapex", "android_common") diff --git a/apex/builder.go b/apex/builder.go index 22cd69bf4..307142097 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -686,7 +686,7 @@ func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) { apexBundleName := a.Name() a.outputFile = android.PathForModuleInstall(&factx, "apex", apexBundleName) - if a.installable() && a.GetOverriddenBy() == "" { + if a.installable() { installPath := android.PathForModuleInstall(ctx, "apex", apexBundleName) devicePath := android.InstallPathToOnDevicePath(ctx, installPath) addFlattenedFileContextsInfos(ctx, apexBundleName+":"+devicePath+":"+a.fileContexts.String()) diff --git a/apex/prebuilt.go b/apex/prebuilt.go index d459f8755..37457e921 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -257,6 +257,9 @@ type ApexSet struct { // list of commands to create symlinks for backward compatibility. // these commands will be attached as LOCAL_POST_INSTALL_CMD compatSymlinks []string + + hostRequired []string + postInstallCommands []string } type ApexSetProperties struct { @@ -343,21 +346,43 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { for _, overridden := range a.properties.Overrides { a.compatSymlinks = append(a.compatSymlinks, makeCompatSymlinks(overridden, ctx)...) } + + if ctx.Config().InstallExtraFlattenedApexes() { + // flattened apex should be in /system_ext/apex + flattenedApexDir := android.PathForModuleInstall(&systemExtContext{ctx}, "apex", a.BaseModuleName()) + a.postInstallCommands = append(a.postInstallCommands, + fmt.Sprintf("$(HOST_OUT_EXECUTABLES)/deapexer --debugfs_path $(HOST_OUT_EXECUTABLES)/debugfs extract %s %s", + a.outputApex.String(), + flattenedApexDir.ToMakePath().String(), + )) + a.hostRequired = []string{"deapexer", "debugfs"} + } +} + +type systemExtContext struct { + android.ModuleContext +} + +func (*systemExtContext) SystemExtSpecific() bool { + return true } func (a *ApexSet) AndroidMkEntries() []android.AndroidMkEntries { return []android.AndroidMkEntries{android.AndroidMkEntries{ - Class: "ETC", - OutputFile: android.OptionalPathForPath(a.outputApex), - Include: "$(BUILD_PREBUILT)", + Class: "ETC", + OutputFile: android.OptionalPathForPath(a.outputApex), + Include: "$(BUILD_PREBUILT)", + Host_required: a.hostRequired, ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(entries *android.AndroidMkEntries) { entries.SetString("LOCAL_MODULE_PATH", a.installDir.ToMakePath().String()) entries.SetString("LOCAL_MODULE_STEM", a.installFilename) entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !a.installable()) entries.AddStrings("LOCAL_OVERRIDES_MODULES", a.properties.Overrides...) - if len(a.compatSymlinks) > 0 { - entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(a.compatSymlinks, " && ")) + postInstallCommands := append([]string{}, a.postInstallCommands...) + postInstallCommands = append(postInstallCommands, a.compatSymlinks...) + if len(postInstallCommands) > 0 { + entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(postInstallCommands, " && ")) } }, }, diff --git a/cc/config/vndk.go b/cc/config/vndk.go index 54f693e0b..6f2e80741 100644 --- a/cc/config/vndk.go +++ b/cc/config/vndk.go @@ -18,10 +18,12 @@ package config // For these libraries, the vendor variants must be installed even if the device // has VndkUseCoreVariant set. var VndkMustUseVendorVariantList = []string{ + "android.hardware.automotive.occupant_awareness-ndk_platform", "android.hardware.light-ndk_platform", "android.hardware.identity-ndk_platform", "android.hardware.nfc@1.2", "android.hardware.power-ndk_platform", + "android.hardware.rebootescrow-ndk_platform", "android.hardware.vibrator-ndk_platform", "libbinder", "libcrypto", diff --git a/cc/sanitize.go b/cc/sanitize.go index 2243082ad..418671fcd 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -48,6 +48,10 @@ var ( // higher number of "optimized out" stack variables. // b/112437883. "-mllvm", "-instcombine-lower-dbg-declare=0", + // TODO(b/159343917): HWASan and GlobalISel don't play nicely, and + // GlobalISel is the default at -O0 on aarch64. + "-mllvm", "--aarch64-enable-global-isel-at-O=-1", + "-mllvm", "-fast-isel=false", } cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso", diff --git a/java/app.go b/java/app.go index 34f96dd50..900f6a6d7 100755 --- a/java/app.go +++ b/java/app.go @@ -118,17 +118,17 @@ var TargetCpuAbi = map[string]string{ } func SupportedAbis(ctx android.ModuleContext) []string { - abiName := func(archVar string, deviceArch string) string { + abiName := func(targetIdx int, deviceArch string) string { if abi, found := TargetCpuAbi[deviceArch]; found { return abi } - ctx.ModuleErrorf("Invalid %s: %s", archVar, deviceArch) + ctx.ModuleErrorf("Target %d has invalid Arch: %s", targetIdx, deviceArch) return "BAD_ABI" } - result := []string{abiName("TARGET_ARCH", ctx.DeviceConfig().DeviceArch())} - if s := ctx.DeviceConfig().DeviceSecondaryArch(); s != "" { - result = append(result, abiName("TARGET_2ND_ARCH", s)) + var result []string + for i, target := range ctx.Config().Targets[android.Android] { + result = append(result, abiName(i, target.Arch.ArchType.String())) } return result } @@ -268,6 +268,9 @@ type overridableAppProperties struct { // the logging parent of this app. Logging_parent *string + + // Whether to rename the package in resources to the override name rather than the base name. Defaults to true. + Rename_resources_package *bool } // runtime_resource_overlay properties that can be overridden by override_runtime_resource_overlay @@ -507,10 +510,23 @@ func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool { !a.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs } +func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string { + aaptFlags := []string{"--rename-manifest-package " + packageName} + if renameResourcesPackage { + // Required to rename the package name in the resources table. + aaptFlags = append(aaptFlags, "--rename-resources-package "+packageName) + } + return aaptFlags +} + func (a *AndroidApp) OverriddenManifestPackageName() string { return a.overriddenManifestPackageName } +func (a *AndroidApp) renameResourcesPackage() bool { + return proptools.BoolDefault(a.overridableAppProperties.Rename_resources_package, true) +} + func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { a.aapt.usesNonSdkApis = Bool(a.Module.deviceProperties.Platform_apis) @@ -543,7 +559,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { if !overridden { manifestPackageName = *a.overridableAppProperties.Package_name } - aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName) + aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, a.renameResourcesPackage())...) a.overriddenManifestPackageName = manifestPackageName } @@ -803,18 +819,32 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { // Build a final signed app package. packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk") + v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature) + var v4SignatureFile android.WritablePath = nil + if v4SigningRequested { + v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig") + } var lineageFile android.Path if lineage := String(a.overridableAppProperties.Lineage); lineage != "" { lineageFile = android.PathForModuleSrc(ctx, lineage) } - CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, lineageFile) + CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile, lineageFile) a.outputFile = packageFile + if v4SigningRequested { + a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile) + } for _, split := range a.aapt.splits { // Sign the split APKs packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk") - CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, lineageFile) + if v4SigningRequested { + v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig") + } + CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile, lineageFile) a.extraOutputFiles = append(a.extraOutputFiles, packageFile) + if v4SigningRequested { + a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile) + } } // Build an app bundle. @@ -1533,7 +1563,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext if lineage := String(a.properties.Lineage); lineage != "" { lineageFile = android.PathForModuleSrc(ctx, lineage) } - SignAppPackage(ctx, signed, dexOutput, certificates, lineageFile) + SignAppPackage(ctx, signed, dexOutput, certificates, nil, lineageFile) a.outputFile = signed } else { alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename) @@ -1807,7 +1837,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC if !overridden { manifestPackageName = *r.overridableProperties.Package_name } - aaptLinkFlags = append(aaptLinkFlags, "--rename-manifest-package "+manifestPackageName) + aaptLinkFlags = append(aaptLinkFlags, generateAaptRenamePackageFlags(manifestPackageName, false)...) } if r.overridableProperties.Target_package_name != nil { aaptLinkFlags = append(aaptLinkFlags, @@ -1823,7 +1853,7 @@ func (r *RuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleC if lineage := String(r.properties.Lineage); lineage != "" { lineageFile = android.PathForModuleSrc(ctx, lineage) } - SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, lineageFile) + SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil, lineageFile) r.certificate = certificates[0] r.outputFile = signed diff --git a/java/app_builder.go b/java/app_builder.go index 014bd54f1..97ec269ee 100644 --- a/java/app_builder.go +++ b/java/app_builder.go @@ -52,7 +52,7 @@ var combineApk = pctx.AndroidStaticRule("combineApk", }) func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath, - packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, lineageFile android.Path) { + packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath, lineageFile android.Path) { unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk" unsignedApk := android.PathForModuleOut(ctx, unsignedApkName) @@ -73,10 +73,10 @@ func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.Writa Implicits: deps, }) - SignAppPackage(ctx, outputFile, unsignedApk, certificates, lineageFile) + SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile, lineageFile) } -func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate, lineageFile android.Path) { +func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate, v4SignatureFile android.WritablePath, lineageFile android.Path) { var certificateArgs []string var deps android.Paths @@ -87,6 +87,11 @@ func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, u outputFiles := android.WritablePaths{signedApk} var flags []string + if v4SignatureFile != nil { + outputFiles = append(outputFiles, v4SignatureFile) + flags = append(flags, "--enable-v4") + } + if lineageFile != nil { flags = append(flags, "--lineage", lineageFile.String()) deps = append(deps, lineageFile) diff --git a/java/app_test.go b/java/app_test.go index b8d8616f3..536797119 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -176,16 +176,17 @@ func TestAndroidAppSet_Variants(t *testing.T) { set: "prebuilts/apks/app.apks", }` testCases := []struct { - name string - deviceArch *string - deviceSecondaryArch *string - aaptPrebuiltDPI []string - sdkVersion int - expected map[string]string + name string + targets []android.Target + aaptPrebuiltDPI []string + sdkVersion int + expected map[string]string }{ { - name: "One", - deviceArch: proptools.StringPtr("x86"), + name: "One", + targets: []android.Target{ + {Os: android.Android, Arch: android.Arch{ArchType: android.X86}}, + }, aaptPrebuiltDPI: []string{"ldpi", "xxhdpi"}, sdkVersion: 29, expected: map[string]string{ @@ -197,11 +198,13 @@ func TestAndroidAppSet_Variants(t *testing.T) { }, }, { - name: "Two", - deviceArch: proptools.StringPtr("x86_64"), - deviceSecondaryArch: proptools.StringPtr("x86"), - aaptPrebuiltDPI: nil, - sdkVersion: 30, + name: "Two", + targets: []android.Target{ + {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64}}, + {Os: android.Android, Arch: android.Arch{ArchType: android.X86}}, + }, + aaptPrebuiltDPI: nil, + sdkVersion: 30, expected: map[string]string{ "abis": "X86_64,X86", "allow-prereleased": "false", @@ -216,8 +219,7 @@ func TestAndroidAppSet_Variants(t *testing.T) { config := testAppConfig(nil, bp, nil) config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI config.TestProductVariables.Platform_sdk_version = &test.sdkVersion - config.TestProductVariables.DeviceArch = test.deviceArch - config.TestProductVariables.DeviceSecondaryArch = test.deviceSecondaryArch + config.Targets[android.Android] = test.targets ctx := testContext() run(t, ctx, config) module := ctx.ModuleForTests("foo", "android_common") @@ -1655,6 +1657,66 @@ func TestCertificates(t *testing.T) { } } +func TestRequestV4SigningFlag(t *testing.T) { + testCases := []struct { + name string + bp string + expected string + }{ + { + name: "default", + bp: ` + android_app { + name: "foo", + srcs: ["a.java"], + sdk_version: "current", + } + `, + expected: "", + }, + { + name: "default", + bp: ` + android_app { + name: "foo", + srcs: ["a.java"], + sdk_version: "current", + v4_signature: false, + } + `, + expected: "", + }, + { + name: "module certificate property", + bp: ` + android_app { + name: "foo", + srcs: ["a.java"], + sdk_version: "current", + v4_signature: true, + } + `, + expected: "--enable-v4", + }, + } + + for _, test := range testCases { + t.Run(test.name, func(t *testing.T) { + config := testAppConfig(nil, test.bp, nil) + ctx := testContext() + + run(t, ctx, config) + foo := ctx.ModuleForTests("foo", "android_common") + + signapk := foo.Output("foo.apk") + signFlags := signapk.Args["flags"] + if test.expected != signFlags { + t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags) + } + }) + } +} + func TestPackageNameOverride(t *testing.T) { testCases := []struct { name string @@ -1777,52 +1839,125 @@ func TestOverrideAndroidApp(t *testing.T) { base: "foo", package_name: "org.dandroid.bp", } + + override_android_app { + name: "baz_no_rename_resources", + base: "foo", + package_name: "org.dandroid.bp", + rename_resources_package: false, + } + + android_app { + name: "foo_no_rename_resources", + srcs: ["a.java"], + certificate: "expiredkey", + overrides: ["qux"], + rename_resources_package: false, + sdk_version: "current", + } + + override_android_app { + name: "baz_base_no_rename_resources", + base: "foo_no_rename_resources", + package_name: "org.dandroid.bp", + } + + override_android_app { + name: "baz_override_base_rename_resources", + base: "foo_no_rename_resources", + package_name: "org.dandroid.bp", + rename_resources_package: true, + } `) expectedVariants := []struct { - moduleName string - variantName string - apkName string - apkPath string - certFlag string - lineageFlag string - overrides []string - aaptFlag string - logging_parent string + name string + moduleName string + variantName string + apkName string + apkPath string + certFlag string + lineageFlag string + overrides []string + packageFlag string + renameResources bool + logging_parent string }{ { - moduleName: "foo", - variantName: "android_common", - apkPath: "/target/product/test_device/system/app/foo/foo.apk", - certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", - lineageFlag: "", - overrides: []string{"qux"}, - aaptFlag: "", - logging_parent: "", + name: "foo", + moduleName: "foo", + variantName: "android_common", + apkPath: "/target/product/test_device/system/app/foo/foo.apk", + certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + lineageFlag: "", + overrides: []string{"qux"}, + packageFlag: "", + renameResources: false, + logging_parent: "", }, { - moduleName: "bar", - variantName: "android_common_bar", - apkPath: "/target/product/test_device/system/app/bar/bar.apk", - certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", - lineageFlag: "--lineage lineage.bin", - overrides: []string{"qux", "foo"}, - aaptFlag: "", - logging_parent: "bah", + name: "foo", + moduleName: "bar", + variantName: "android_common_bar", + apkPath: "/target/product/test_device/system/app/bar/bar.apk", + certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8", + lineageFlag: "--lineage lineage.bin", + overrides: []string{"qux", "foo"}, + packageFlag: "", + renameResources: false, + logging_parent: "bah", }, { - moduleName: "baz", - variantName: "android_common_baz", - apkPath: "/target/product/test_device/system/app/baz/baz.apk", - certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", - lineageFlag: "", - overrides: []string{"qux", "foo"}, - aaptFlag: "--rename-manifest-package org.dandroid.bp", - logging_parent: "", + name: "foo", + moduleName: "baz", + variantName: "android_common_baz", + apkPath: "/target/product/test_device/system/app/baz/baz.apk", + certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + lineageFlag: "", + overrides: []string{"qux", "foo"}, + packageFlag: "org.dandroid.bp", + renameResources: true, + logging_parent: "", + }, + { + name: "foo", + moduleName: "baz_no_rename_resources", + variantName: "android_common_baz_no_rename_resources", + apkPath: "/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk", + certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + lineageFlag: "", + overrides: []string{"qux", "foo"}, + packageFlag: "org.dandroid.bp", + renameResources: false, + logging_parent: "", + }, + { + name: "foo_no_rename_resources", + moduleName: "baz_base_no_rename_resources", + variantName: "android_common_baz_base_no_rename_resources", + apkPath: "/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk", + certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + lineageFlag: "", + overrides: []string{"qux", "foo_no_rename_resources"}, + packageFlag: "org.dandroid.bp", + renameResources: false, + logging_parent: "", + }, + { + name: "foo_no_rename_resources", + moduleName: "baz_override_base_rename_resources", + variantName: "android_common_baz_override_base_rename_resources", + apkPath: "/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk", + certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8", + lineageFlag: "", + overrides: []string{"qux", "foo_no_rename_resources"}, + packageFlag: "org.dandroid.bp", + renameResources: true, + logging_parent: "", }, } for _, expected := range expectedVariants { - variant := ctx.ModuleForTests("foo", expected.variantName) + variant := ctx.ModuleForTests(expected.name, expected.variantName) // Check the final apk name outputs := variant.AllOutputs() @@ -1868,9 +2003,12 @@ func TestOverrideAndroidApp(t *testing.T) { // Check the package renaming flag, if exists. res := variant.Output("package-res.apk") aapt2Flags := res.Args["flags"] - if !strings.Contains(aapt2Flags, expected.aaptFlag) { - t.Errorf("package renaming flag, %q is missing in aapt2 link flags, %q", expected.aaptFlag, aapt2Flags) + checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) + expectedPackage := expected.packageFlag + if !expected.renameResources { + expectedPackage = "" } + checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage) } } @@ -2007,6 +2145,7 @@ func TestOverrideAndroidTest(t *testing.T) { res := variant.Output("package-res.apk") aapt2Flags := res.Args["flags"] checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) + checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag) checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag) } } @@ -3131,6 +3270,65 @@ func TestRuntimeResourceOverlay(t *testing.T) { } } +func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) { + ctx, config := testJava(t, ` + java_defaults { + name: "rro_defaults", + theme: "default_theme", + product_specific: true, + aaptflags: ["--keep-raw-values"], + } + + runtime_resource_overlay { + name: "foo_with_defaults", + defaults: ["rro_defaults"], + } + + runtime_resource_overlay { + name: "foo_barebones", + } + `) + + // + // RRO module with defaults + // + m := ctx.ModuleForTests("foo_with_defaults", "android_common") + + // Check AAPT2 link flags. + aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ") + expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"} + absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags) + if len(absentFlags) > 0 { + t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags) + } + + // Check device location. + path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"] + expectedPath := []string{"/tmp/target/product/test_device/product/overlay/default_theme"} + if !reflect.DeepEqual(path, expectedPath) { + t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath) + } + + // + // RRO module without defaults + // + m = ctx.ModuleForTests("foo_barebones", "android_common") + + // Check AAPT2 link flags. + aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ") + unexpectedFlags := "--keep-raw-values" + if inList(unexpectedFlags, aapt2Flags) { + t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags) + } + + // Check device location. + path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"] + expectedPath = []string{"/tmp/target/product/test_device/system/overlay"} + if !reflect.DeepEqual(path, expectedPath) { + t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath) + } +} + func TestOverrideRuntimeResourceOverlay(t *testing.T) { ctx, _ := testJava(t, ` runtime_resource_overlay { @@ -3202,65 +3400,7 @@ func TestOverrideRuntimeResourceOverlay(t *testing.T) { res := variant.Output("package-res.apk") aapt2Flags := res.Args["flags"] checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag) + checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", "") checkAapt2LinkFlag(t, aapt2Flags, "rename-overlay-target-package", expected.targetPackageFlag) } } - -func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) { - ctx, config := testJava(t, ` - java_defaults { - name: "rro_defaults", - theme: "default_theme", - product_specific: true, - aaptflags: ["--keep-raw-values"], - } - - runtime_resource_overlay { - name: "foo_with_defaults", - defaults: ["rro_defaults"], - } - - runtime_resource_overlay { - name: "foo_barebones", - } - `) - - // - // RRO module with defaults - // - m := ctx.ModuleForTests("foo_with_defaults", "android_common") - - // Check AAPT2 link flags. - aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ") - expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"} - absentFlags := android.RemoveListFromList(expectedFlags, aapt2Flags) - if len(absentFlags) > 0 { - t.Errorf("expected values, %q are missing in aapt2 link flags, %q", absentFlags, aapt2Flags) - } - - // Check device location. - path := android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"] - expectedPath := []string{"/tmp/target/product/test_device/product/overlay/default_theme"} - if !reflect.DeepEqual(path, expectedPath) { - t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath) - } - - // - // RRO module without defaults - // - m = ctx.ModuleForTests("foo_barebones", "android_common") - - // Check AAPT2 link flags. - aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ") - unexpectedFlags := "--keep-raw-values" - if inList(unexpectedFlags, aapt2Flags) { - t.Errorf("unexpected value, %q is present in aapt2 link flags, %q", unexpectedFlags, aapt2Flags) - } - - // Check device location. - path = android.AndroidMkEntriesForTest(t, config, "", m.Module())[0].EntryMap["LOCAL_MODULE_PATH"] - expectedPath = []string{"/tmp/target/product/test_device/system/overlay"} - if !reflect.DeepEqual(path, expectedPath) { - t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath) - } -} diff --git a/java/config/config.go b/java/config/config.go index 05da3b54b..31e2b0ffe 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -41,6 +41,7 @@ var ( InstrumentFrameworkModules = []string{ "framework", + "framework-minus-apex", "telephony-common", "services", "android.car", @@ -51,6 +52,7 @@ var ( "core-libart", // TODO: Could this be all updatable bootclasspath jars? "updatable-media", + "framework-mediaprovider", "framework-sdkextensions", "android.net.ipsec.ike", } diff --git a/java/droiddoc.go b/java/droiddoc.go index 4c5f66c18..3b192ba55 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -1600,6 +1600,15 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt") cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint" + // TODO(b/154317059): Clean up this whitelist by baselining and/or checking in last-released. + if d.Name() != "android.car-system-stubs-docs" && + d.Name() != "android.car-stubs-docs" && + d.Name() != "system-api-stubs-docs" && + d.Name() != "test-api-stubs-docs" { + cmd.Flag("--lints-as-errors") + cmd.Flag("--warnings-as-errors") // Most lints are actually warnings. + } + baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file) updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt") d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp") diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index ea3fbdade..29b6bcd7d 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -207,6 +207,15 @@ func stubFlagsRule(ctx android.SingletonContext) { rule.Build(pctx, ctx, "hiddenAPIStubFlagsFile", "hiddenapi stub flags") } +func moduleForGreyListRemovedApis(ctx android.SingletonContext, module android.Module) bool { + switch ctx.ModuleName(module) { + case "api-stubs-docs", "system-api-stubs-docs", "android.car-stubs-docs", "android.car-system-stubs-docs": + return true + default: + return false + } +} + // flagsRule creates a rule to build hiddenapi-flags.csv out of flags.csv files generated for boot image modules and // the unsupported API. func flagsRule(ctx android.SingletonContext) android.Path { @@ -222,7 +231,7 @@ func flagsRule(ctx android.SingletonContext) android.Path { // Track @removed public and system APIs via corresponding droidstubs targets. // These APIs are not present in the stubs, however, we have to keep allowing access // to them at runtime. - if m := ctx.ModuleName(module); m == "api-stubs-docs" || m == "system-api-stubs-docs" { + if moduleForGreyListRemovedApis(ctx, module) { greylistRemovedApis = append(greylistRemovedApis, ds.removedDexApiFile) } } diff --git a/java/java.go b/java/java.go index 27e425dc1..79ad74a1f 100644 --- a/java/java.go +++ b/java/java.go @@ -324,6 +324,10 @@ type CompilerDeviceProperties struct { Stem *string IsSDKLibrary bool `blueprint:"mutated"` + + // If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file. + // Defaults to false. + V4_signature *bool } // Functionality common to Module and Import diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go index 8af66d098..021920af6 100644 --- a/java/legacy_core_platform_api_usage.go +++ b/java/legacy_core_platform_api_usage.go @@ -19,6 +19,10 @@ import ( "android/soong/java/config" ) +// This variable is effectively unused in pre-master branches, and is +// included (with the same value as it has in AOSP) only to ease +// merges between branches (see the comment in the +// useLegacyCorePlatformApi() function): var legacyCorePlatformApiModules = []string{ "ahat-test-dump", "android.car", @@ -132,6 +136,10 @@ var legacyCorePlatformApiModules = []string{ "wifi-service", } +// This variable is effectively unused in pre-master branches, and is +// included (with the same value as it has in AOSP) only to ease +// merges between branches (see the comment in the +// useLegacyCorePlatformApi() function): var legacyCorePlatformApiLookup = make(map[string]struct{}) func init() { @@ -141,8 +149,12 @@ func init() { } func useLegacyCorePlatformApi(ctx android.EarlyModuleContext) bool { - _, found := legacyCorePlatformApiLookup[ctx.ModuleName()] - return found + // In pre-master branches, we don't attempt to force usage of the stable + // version of the core/platform API. Instead, we always use the legacy + // version --- except in tests, where we always use stable, so that we + // can make the test assertions the same as other branches. + // This should be false in tests and true otherwise: + return ctx.Config().TestProductVariables == nil } func corePlatformSystemModules(ctx android.EarlyModuleContext) string { diff --git a/java/sdk_library.go b/java/sdk_library.go index a5db56c2b..30478a1fb 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -419,6 +419,9 @@ type sdkLibraryProperties struct { // $(location