From e16292761e6505e793bb2be1ae1e9527887e70ef Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 24 Apr 2019 14:41:12 -0700 Subject: [PATCH 01/12] Teach soong not to duplicate the HWASAN runtime into each APEX. When HWASAN is enabled, the runtime is conceptually part of Bionic (and mutually depends on it), so it needs to be treated in the same way as the Bionic libs. Now there are only two copies of the runtime: the one in /system/lib64/bootstrap (which won't be used by ordinary processes) and the one in the runtime APEX. This reduces the size of the HWASAN system image and fixes an issue where multiple copies of the HWASAN runtime were being loaded into 64-bit binaries in APEXes because the linker namespace for the binary is different from the one for its dependent libraries outside of APEXes. HWASAN only supports loading one copy of the runtime per process, so this was causing such binaries to crash on startup. Bug: http://b/134503977 Test: Builds Change-Id: I228896e193a035e6dfba9f6e28d0b2e12fc163ea Merged-In: I228896e193a035e6dfba9f6e28d0b2e12fc163ea (cherry picked from commit 3478bb2a7fbcaaea1326a1df4a564d7ca24056ce) --- apex/apex.go | 11 +++++++++++ cc/binary.go | 4 ++-- cc/cc.go | 10 ++++++++++ cc/library.go | 6 +++--- cc/makevars.go | 15 ++++++++++++++- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index fa4cb48ce..74a026796 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -521,6 +521,17 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { a.properties.Multilib.Prefer32.Binaries, target.String(), a.getImageVariation(config)) } + + if strings.HasPrefix(ctx.ModuleName(), "com.android.runtime") && target.Os.Class == android.Device { + for _, sanitizer := range ctx.Config().SanitizeDevice() { + if sanitizer == "hwaddress" { + addDependenciesForNativeModules(ctx, + []string{"libclang_rt.hwasan-aarch64-android"}, + nil, target.String(), a.getImageVariation(config)) + break + } + } + } } } diff --git a/cc/binary.go b/cc/binary.go index 35c3d85d1..cc4c8f900 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -440,8 +440,8 @@ func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) { // Bionic binaries (e.g. linker) is installed to the bootstrap subdirectory. // The original path becomes a symlink to the corresponding file in the // runtime APEX. - if isBionic(ctx.baseModuleName()) && ctx.Arch().Native && ctx.apexName() == "" && !ctx.inRecovery() { - if ctx.Device() { + if installToBootstrap(ctx.baseModuleName(), ctx.Config()) && ctx.Arch().Native && ctx.apexName() == "" && !ctx.inRecovery() { + if ctx.Device() && isBionic(ctx.baseModuleName()) { binary.installSymlinkToRuntimeApex(ctx, file) } binary.baseInstaller.subDir = "bootstrap" diff --git a/cc/cc.go b/cc/cc.go index 0668fd9aa..0089dc71c 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -596,6 +596,9 @@ func (c *Module) HasStubsVariants() bool { if library, ok := c.linker.(*libraryDecorator); ok { return len(library.Properties.Stubs.Versions) > 0 } + if library, ok := c.linker.(*prebuiltLibraryLinker); ok { + return len(library.Properties.Stubs.Versions) > 0 + } return false } @@ -615,6 +618,13 @@ func isBionic(name string) bool { return false } +func installToBootstrap(name string, config android.Config) bool { + if name == "libclang_rt.hwasan-aarch64-android" { + return inList("hwaddress", config.SanitizeDevice()) + } + return isBionic(name) +} + type baseModuleContext struct { android.BaseContext moduleContextImpl diff --git a/cc/library.go b/cc/library.go index ca1c1be04..d8eb5b4e5 100644 --- a/cc/library.go +++ b/cc/library.go @@ -934,12 +934,12 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { library.baseInstaller.subDir += "-" + vndkVersion } } - } else if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx, ctx.ModuleName()) { + } else if len(library.Properties.Stubs.Versions) > 0 { // Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory. // The original path becomes a symlink to the corresponding file in the // runtime APEX. - if isBionic(ctx.baseModuleName()) && !library.buildStubs() && ctx.Arch().Native && !ctx.inRecovery() { - if ctx.Device() { + if installToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && ctx.Arch().Native && !ctx.inRecovery() { + if ctx.Device() && isBionic(ctx.baseModuleName()) { library.installSymlinkToRuntimeApex(ctx, file) } library.baseInstaller.subDir = "bootstrap" diff --git a/cc/makevars.go b/cc/makevars.go index aa6fdea56..b03e170f3 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -95,7 +95,20 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(vndkCoreLibraries, " ")) ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(vndkSpLibraries, " ")) - ctx.Strict("LLNDK_LIBRARIES", strings.Join(llndkLibraries, " ")) + + // Make uses LLNDK_LIBRARIES to determine which libraries to install. + // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN. + // Therefore, by removing the library here, we cause it to only be installed if libc + // depends on it. + installedLlndkLibraries := []string{} + for _, lib := range llndkLibraries { + if strings.HasPrefix(lib, "libclang_rt.hwasan-") { + continue + } + installedLlndkLibraries = append(installedLlndkLibraries, lib) + } + ctx.Strict("LLNDK_LIBRARIES", strings.Join(installedLlndkLibraries, " ")) + ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(vndkPrivateLibraries, " ")) ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(vndkUsingCoreVariantLibraries, " ")) From 18af090842f0d3e47b7595d48b540bbb07c0d167 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Thu, 27 Jun 2019 14:08:51 +0100 Subject: [PATCH 02/12] Allow neverallow rules to be defined by custom bootstrap_go_packages * Adds a Rule interface to hide the rule struct and expose the mutator functions. * Makes the neverallow() function public as NeverAllow(). * Adds AddNeverAllowRules func to add more rules. * Moves the population of the builtin rules to init() function. Bug: 136159343 Test: m droid - changed a built in rule to cause build failure to ensure the rules were still being applied, then reverted the change and ran 'm droid' again. Change-Id: Ie3a4456d1f6bc12c5b4931bf698333275347fdf0 --- android/neverallow.go | 138 ++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 58 deletions(-) diff --git a/android/neverallow.go b/android/neverallow.go index 208207b03..af9167667 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -31,62 +31,65 @@ import ( // work regardless of these restrictions. // // A module is disallowed if all of the following are true: -// - it is in one of the "in" paths -// - it is not in one of the "notIn" paths -// - it has all "with" properties matched +// - it is in one of the "In" paths +// - it is not in one of the "NotIn" paths +// - it has all "With" properties matched // - - values are matched in their entirety // - - nil is interpreted as an empty string // - - nested properties are separated with a '.' // - - if the property is a list, any of the values in the list being matches // counts as a match -// - it has none of the "without" properties matched (same rules as above) +// - it has none of the "Without" properties matched (same rules as above) func registerNeverallowMutator(ctx RegisterMutatorsContext) { ctx.BottomUp("neverallow", neverallowMutator).Parallel() } -var neverallows = createNeverAllows() +var neverallows = []Rule{} -func createNeverAllows() []*rule { - rules := []*rule{} - rules = append(rules, createTrebleRules()...) - rules = append(rules, createLibcoreRules()...) - rules = append(rules, createMediaRules()...) - rules = append(rules, createJavaDeviceForHostRules()...) - return rules +func init() { + AddNeverAllowRules(createTrebleRules()...) + AddNeverAllowRules(createLibcoreRules()...) + AddNeverAllowRules(createMediaRules()...) + AddNeverAllowRules(createJavaDeviceForHostRules()...) } -func createTrebleRules() []*rule { - return []*rule{ - neverallow(). - in("vendor", "device"). - with("vndk.enabled", "true"). - without("vendor", "true"). - because("the VNDK can never contain a library that is device dependent."), - neverallow(). - with("vndk.enabled", "true"). - without("vendor", "true"). - without("owner", ""). - because("a VNDK module can never have an owner."), +// Add a NeverAllow rule to the set of rules to apply. +func AddNeverAllowRules(rules ...Rule) { + neverallows = append(neverallows, rules...) +} + +func createTrebleRules() []Rule { + return []Rule{ + NeverAllow(). + In("vendor", "device"). + With("vndk.enabled", "true"). + Without("vendor", "true"). + Because("the VNDK can never contain a library that is device dependent."), + NeverAllow(). + With("vndk.enabled", "true"). + Without("vendor", "true"). + Without("owner", ""). + Because("a VNDK module can never have an owner."), // TODO(b/67974785): always enforce the manifest - neverallow(). - without("name", "libhidltransport-impl-internal"). - with("product_variables.enforce_vintf_manifest.cflags", "*"). - because("manifest enforcement should be independent of ."), + NeverAllow(). + Without("name", "libhidltransport-impl-internal"). + With("product_variables.enforce_vintf_manifest.cflags", "*"). + Because("manifest enforcement should be independent of ."), // TODO(b/67975799): vendor code should always use /vendor/bin/sh - neverallow(). - without("name", "libc_bionic_ndk"). - with("product_variables.treble_linker_namespaces.cflags", "*"). - because("nothing should care if linker namespaces are enabled or not"), + NeverAllow(). + Without("name", "libc_bionic_ndk"). + With("product_variables.treble_linker_namespaces.cflags", "*"). + Because("nothing should care if linker namespaces are enabled or not"), // Example: - // *neverallow().with("Srcs", "main.cpp")) + // *NeverAllow().with("Srcs", "main.cpp")) } } -func createLibcoreRules() []*rule { +func createLibcoreRules() []Rule { var coreLibraryProjects = []string{ "libcore", "external/apache-harmony", @@ -103,35 +106,35 @@ func createLibcoreRules() []*rule { // Core library constraints. The sdk_version: "none" can only be used in core library projects. // Access to core library targets is restricted using visibility rules. - rules := []*rule{ - neverallow(). - notIn(coreLibraryProjects...). - with("sdk_version", "none"), + rules := []Rule{ + NeverAllow(). + NotIn(coreLibraryProjects...). + With("sdk_version", "none"), } return rules } -func createMediaRules() []*rule { - return []*rule{ - neverallow(). - with("libs", "updatable-media"). - because("updatable-media includes private APIs. Use updatable_media_stubs instead."), +func createMediaRules() []Rule { + return []Rule{ + NeverAllow(). + With("libs", "updatable-media"). + Because("updatable-media includes private APIs. Use updatable_media_stubs instead."), } } -func createJavaDeviceForHostRules() []*rule { +func createJavaDeviceForHostRules() []Rule { javaDeviceForHostProjectsWhitelist := []string{ "external/guava", "external/robolectric-shadows", "framework/layoutlib", } - return []*rule{ - neverallow(). - notIn(javaDeviceForHostProjectsWhitelist...). - moduleType("java_device_for_host", "java_host_for_device"). - because("java_device_for_host can only be used in whitelisted projects"), + return []Rule{ + NeverAllow(). + NotIn(javaDeviceForHostProjectsWhitelist...). + ModuleType("java_device_for_host", "java_host_for_device"). + Because("java_device_for_host can only be used in whitelisted projects"), } } @@ -144,7 +147,8 @@ func neverallowMutator(ctx BottomUpMutatorContext) { dir := ctx.ModuleDir() + "/" properties := m.GetProperties() - for _, n := range neverallows { + for _, r := range neverallows { + n := r.(*rule) if !n.appliesToPath(dir) { continue } @@ -166,6 +170,23 @@ type ruleProperty struct { value string // e.x.: true } +// A NeverAllow rule. +type Rule interface { + In(path ...string) Rule + + NotIn(path ...string) Rule + + ModuleType(types ...string) Rule + + NotModuleType(types ...string) Rule + + With(properties, value string) Rule + + Without(properties, value string) Rule + + Because(reason string) Rule +} + type rule struct { // User string for why this is a thing. reason string @@ -180,31 +201,32 @@ type rule struct { unlessProps []ruleProperty } -func neverallow() *rule { +// Create a new NeverAllow rule. +func NeverAllow() Rule { return &rule{} } -func (r *rule) in(path ...string) *rule { +func (r *rule) In(path ...string) Rule { r.paths = append(r.paths, cleanPaths(path)...) return r } -func (r *rule) notIn(path ...string) *rule { +func (r *rule) NotIn(path ...string) Rule { r.unlessPaths = append(r.unlessPaths, cleanPaths(path)...) return r } -func (r *rule) moduleType(types ...string) *rule { +func (r *rule) ModuleType(types ...string) Rule { r.moduleTypes = append(r.moduleTypes, types...) return r } -func (r *rule) notModuleType(types ...string) *rule { +func (r *rule) NotModuleType(types ...string) Rule { r.unlessModuleTypes = append(r.unlessModuleTypes, types...) return r } -func (r *rule) with(properties, value string) *rule { +func (r *rule) With(properties, value string) Rule { r.props = append(r.props, ruleProperty{ fields: fieldNamesForProperties(properties), value: value, @@ -212,7 +234,7 @@ func (r *rule) with(properties, value string) *rule { return r } -func (r *rule) without(properties, value string) *rule { +func (r *rule) Without(properties, value string) Rule { r.unlessProps = append(r.unlessProps, ruleProperty{ fields: fieldNamesForProperties(properties), value: value, @@ -220,7 +242,7 @@ func (r *rule) without(properties, value string) *rule { return r } -func (r *rule) because(reason string) *rule { +func (r *rule) Because(reason string) Rule { r.reason = reason return r } From 3b98a509f19cb25e9734bb62ba0b592663ed8e4e Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Thu, 11 Jul 2019 11:24:41 +0900 Subject: [PATCH 03/12] Don't use APEX prebuilts when asan is on Some prebuilt APEXes are enabled with scudo, which causes crash on devices with asan. Bug: 137216042 Test: build walleye_hwasan and check if apexes are not from prebuilts Change-Id: Ic436ad06e724af952d99fb8e66358a595450eb84 --- apex/apex.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index 3726684c9..04b667f85 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1327,10 +1327,16 @@ func (p *Prebuilt) installable() bool { } func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { - if ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild() && p.prebuilt.SourceExists() { - // If the device is configured to use flattened APEX, don't set - // p.properties.Source so that the prebuilt module (which is - // a non-flattened APEX) is not used. + // If the device is configured to use flattened APEX, don't set + // p.properties.Source so that the prebuilt module (which is + // a non-flattened APEX) is not used. + forceDisable := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild() + + // b/137216042 don't use prebuilts when address sanitizer is on + forceDisable = forceDisable || android.InList("address", ctx.Config().SanitizeDevice()) || + android.InList("hwaddress", ctx.Config().SanitizeDevice()) + + if forceDisable && p.prebuilt.SourceExists() { p.properties.ForceDisable = true return } From 716828ab4ec2a673e6022171bb2b52584ee8e916 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 15 Jul 2019 15:29:23 +0900 Subject: [PATCH 04/12] Revert "Don't build hiddenapi flags or encode dex for unbundled builds" This reverts commit 7b8a567f44b3fdb30eac8211e8ed8e27fb162797. Bug: 137282010 Test: With the CL above this one, the unbundled mainline module build does not fail. Merged-In: I2f49fa7dbe1da92cb282a9bc14acd5830888ed17 Change-Id: I2f49fa7dbe1da92cb282a9bc14acd5830888ed17 --- java/hiddenapi_singleton.go | 2 +- java/java.go | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index b1ddab48d..9627dc64b 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -61,7 +61,7 @@ func (h *hiddenAPISingleton) GenerateBuildActions(ctx android.SingletonContext) stubFlagsRule(ctx) // These rules depend on files located in frameworks/base, skip them if running in a tree that doesn't have them. - if ctx.Config().FrameworksBaseDirExists(ctx) && !ctx.Config().UnbundledBuild() { + if ctx.Config().FrameworksBaseDirExists(ctx) { h.flags = flagsRule(ctx) h.metadata = metadataRule(ctx) } else { diff --git a/java/java.go b/java/java.go index ff6bbacc5..bf738c4d3 100644 --- a/java/java.go +++ b/java/java.go @@ -1270,11 +1270,9 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path return } - if !ctx.Config().UnbundledBuild() { - // Hidden API CSV generation and dex encoding - dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile, - j.deviceProperties.UncompressDex) - } + // Hidden API CSV generation and dex encoding + dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile, + j.deviceProperties.UncompressDex) // merge dex jar with resources if necessary if j.resourceJar != nil { From 53554e25593d6498a229d1dc89208aade4137008 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 15 Jul 2019 15:31:16 +0900 Subject: [PATCH 05/12] Fix the unbundled mainline module build This change fixes two problems: 1) the prebuilt apexes are force disabled for the unbundled builds because we need to build the modules from the source then 2) the dependencies from an sdk_library module to *.stubs.{public|system|tests} are not added for the unbundled build because the stubs modules are disabled. Bug: 137282010 Test: unbundled mainline builds are successful Test: build com.android.media and inspect the jar file to see if hiddenapi flags are there $ cd out/dist/mainline_modules_arm $ unzip com.android.media.apex apex_payload.img $ mkdir -p mnt $ sudo mount -o ro,loop apex_payload.img mnt $ dexdump2 mnt/javalib/updatable-media.jar | grep hiddenapi shows results Merged-In: I2c00af07aac4a15770d3acab011a36e2e4803bfc Change-Id: I2c00af07aac4a15770d3acab011a36e2e4803bfc --- apex/apex.go | 11 +++++++---- java/hiddenapi_singleton.go | 2 +- java/sdk_library.go | 11 ++++++++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index 04b667f85..e5e586010 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1327,10 +1327,13 @@ func (p *Prebuilt) installable() bool { } func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) { - // If the device is configured to use flattened APEX, don't set - // p.properties.Source so that the prebuilt module (which is - // a non-flattened APEX) is not used. - forceDisable := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild() + // If the device is configured to use flattened APEX, force disable the prebuilt because + // the prebuilt is a non-flattened one. + forceDisable := ctx.Config().FlattenApex() + + // Force disable the prebuilts when we are doing unbundled build. We do unbundled build + // to build the prebuilts themselves. + forceDisable = forceDisable || !ctx.Config().UnbundledBuild() // b/137216042 don't use prebuilts when address sanitizer is on forceDisable = forceDisable || android.InList("address", ctx.Config().SanitizeDevice()) || diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index 9627dc64b..09936ea78 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -94,7 +94,7 @@ func stubFlagsRule(ctx android.SingletonContext) { // Add the android.test.base to the set of stubs only if the android.test.base module is on // the boot jars list as the runtime will only enforce hiddenapi access against modules on // that list. - if inList("android.test.base", ctx.Config().BootJars()) { + if inList("android.test.base", ctx.Config().BootJars()) && !ctx.Config().UnbundledBuildUsePrebuiltSdks() { publicStubModules = append(publicStubModules, "android.test.base.stubs") } diff --git a/java/sdk_library.go b/java/sdk_library.go index 974131cf9..84be4dda9 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -162,15 +162,20 @@ var _ Dependency = (*SdkLibrary)(nil) var _ SdkLibraryDependency = (*SdkLibrary)(nil) func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { + useBuiltStubs := !ctx.Config().UnbundledBuildUsePrebuiltSdks() // Add dependencies to the stubs library - ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic)) + if useBuiltStubs { + ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic)) + } ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic)) if !Bool(module.properties.No_standard_libs) { - ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem)) + if useBuiltStubs { + ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem)) + ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest)) + } ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem)) ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest)) - ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest)) } module.Library.deps(ctx) From 40c0afeb7c6606eeb74285f6cdaa956743f3a0cd Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Thu, 6 Jun 2019 16:23:32 -0700 Subject: [PATCH 06/12] Support require_root in auto-gen test configs require_root is added to allow auto-generated test config to include RootTargetPreparer so the test runs with root permission. Bug: 134509111 Bug: 136633978 Test: add "require_root: true" to init_benchmarks and libpower_test build the modules, confirm the extra target preparer is added in the test configs. Change-Id: Ia07503e338935d6aa92560e7cf7b18d2a4c51243 Merged-In: Ia07503e338935d6aa92560e7cf7b18d2a4c51243 --- cc/test.go | 29 ++++++++++++++------ tradefed/autogen.go | 65 ++++++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 32 deletions(-) diff --git a/cc/test.go b/cc/test.go index dae2a3774..c735fd91f 100644 --- a/cc/test.go +++ b/cc/test.go @@ -64,6 +64,10 @@ type TestBinaryProperties struct { // Test options. Test_options TestOptions + + // Add RootTargetPreparer to auto generated test config. This guarantees the test to run + // with root permission. + Require_root *bool } func init() { @@ -273,18 +277,19 @@ func (test *testBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags { func (test *testBinary) install(ctx ModuleContext, file android.Path) { test.data = android.PathsForModuleSrc(ctx, test.Properties.Data) - optionsMap := map[string]string{} - if Bool(test.testDecorator.Properties.Isolated) { - optionsMap["not-shardable"] = "true" + var configs []tradefed.Config + if Bool(test.Properties.Require_root) { + configs = append(configs, tradefed.Preparer{"com.android.tradefed.targetprep.RootTargetPreparer"}) + } + if Bool(test.testDecorator.Properties.Isolated) { + configs = append(configs, tradefed.Option{"not-shardable", "true"}) } - if test.Properties.Test_options.Run_test_as != nil { - optionsMap["run-test-as"] = String(test.Properties.Test_options.Run_test_as) + configs = append(configs, tradefed.Option{"run-test-as", String(test.Properties.Test_options.Run_test_as)}) } test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config, - test.Properties.Test_config_template, - test.Properties.Test_suites, optionsMap) + test.Properties.Test_config_template, test.Properties.Test_suites, configs) test.binaryDecorator.baseInstaller.dir = "nativetest" test.binaryDecorator.baseInstaller.dir64 = "nativetest64" @@ -371,6 +376,10 @@ type BenchmarkProperties struct { // the name of the test configuration template (for example "AndroidTestTemplate.xml") that // should be installed with the module. Test_config_template *string `android:"path,arch_variant"` + + // Add RootTargetPreparer to auto generated test config. This guarantees the test to run + // with root permission. + Require_root *bool } type benchmarkDecorator struct { @@ -403,8 +412,12 @@ func (benchmark *benchmarkDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Path) { benchmark.data = android.PathsForModuleSrc(ctx, benchmark.Properties.Data) + var configs []tradefed.Config + if Bool(benchmark.Properties.Require_root) { + configs = append(configs, tradefed.Preparer{"com.android.tradefed.targetprep.RootTargetPreparer"}) + } benchmark.testConfig = tradefed.AutoGenNativeBenchmarkTestConfig(ctx, benchmark.Properties.Test_config, - benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites) + benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites, configs) benchmark.binaryDecorator.baseInstaller.dir = filepath.Join("benchmarktest", ctx.ModuleName()) benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName()) diff --git a/tradefed/autogen.go b/tradefed/autogen.go index da5dabe6d..952b02236 100644 --- a/tradefed/autogen.go +++ b/tradefed/autogen.go @@ -16,7 +16,6 @@ package tradefed import ( "fmt" - "sort" "strings" "github.com/google/blueprint" @@ -39,9 +38,9 @@ func getTestConfig(ctx android.ModuleContext, prop *string) android.Path { } var autogenTestConfig = pctx.StaticRule("autogenTestConfig", blueprint.RuleParams{ - Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_OPTIONS}&'${extraOptions}'&g' $template > $out", + Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_CONFIGS}&'${extraConfigs}'&g' $template > $out", CommandDeps: []string{"$template"}, -}, "name", "template", "extraOptions") +}, "name", "template", "extraConfigs") func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string) (path android.Path, autogenPath android.WritablePath) { if p := getTestConfig(ctx, prop); p != nil { @@ -57,17 +56,38 @@ func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string } } -func autogenTemplate(ctx android.ModuleContext, output android.WritablePath, template string, optionsMap map[string]string) { - // If no test option found, delete {EXTRA_OPTIONS} line. - var options []string - for optionName, value := range optionsMap { - if value != "" { - options = append(options, fmt.Sprintf(`