blob: 3fa73e64de31f497e67b1b9186295815688609f8 [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 Onuki4a9869d2023-10-20 10:42:47 -070037
38const ravenwoodUtilsName = "ravenwood-utils"
39const ravenwoodRuntimeName = "ravenwood-runtime"
40
Makoto Onuki2ca84272024-02-10 00:15:21 +000041type ravenwoodLibgroupJniDepProviderInfo struct {
42 // All the jni_libs module names with transient dependencies.
43 names map[string]bool
44}
45
46var ravenwoodLibgroupJniDepProvider = blueprint.NewProvider[ravenwoodLibgroupJniDepProviderInfo]()
47
Makoto Onuki68676572024-02-02 13:29:01 -080048func getLibPath(archType android.ArchType) string {
49 if archType.Multilib == "lib64" {
50 return "lib64"
51 }
52 return "lib"
53}
54
55type ravenwoodTestProperties struct {
56 Jni_libs []string
Makoto Onuki3380f6d2024-05-10 16:00:28 -070057
58 // Specify another android_app module here to copy it to the test directory, so that
59 // the ravenwood test can access it.
60 // TODO: For now, we simply refer to another android_app module and copy it to the
61 // test directory. Eventually, android_ravenwood_test should support all the resource
62 // related properties and build resources from the `res/` directory.
63 Resource_apk *string
Makoto Onuki68676572024-02-02 13:29:01 -080064}
65
Makoto Onuki4a9869d2023-10-20 10:42:47 -070066type ravenwoodTest struct {
67 Library
68
Makoto Onuki68676572024-02-02 13:29:01 -080069 ravenwoodTestProperties ravenwoodTestProperties
70
Makoto Onuki4a9869d2023-10-20 10:42:47 -070071 testProperties testProperties
72 testConfig android.Path
73
74 forceOSType android.OsType
75 forceArchType android.ArchType
76}
77
78func ravenwoodTestFactory() android.Module {
79 module := &ravenwoodTest{}
80
81 module.addHostAndDeviceProperties()
Makoto Onuki68676572024-02-02 13:29:01 -080082 module.AddProperties(&module.testProperties, &module.ravenwoodTestProperties)
Makoto Onuki4a9869d2023-10-20 10:42:47 -070083
84 module.Module.dexpreopter.isTest = true
85 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
86
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -070087 module.testProperties.Test_suites = []string{
88 "general-tests",
89 "ravenwood-tests",
90 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -070091 module.testProperties.Test_options.Unit_test = proptools.BoolPtr(false)
92
93 InitJavaModule(module, android.DeviceSupported)
94 android.InitDefaultableModule(module)
95
96 return module
97}
98
99func (r *ravenwoodTest) InstallInTestcases() bool { return true }
100func (r *ravenwoodTest) InstallForceOS() (*android.OsType, *android.ArchType) {
101 return &r.forceOSType, &r.forceArchType
102}
103func (r *ravenwoodTest) TestSuites() []string {
104 return r.testProperties.Test_suites
105}
106
107func (r *ravenwoodTest) DepsMutator(ctx android.BottomUpMutatorContext) {
108 r.Library.DepsMutator(ctx)
109
110 // Generically depend on the runtime so that it's installed together with us
Makoto Onuki2ca84272024-02-10 00:15:21 +0000111 ctx.AddVariationDependencies(nil, ravenwoodRuntimeTag, ravenwoodRuntimeName)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700112
113 // Directly depend on any utils so that we link against them
Makoto Onuki2ca84272024-02-10 00:15:21 +0000114 utils := ctx.AddVariationDependencies(nil, ravenwoodUtilsTag, ravenwoodUtilsName)[0]
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700115 if utils != nil {
116 for _, lib := range utils.(*ravenwoodLibgroup).ravenwoodLibgroupProperties.Libs {
117 ctx.AddVariationDependencies(nil, libTag, lib)
118 }
119 }
Makoto Onuki68676572024-02-02 13:29:01 -0800120
121 // Add jni libs
122 for _, lib := range r.ravenwoodTestProperties.Jni_libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000123 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800124 }
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700125
126 // Resources APK
127 if resourceApk := proptools.String(r.ravenwoodTestProperties.Resource_apk); resourceApk != "" {
128 ctx.AddVariationDependencies(nil, ravenwoodTestResourceApkTag, resourceApk)
129 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700130}
131
132func (r *ravenwoodTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
133 r.forceOSType = ctx.Config().BuildOS
134 r.forceArchType = ctx.Config().BuildArch
135
136 r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
137 TestConfigProp: r.testProperties.Test_config,
138 TestConfigTemplateProp: r.testProperties.Test_config_template,
139 TestSuites: r.testProperties.Test_suites,
140 AutoGenConfig: r.testProperties.Auto_gen_config,
141 DeviceTemplate: "${RavenwoodTestConfigTemplate}",
142 HostTemplate: "${RavenwoodTestConfigTemplate}",
143 })
144
Makoto Onuki7ded3822024-03-28 14:42:20 -0700145 // Always enable Ravenizer for ravenwood tests.
146 r.Library.ravenizer.enabled = true
147
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700148 r.Library.GenerateAndroidBuildActions(ctx)
149
Makoto Onuki2ca84272024-02-10 00:15:21 +0000150 // Start by depending on all files installed by dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700151 var installDeps android.InstallPaths
Makoto Onuki2ca84272024-02-10 00:15:21 +0000152
153 // All JNI libraries included in the runtime
154 var runtimeJniModuleNames map[string]bool
155
156 if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
Yu Liud46e5ae2024-08-15 18:46:17 +0000157 for _, installFile := range android.OtherModuleProviderOrDefault(
158 ctx, utils, android.InstallFilesProvider).InstallFiles {
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700159 installDeps = append(installDeps, installFile)
160 }
Makoto Onuki2ca84272024-02-10 00:15:21 +0000161 jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
162 if ok {
163 runtimeJniModuleNames = jniDeps.names
164 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700165 }
166
Makoto Onuki2ca84272024-02-10 00:15:21 +0000167 if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
Yu Liud46e5ae2024-08-15 18:46:17 +0000168 for _, installFile := range android.OtherModuleProviderOrDefault(
169 ctx, runtime, android.InstallFilesProvider).InstallFiles {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000170 installDeps = append(installDeps, installFile)
171 }
172 jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
173 if ok {
174 runtimeJniModuleNames = jniDeps.names
175 }
176 }
177
178 // Also remember what JNI libs are in the runtime.
179
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700180 // Also depend on our config
181 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
182 installConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
183 installDeps = append(installDeps, installConfig)
184
Makoto Onuki2ca84272024-02-10 00:15:21 +0000185 // Depend on the JNI libraries, but don't install the ones that the runtime already
186 // contains.
Makoto Onuki68676572024-02-02 13:29:01 -0800187 soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000188 for _, jniLib := range collectTransitiveJniDeps(ctx) {
189 if _, ok := runtimeJniModuleNames[jniLib.name]; ok {
190 continue // Runtime already includes it.
191 }
192 installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800193 installDeps = append(installDeps, installJni)
194 }
195
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700196 resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
197 if resApk := ctx.GetDirectDepsWithTag(ravenwoodTestResourceApkTag); len(resApk) > 0 {
Yu Liud46e5ae2024-08-15 18:46:17 +0000198 for _, installFile := range android.OtherModuleProviderOrDefault(
199 ctx, resApk[0], android.InstallFilesProvider).InstallFiles {
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700200 installResApk := ctx.InstallFile(resApkInstallPath, "ravenwood-res.apk", installFile)
201 installDeps = append(installDeps, installResApk)
202 }
203 }
204
Makoto Onuki68676572024-02-02 13:29:01 -0800205 // Install our JAR with all dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700206 ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
207}
208
209func (r *ravenwoodTest) AndroidMkEntries() []android.AndroidMkEntries {
210 entriesList := r.Library.AndroidMkEntries()
211 entries := &entriesList[0]
212 entries.ExtraEntries = append(entries.ExtraEntries,
213 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
214 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700215 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE",
216 "general-tests", "ravenwood-tests")
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700217 if r.testConfig != nil {
218 entries.SetPath("LOCAL_FULL_TEST_CONFIG", r.testConfig)
219 }
220 })
221 return entriesList
222}
223
224type ravenwoodLibgroupProperties struct {
225 Libs []string
Makoto Onuki68676572024-02-02 13:29:01 -0800226
227 Jni_libs []string
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700228
229 // We use this to copy framework-res.apk to the ravenwood runtime directory.
John Wu680cd732024-09-13 20:59:05 +0000230 Data []string `android:"path,arch_variant"`
231
232 // We use this to copy font files to the ravenwood runtime directory.
233 Fonts []string `android:"path,arch_variant"`
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700234}
235
236type ravenwoodLibgroup struct {
237 android.ModuleBase
238
239 ravenwoodLibgroupProperties ravenwoodLibgroupProperties
240
241 forceOSType android.OsType
242 forceArchType android.ArchType
243}
244
245func ravenwoodLibgroupFactory() android.Module {
246 module := &ravenwoodLibgroup{}
247 module.AddProperties(&module.ravenwoodLibgroupProperties)
248
249 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
250 return module
251}
252
253func (r *ravenwoodLibgroup) InstallInTestcases() bool { return true }
254func (r *ravenwoodLibgroup) InstallForceOS() (*android.OsType, *android.ArchType) {
255 return &r.forceOSType, &r.forceArchType
256}
257func (r *ravenwoodLibgroup) TestSuites() []string {
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700258 return []string{
259 "general-tests",
260 "ravenwood-tests",
261 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700262}
263
264func (r *ravenwoodLibgroup) DepsMutator(ctx android.BottomUpMutatorContext) {
265 // Always depends on our underlying libs
266 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000267 ctx.AddVariationDependencies(nil, ravenwoodLibContentTag, lib)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700268 }
Makoto Onuki68676572024-02-02 13:29:01 -0800269 for _, lib := range r.ravenwoodLibgroupProperties.Jni_libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000270 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800271 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700272}
273
274func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
275 r.forceOSType = ctx.Config().BuildOS
276 r.forceArchType = ctx.Config().BuildArch
277
Makoto Onuki2ca84272024-02-10 00:15:21 +0000278 // Collect the JNI dependencies, including the transitive deps.
279 jniDepNames := make(map[string]bool)
280 jniLibs := collectTransitiveJniDeps(ctx)
281
282 for _, jni := range jniLibs {
283 jniDepNames[jni.name] = true
284 }
285 android.SetProvider(ctx, ravenwoodLibgroupJniDepProvider, ravenwoodLibgroupJniDepProviderInfo{
286 names: jniDepNames,
287 })
288
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700289 // Install our runtime into expected location for packaging
290 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
291 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000292 libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag)
Jerome Gaillard44fc5bf2024-07-30 16:11:59 +0000293 if libModule == nil {
294 if ctx.Config().AllowMissingDependencies() {
295 ctx.AddMissingDependencies([]string{lib})
296 } else {
297 ctx.PropertyErrorf("lib", "missing dependency %q", lib)
298 }
299 continue
300 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700301 libJar := android.OutputFileForModule(ctx, libModule, "")
302 ctx.InstallFile(installPath, lib+".jar", libJar)
303 }
Makoto Onuki68676572024-02-02 13:29:01 -0800304 soInstallPath := android.PathForModuleInstall(ctx, r.BaseModuleName()).Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000305
306 for _, jniLib := range jniLibs {
307 ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800308 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700309
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700310 dataInstallPath := installPath.Join(ctx, "ravenwood-data")
John Wu680cd732024-09-13 20:59:05 +0000311 data := android.PathsForModuleSrc(ctx, r.ravenwoodLibgroupProperties.Data)
312 for _, file := range data {
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700313 ctx.InstallFile(dataInstallPath, file.Base(), file)
314 }
315
John Wu680cd732024-09-13 20:59:05 +0000316 fontsInstallPath := installPath.Join(ctx, "fonts")
317 fonts := android.PathsForModuleSrc(ctx, r.ravenwoodLibgroupProperties.Fonts)
318 for _, file := range fonts {
319 ctx.InstallFile(fontsInstallPath, file.Base(), file)
320 }
321
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700322 // Normal build should perform install steps
323 ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install"))
324}
Makoto Onuki2ca84272024-02-10 00:15:21 +0000325
326// collectTransitiveJniDeps returns all JNI dependencies, including transitive
327// ones, including NDK / stub libs. (Because Ravenwood has no "preinstalled" libraries)
328func collectTransitiveJniDeps(ctx android.ModuleContext) []jniLib {
329 libs, _ := collectJniDeps(ctx, true, false, nil)
330 return libs
331}