blob: bb136cf6e790b796fe0d6ea11ce7837c57d8ff99 [file] [log] [blame]
Makoto Onuki4a9869d2023-10-20 10:42:47 -07001// Copyright 2023 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package java
15
16import (
17 "android/soong/android"
18 "android/soong/tradefed"
19
Makoto Onuki2ca84272024-02-10 00:15:21 +000020 "github.com/google/blueprint"
Makoto Onuki4a9869d2023-10-20 10:42:47 -070021 "github.com/google/blueprint/proptools"
22)
23
24func init() {
25 RegisterRavenwoodBuildComponents(android.InitRegistrationContext)
26}
27
28func RegisterRavenwoodBuildComponents(ctx android.RegistrationContext) {
29 ctx.RegisterModuleType("android_ravenwood_test", ravenwoodTestFactory)
30 ctx.RegisterModuleType("android_ravenwood_libgroup", ravenwoodLibgroupFactory)
31}
32
Makoto Onuki2ca84272024-02-10 00:15:21 +000033var ravenwoodLibContentTag = dependencyTag{name: "ravenwoodlibcontent"}
34var ravenwoodUtilsTag = dependencyTag{name: "ravenwoodutils"}
35var ravenwoodRuntimeTag = dependencyTag{name: "ravenwoodruntime"}
Makoto Onuki3380f6d2024-05-10 16:00:28 -070036var ravenwoodDataTag = dependencyTag{name: "ravenwooddata"}
37var ravenwoodTestResourceApkTag = dependencyTag{name: "ravenwoodtestresapk"}
Makoto Onuki4a9869d2023-10-20 10:42:47 -070038
39const ravenwoodUtilsName = "ravenwood-utils"
40const ravenwoodRuntimeName = "ravenwood-runtime"
41
Makoto Onuki2ca84272024-02-10 00:15:21 +000042type ravenwoodLibgroupJniDepProviderInfo struct {
43 // All the jni_libs module names with transient dependencies.
44 names map[string]bool
45}
46
47var ravenwoodLibgroupJniDepProvider = blueprint.NewProvider[ravenwoodLibgroupJniDepProviderInfo]()
48
Makoto Onuki68676572024-02-02 13:29:01 -080049func getLibPath(archType android.ArchType) string {
50 if archType.Multilib == "lib64" {
51 return "lib64"
52 }
53 return "lib"
54}
55
56type ravenwoodTestProperties struct {
57 Jni_libs []string
Makoto Onuki3380f6d2024-05-10 16:00:28 -070058
59 // Specify another android_app module here to copy it to the test directory, so that
60 // the ravenwood test can access it.
61 // TODO: For now, we simply refer to another android_app module and copy it to the
62 // test directory. Eventually, android_ravenwood_test should support all the resource
63 // related properties and build resources from the `res/` directory.
64 Resource_apk *string
Makoto Onuki68676572024-02-02 13:29:01 -080065}
66
Makoto Onuki4a9869d2023-10-20 10:42:47 -070067type ravenwoodTest struct {
68 Library
69
Makoto Onuki68676572024-02-02 13:29:01 -080070 ravenwoodTestProperties ravenwoodTestProperties
71
Makoto Onuki4a9869d2023-10-20 10:42:47 -070072 testProperties testProperties
73 testConfig android.Path
74
75 forceOSType android.OsType
76 forceArchType android.ArchType
77}
78
79func ravenwoodTestFactory() android.Module {
80 module := &ravenwoodTest{}
81
82 module.addHostAndDeviceProperties()
Makoto Onuki68676572024-02-02 13:29:01 -080083 module.AddProperties(&module.testProperties, &module.ravenwoodTestProperties)
Makoto Onuki4a9869d2023-10-20 10:42:47 -070084
85 module.Module.dexpreopter.isTest = true
86 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
87
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -070088 module.testProperties.Test_suites = []string{
89 "general-tests",
90 "ravenwood-tests",
91 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -070092 module.testProperties.Test_options.Unit_test = proptools.BoolPtr(false)
93
94 InitJavaModule(module, android.DeviceSupported)
95 android.InitDefaultableModule(module)
96
97 return module
98}
99
100func (r *ravenwoodTest) InstallInTestcases() bool { return true }
101func (r *ravenwoodTest) InstallForceOS() (*android.OsType, *android.ArchType) {
102 return &r.forceOSType, &r.forceArchType
103}
104func (r *ravenwoodTest) TestSuites() []string {
105 return r.testProperties.Test_suites
106}
107
108func (r *ravenwoodTest) DepsMutator(ctx android.BottomUpMutatorContext) {
109 r.Library.DepsMutator(ctx)
110
111 // Generically depend on the runtime so that it's installed together with us
Makoto Onuki2ca84272024-02-10 00:15:21 +0000112 ctx.AddVariationDependencies(nil, ravenwoodRuntimeTag, ravenwoodRuntimeName)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700113
114 // Directly depend on any utils so that we link against them
Makoto Onuki2ca84272024-02-10 00:15:21 +0000115 utils := ctx.AddVariationDependencies(nil, ravenwoodUtilsTag, ravenwoodUtilsName)[0]
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700116 if utils != nil {
117 for _, lib := range utils.(*ravenwoodLibgroup).ravenwoodLibgroupProperties.Libs {
118 ctx.AddVariationDependencies(nil, libTag, lib)
119 }
120 }
Makoto Onuki68676572024-02-02 13:29:01 -0800121
122 // Add jni libs
123 for _, lib := range r.ravenwoodTestProperties.Jni_libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000124 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800125 }
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700126
127 // Resources APK
128 if resourceApk := proptools.String(r.ravenwoodTestProperties.Resource_apk); resourceApk != "" {
129 ctx.AddVariationDependencies(nil, ravenwoodTestResourceApkTag, resourceApk)
130 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700131}
132
133func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
134 r.forceOSType = ctx.Config().BuildOS
135 r.forceArchType = ctx.Config().BuildArch
136
137 r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
138 TestConfigProp: r.testProperties.Test_config,
139 TestConfigTemplateProp: r.testProperties.Test_config_template,
140 TestSuites: r.testProperties.Test_suites,
141 AutoGenConfig: r.testProperties.Auto_gen_config,
142 DeviceTemplate: "${RavenwoodTestConfigTemplate}",
143 HostTemplate: "${RavenwoodTestConfigTemplate}",
144 })
145
Makoto Onuki7ded3822024-03-28 14:42:20 -0700146 // Always enable Ravenizer for ravenwood tests.
147 r.Library.ravenizer.enabled = true
148
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700149 r.Library.GenerateAndroidBuildActions(ctx)
150
Makoto Onuki2ca84272024-02-10 00:15:21 +0000151 // Start by depending on all files installed by dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700152 var installDeps android.InstallPaths
Makoto Onuki2ca84272024-02-10 00:15:21 +0000153
154 // All JNI libraries included in the runtime
155 var runtimeJniModuleNames map[string]bool
156
157 if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
Yu Liud46e5ae2024-08-15 18:46:17 +0000158 for _, installFile := range android.OtherModuleProviderOrDefault(
159 ctx, utils, android.InstallFilesProvider).InstallFiles {
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700160 installDeps = append(installDeps, installFile)
161 }
Makoto Onuki2ca84272024-02-10 00:15:21 +0000162 jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
163 if ok {
164 runtimeJniModuleNames = jniDeps.names
165 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700166 }
167
Makoto Onuki2ca84272024-02-10 00:15:21 +0000168 if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
Yu Liud46e5ae2024-08-15 18:46:17 +0000169 for _, installFile := range android.OtherModuleProviderOrDefault(
170 ctx, runtime, android.InstallFilesProvider).InstallFiles {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000171 installDeps = append(installDeps, installFile)
172 }
173 jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
174 if ok {
175 runtimeJniModuleNames = jniDeps.names
176 }
177 }
178
179 // Also remember what JNI libs are in the runtime.
180
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700181 // Also depend on our config
182 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
183 installConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
184 installDeps = append(installDeps, installConfig)
185
Makoto Onuki2ca84272024-02-10 00:15:21 +0000186 // Depend on the JNI libraries, but don't install the ones that the runtime already
187 // contains.
Makoto Onuki68676572024-02-02 13:29:01 -0800188 soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000189 for _, jniLib := range collectTransitiveJniDeps(ctx) {
190 if _, ok := runtimeJniModuleNames[jniLib.name]; ok {
191 continue // Runtime already includes it.
192 }
193 installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800194 installDeps = append(installDeps, installJni)
195 }
196
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700197 resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
198 if resApk := ctx.GetDirectDepsWithTag(ravenwoodTestResourceApkTag); len(resApk) > 0 {
Yu Liud46e5ae2024-08-15 18:46:17 +0000199 for _, installFile := range android.OtherModuleProviderOrDefault(
200 ctx, resApk[0], android.InstallFilesProvider).InstallFiles {
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700201 installResApk := ctx.InstallFile(resApkInstallPath, "ravenwood-res.apk", installFile)
202 installDeps = append(installDeps, installResApk)
203 }
204 }
205
Makoto Onuki68676572024-02-02 13:29:01 -0800206 // Install our JAR with all dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700207 ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
208}
209
210func (r *ravenwoodTest) AndroidMkEntries() []android.AndroidMkEntries {
211 entriesList := r.Library.AndroidMkEntries()
212 entries := &entriesList[0]
213 entries.ExtraEntries = append(entries.ExtraEntries,
214 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
215 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700216 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE",
217 "general-tests", "ravenwood-tests")
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700218 if r.testConfig != nil {
219 entries.SetPath("LOCAL_FULL_TEST_CONFIG", r.testConfig)
220 }
221 })
222 return entriesList
223}
224
225type ravenwoodLibgroupProperties struct {
226 Libs []string
Makoto Onuki68676572024-02-02 13:29:01 -0800227
228 Jni_libs []string
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700229
230 // We use this to copy framework-res.apk to the ravenwood runtime directory.
231 Data []string
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700232}
233
234type ravenwoodLibgroup struct {
235 android.ModuleBase
236
237 ravenwoodLibgroupProperties ravenwoodLibgroupProperties
238
239 forceOSType android.OsType
240 forceArchType android.ArchType
241}
242
243func ravenwoodLibgroupFactory() android.Module {
244 module := &ravenwoodLibgroup{}
245 module.AddProperties(&module.ravenwoodLibgroupProperties)
246
247 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
248 return module
249}
250
251func (r *ravenwoodLibgroup) InstallInTestcases() bool { return true }
252func (r *ravenwoodLibgroup) InstallForceOS() (*android.OsType, *android.ArchType) {
253 return &r.forceOSType, &r.forceArchType
254}
255func (r *ravenwoodLibgroup) TestSuites() []string {
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700256 return []string{
257 "general-tests",
258 "ravenwood-tests",
259 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700260}
261
262func (r *ravenwoodLibgroup) DepsMutator(ctx android.BottomUpMutatorContext) {
263 // Always depends on our underlying libs
264 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000265 ctx.AddVariationDependencies(nil, ravenwoodLibContentTag, lib)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700266 }
Makoto Onuki68676572024-02-02 13:29:01 -0800267 for _, lib := range r.ravenwoodLibgroupProperties.Jni_libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000268 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800269 }
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700270 for _, data := range r.ravenwoodLibgroupProperties.Data {
271 ctx.AddVariationDependencies(nil, ravenwoodDataTag, data)
272 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700273}
274
275func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
276 r.forceOSType = ctx.Config().BuildOS
277 r.forceArchType = ctx.Config().BuildArch
278
Makoto Onuki2ca84272024-02-10 00:15:21 +0000279 // Collect the JNI dependencies, including the transitive deps.
280 jniDepNames := make(map[string]bool)
281 jniLibs := collectTransitiveJniDeps(ctx)
282
283 for _, jni := range jniLibs {
284 jniDepNames[jni.name] = true
285 }
286 android.SetProvider(ctx, ravenwoodLibgroupJniDepProvider, ravenwoodLibgroupJniDepProviderInfo{
287 names: jniDepNames,
288 })
289
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700290 // Install our runtime into expected location for packaging
291 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
292 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000293 libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag)
Jerome Gaillard44fc5bf2024-07-30 16:11:59 +0000294 if libModule == nil {
295 if ctx.Config().AllowMissingDependencies() {
296 ctx.AddMissingDependencies([]string{lib})
297 } else {
298 ctx.PropertyErrorf("lib", "missing dependency %q", lib)
299 }
300 continue
301 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700302 libJar := android.OutputFileForModule(ctx, libModule, "")
303 ctx.InstallFile(installPath, lib+".jar", libJar)
304 }
Makoto Onuki68676572024-02-02 13:29:01 -0800305 soInstallPath := android.PathForModuleInstall(ctx, r.BaseModuleName()).Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000306
307 for _, jniLib := range jniLibs {
308 ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800309 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700310
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700311 dataInstallPath := installPath.Join(ctx, "ravenwood-data")
312 for _, data := range r.ravenwoodLibgroupProperties.Data {
313 libModule := ctx.GetDirectDepWithTag(data, ravenwoodDataTag)
314 file := android.OutputFileForModule(ctx, libModule, "")
315 ctx.InstallFile(dataInstallPath, file.Base(), file)
316 }
317
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700318 // Normal build should perform install steps
319 ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install"))
320}
Makoto Onuki2ca84272024-02-10 00:15:21 +0000321
322// collectTransitiveJniDeps returns all JNI dependencies, including transitive
323// ones, including NDK / stub libs. (Because Ravenwood has no "preinstalled" libraries)
324func collectTransitiveJniDeps(ctx android.ModuleContext) []jniLib {
325 libs, _ := collectJniDeps(ctx, true, false, nil)
326 return libs
327}