blob: 4c9fdc212aa1f7cab5aa08c56224e9038c1e34a9 [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 ravenwoodTestResourceApkTag = dependencyTag{name: "ravenwoodtestresapk"}
Makoto Onukied392f72024-09-17 09:56:33 -070037var ravenwoodTestInstResourceApkTag = dependencyTag{name: "ravenwoodtest-inst-res-apk"}
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 {
Jihoon Kang371a0372024-10-01 16:44:41 +000057 Jni_libs proptools.Configurable[[]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
Makoto Onukied392f72024-09-17 09:56:33 -070060 // the ravenwood test can access it. This APK will be loaded as resources of the test
61 // target app.
Makoto Onuki3380f6d2024-05-10 16:00:28 -070062 // TODO: For now, we simply refer to another android_app module and copy it to the
63 // test directory. Eventually, android_ravenwood_test should support all the resource
64 // related properties and build resources from the `res/` directory.
65 Resource_apk *string
Makoto Onukied392f72024-09-17 09:56:33 -070066
67 // Specify another android_app module here to copy it to the test directory, so that
68 // the ravenwood test can access it. This APK will be loaded as resources of the test
69 // instrumentation app itself.
70 Inst_resource_apk *string
Makoto Onuki68676572024-02-02 13:29:01 -080071}
72
Makoto Onuki4a9869d2023-10-20 10:42:47 -070073type ravenwoodTest struct {
74 Library
75
Makoto Onuki68676572024-02-02 13:29:01 -080076 ravenwoodTestProperties ravenwoodTestProperties
77
Makoto Onuki4a9869d2023-10-20 10:42:47 -070078 testProperties testProperties
79 testConfig android.Path
80
81 forceOSType android.OsType
82 forceArchType android.ArchType
83}
84
85func ravenwoodTestFactory() android.Module {
86 module := &ravenwoodTest{}
87
88 module.addHostAndDeviceProperties()
Makoto Onuki68676572024-02-02 13:29:01 -080089 module.AddProperties(&module.testProperties, &module.ravenwoodTestProperties)
Makoto Onuki4a9869d2023-10-20 10:42:47 -070090
91 module.Module.dexpreopter.isTest = true
92 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
93
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -070094 module.testProperties.Test_suites = []string{
95 "general-tests",
96 "ravenwood-tests",
97 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -070098 module.testProperties.Test_options.Unit_test = proptools.BoolPtr(false)
99
100 InitJavaModule(module, android.DeviceSupported)
101 android.InitDefaultableModule(module)
102
103 return module
104}
105
106func (r *ravenwoodTest) InstallInTestcases() bool { return true }
107func (r *ravenwoodTest) InstallForceOS() (*android.OsType, *android.ArchType) {
108 return &r.forceOSType, &r.forceArchType
109}
110func (r *ravenwoodTest) TestSuites() []string {
111 return r.testProperties.Test_suites
112}
113
114func (r *ravenwoodTest) DepsMutator(ctx android.BottomUpMutatorContext) {
115 r.Library.DepsMutator(ctx)
116
117 // Generically depend on the runtime so that it's installed together with us
Makoto Onuki2ca84272024-02-10 00:15:21 +0000118 ctx.AddVariationDependencies(nil, ravenwoodRuntimeTag, ravenwoodRuntimeName)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700119
120 // Directly depend on any utils so that we link against them
Makoto Onuki2ca84272024-02-10 00:15:21 +0000121 utils := ctx.AddVariationDependencies(nil, ravenwoodUtilsTag, ravenwoodUtilsName)[0]
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700122 if utils != nil {
123 for _, lib := range utils.(*ravenwoodLibgroup).ravenwoodLibgroupProperties.Libs {
124 ctx.AddVariationDependencies(nil, libTag, lib)
125 }
126 }
Makoto Onuki68676572024-02-02 13:29:01 -0800127
128 // Add jni libs
Jihoon Kang371a0372024-10-01 16:44:41 +0000129 for _, lib := range r.ravenwoodTestProperties.Jni_libs.GetOrDefault(ctx, nil) {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000130 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800131 }
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700132
133 // Resources APK
134 if resourceApk := proptools.String(r.ravenwoodTestProperties.Resource_apk); resourceApk != "" {
135 ctx.AddVariationDependencies(nil, ravenwoodTestResourceApkTag, resourceApk)
136 }
Makoto Onukied392f72024-09-17 09:56:33 -0700137
138 if resourceApk := proptools.String(r.ravenwoodTestProperties.Inst_resource_apk); resourceApk != "" {
139 ctx.AddVariationDependencies(nil, ravenwoodTestInstResourceApkTag, resourceApk)
140 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700141}
142
143func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
144 r.forceOSType = ctx.Config().BuildOS
145 r.forceArchType = ctx.Config().BuildArch
146
147 r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
148 TestConfigProp: r.testProperties.Test_config,
149 TestConfigTemplateProp: r.testProperties.Test_config_template,
150 TestSuites: r.testProperties.Test_suites,
151 AutoGenConfig: r.testProperties.Auto_gen_config,
152 DeviceTemplate: "${RavenwoodTestConfigTemplate}",
153 HostTemplate: "${RavenwoodTestConfigTemplate}",
154 })
155
Makoto Onuki7ded3822024-03-28 14:42:20 -0700156 // Always enable Ravenizer for ravenwood tests.
157 r.Library.ravenizer.enabled = true
158
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700159 r.Library.GenerateAndroidBuildActions(ctx)
160
Makoto Onuki2ca84272024-02-10 00:15:21 +0000161 // Start by depending on all files installed by dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700162 var installDeps android.InstallPaths
Makoto Onuki2ca84272024-02-10 00:15:21 +0000163
164 // All JNI libraries included in the runtime
165 var runtimeJniModuleNames map[string]bool
166
167 if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
Yu Liud46e5ae2024-08-15 18:46:17 +0000168 for _, installFile := range android.OtherModuleProviderOrDefault(
169 ctx, utils, android.InstallFilesProvider).InstallFiles {
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700170 installDeps = append(installDeps, installFile)
171 }
Makoto Onuki2ca84272024-02-10 00:15:21 +0000172 jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
173 if ok {
174 runtimeJniModuleNames = jniDeps.names
175 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700176 }
177
Makoto Onuki2ca84272024-02-10 00:15:21 +0000178 if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
Yu Liud46e5ae2024-08-15 18:46:17 +0000179 for _, installFile := range android.OtherModuleProviderOrDefault(
180 ctx, runtime, android.InstallFilesProvider).InstallFiles {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000181 installDeps = append(installDeps, installFile)
182 }
183 jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
184 if ok {
185 runtimeJniModuleNames = jniDeps.names
186 }
187 }
188
189 // Also remember what JNI libs are in the runtime.
190
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700191 // Also depend on our config
192 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
193 installConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
194 installDeps = append(installDeps, installConfig)
195
Makoto Onuki2ca84272024-02-10 00:15:21 +0000196 // Depend on the JNI libraries, but don't install the ones that the runtime already
197 // contains.
Makoto Onuki68676572024-02-02 13:29:01 -0800198 soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000199 for _, jniLib := range collectTransitiveJniDeps(ctx) {
200 if _, ok := runtimeJniModuleNames[jniLib.name]; ok {
201 continue // Runtime already includes it.
202 }
203 installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800204 installDeps = append(installDeps, installJni)
205 }
206
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700207 resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
Makoto Onukied392f72024-09-17 09:56:33 -0700208
209 copyResApk := func(tag blueprint.DependencyTag, toFileName string) {
210 if resApk := ctx.GetDirectDepsWithTag(tag); len(resApk) > 0 {
211 installFile := android.OutputFileForModule(ctx, resApk[0], "")
212 installResApk := ctx.InstallFile(resApkInstallPath, toFileName, installFile)
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700213 installDeps = append(installDeps, installResApk)
214 }
215 }
Makoto Onukied392f72024-09-17 09:56:33 -0700216 copyResApk(ravenwoodTestResourceApkTag, "ravenwood-res.apk")
217 copyResApk(ravenwoodTestInstResourceApkTag, "ravenwood-inst-res.apk")
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700218
Makoto Onuki68676572024-02-02 13:29:01 -0800219 // Install our JAR with all dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700220 ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
221}
222
223func (r *ravenwoodTest) AndroidMkEntries() []android.AndroidMkEntries {
224 entriesList := r.Library.AndroidMkEntries()
225 entries := &entriesList[0]
226 entries.ExtraEntries = append(entries.ExtraEntries,
227 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
228 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700229 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE",
230 "general-tests", "ravenwood-tests")
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700231 if r.testConfig != nil {
232 entries.SetPath("LOCAL_FULL_TEST_CONFIG", r.testConfig)
233 }
234 })
235 return entriesList
236}
237
238type ravenwoodLibgroupProperties struct {
239 Libs []string
Makoto Onuki68676572024-02-02 13:29:01 -0800240
Jihoon Kang371a0372024-10-01 16:44:41 +0000241 Jni_libs proptools.Configurable[[]string]
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700242
243 // We use this to copy framework-res.apk to the ravenwood runtime directory.
John Wu680cd732024-09-13 20:59:05 +0000244 Data []string `android:"path,arch_variant"`
245
246 // We use this to copy font files to the ravenwood runtime directory.
247 Fonts []string `android:"path,arch_variant"`
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700248}
249
250type ravenwoodLibgroup struct {
251 android.ModuleBase
252
253 ravenwoodLibgroupProperties ravenwoodLibgroupProperties
254
255 forceOSType android.OsType
256 forceArchType android.ArchType
257}
258
259func ravenwoodLibgroupFactory() android.Module {
260 module := &ravenwoodLibgroup{}
261 module.AddProperties(&module.ravenwoodLibgroupProperties)
262
263 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
264 return module
265}
266
267func (r *ravenwoodLibgroup) InstallInTestcases() bool { return true }
268func (r *ravenwoodLibgroup) InstallForceOS() (*android.OsType, *android.ArchType) {
269 return &r.forceOSType, &r.forceArchType
270}
271func (r *ravenwoodLibgroup) TestSuites() []string {
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700272 return []string{
273 "general-tests",
274 "ravenwood-tests",
275 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700276}
277
278func (r *ravenwoodLibgroup) DepsMutator(ctx android.BottomUpMutatorContext) {
279 // Always depends on our underlying libs
280 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000281 ctx.AddVariationDependencies(nil, ravenwoodLibContentTag, lib)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700282 }
Jihoon Kang371a0372024-10-01 16:44:41 +0000283 for _, lib := range r.ravenwoodLibgroupProperties.Jni_libs.GetOrDefault(ctx, nil) {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000284 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800285 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700286}
287
288func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
289 r.forceOSType = ctx.Config().BuildOS
290 r.forceArchType = ctx.Config().BuildArch
291
Makoto Onuki2ca84272024-02-10 00:15:21 +0000292 // Collect the JNI dependencies, including the transitive deps.
293 jniDepNames := make(map[string]bool)
294 jniLibs := collectTransitiveJniDeps(ctx)
295
296 for _, jni := range jniLibs {
297 jniDepNames[jni.name] = true
298 }
299 android.SetProvider(ctx, ravenwoodLibgroupJniDepProvider, ravenwoodLibgroupJniDepProviderInfo{
300 names: jniDepNames,
301 })
302
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700303 // Install our runtime into expected location for packaging
304 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
305 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000306 libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag)
Jerome Gaillard44fc5bf2024-07-30 16:11:59 +0000307 if libModule == nil {
308 if ctx.Config().AllowMissingDependencies() {
309 ctx.AddMissingDependencies([]string{lib})
310 } else {
311 ctx.PropertyErrorf("lib", "missing dependency %q", lib)
312 }
313 continue
314 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700315 libJar := android.OutputFileForModule(ctx, libModule, "")
316 ctx.InstallFile(installPath, lib+".jar", libJar)
317 }
Makoto Onuki68676572024-02-02 13:29:01 -0800318 soInstallPath := android.PathForModuleInstall(ctx, r.BaseModuleName()).Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000319
320 for _, jniLib := range jniLibs {
321 ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800322 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700323
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700324 dataInstallPath := installPath.Join(ctx, "ravenwood-data")
John Wu680cd732024-09-13 20:59:05 +0000325 data := android.PathsForModuleSrc(ctx, r.ravenwoodLibgroupProperties.Data)
326 for _, file := range data {
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700327 ctx.InstallFile(dataInstallPath, file.Base(), file)
328 }
329
John Wu680cd732024-09-13 20:59:05 +0000330 fontsInstallPath := installPath.Join(ctx, "fonts")
331 fonts := android.PathsForModuleSrc(ctx, r.ravenwoodLibgroupProperties.Fonts)
332 for _, file := range fonts {
333 ctx.InstallFile(fontsInstallPath, file.Base(), file)
334 }
335
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700336 // Normal build should perform install steps
337 ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install"))
338}
Makoto Onuki2ca84272024-02-10 00:15:21 +0000339
340// collectTransitiveJniDeps returns all JNI dependencies, including transitive
341// ones, including NDK / stub libs. (Because Ravenwood has no "preinstalled" libraries)
342func collectTransitiveJniDeps(ctx android.ModuleContext) []jniLib {
343 libs, _ := collectJniDeps(ctx, true, false, nil)
344 return libs
345}