blob: 4905755f43df335edc0f4539b791ab6332a59dc4 [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
146 r.Library.GenerateAndroidBuildActions(ctx)
147
Makoto Onuki2ca84272024-02-10 00:15:21 +0000148 // Start by depending on all files installed by dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700149 var installDeps android.InstallPaths
Makoto Onuki2ca84272024-02-10 00:15:21 +0000150
151 // All JNI libraries included in the runtime
152 var runtimeJniModuleNames map[string]bool
153
154 if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
Yu Liud46e5ae2024-08-15 18:46:17 +0000155 for _, installFile := range android.OtherModuleProviderOrDefault(
156 ctx, utils, android.InstallFilesProvider).InstallFiles {
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700157 installDeps = append(installDeps, installFile)
158 }
Makoto Onuki2ca84272024-02-10 00:15:21 +0000159 jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
160 if ok {
161 runtimeJniModuleNames = jniDeps.names
162 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700163 }
164
Makoto Onuki2ca84272024-02-10 00:15:21 +0000165 if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
Yu Liud46e5ae2024-08-15 18:46:17 +0000166 for _, installFile := range android.OtherModuleProviderOrDefault(
167 ctx, runtime, android.InstallFilesProvider).InstallFiles {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000168 installDeps = append(installDeps, installFile)
169 }
170 jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
171 if ok {
172 runtimeJniModuleNames = jniDeps.names
173 }
174 }
175
176 // Also remember what JNI libs are in the runtime.
177
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700178 // Also depend on our config
179 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
180 installConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
181 installDeps = append(installDeps, installConfig)
182
Makoto Onuki2ca84272024-02-10 00:15:21 +0000183 // Depend on the JNI libraries, but don't install the ones that the runtime already
184 // contains.
Makoto Onuki68676572024-02-02 13:29:01 -0800185 soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000186 for _, jniLib := range collectTransitiveJniDeps(ctx) {
187 if _, ok := runtimeJniModuleNames[jniLib.name]; ok {
188 continue // Runtime already includes it.
189 }
190 installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800191 installDeps = append(installDeps, installJni)
192 }
193
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700194 resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
195 if resApk := ctx.GetDirectDepsWithTag(ravenwoodTestResourceApkTag); len(resApk) > 0 {
Yu Liud46e5ae2024-08-15 18:46:17 +0000196 for _, installFile := range android.OtherModuleProviderOrDefault(
197 ctx, resApk[0], android.InstallFilesProvider).InstallFiles {
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700198 installResApk := ctx.InstallFile(resApkInstallPath, "ravenwood-res.apk", installFile)
199 installDeps = append(installDeps, installResApk)
200 }
201 }
202
Makoto Onuki68676572024-02-02 13:29:01 -0800203 // Install our JAR with all dependencies
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700204 ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
205}
206
207func (r *ravenwoodTest) AndroidMkEntries() []android.AndroidMkEntries {
208 entriesList := r.Library.AndroidMkEntries()
209 entries := &entriesList[0]
210 entries.ExtraEntries = append(entries.ExtraEntries,
211 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
212 entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700213 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE",
214 "general-tests", "ravenwood-tests")
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700215 if r.testConfig != nil {
216 entries.SetPath("LOCAL_FULL_TEST_CONFIG", r.testConfig)
217 }
218 })
219 return entriesList
220}
221
222type ravenwoodLibgroupProperties struct {
223 Libs []string
Makoto Onuki68676572024-02-02 13:29:01 -0800224
225 Jni_libs []string
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700226
227 // We use this to copy framework-res.apk to the ravenwood runtime directory.
228 Data []string
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700229}
230
231type ravenwoodLibgroup struct {
232 android.ModuleBase
233
234 ravenwoodLibgroupProperties ravenwoodLibgroupProperties
235
236 forceOSType android.OsType
237 forceArchType android.ArchType
238}
239
240func ravenwoodLibgroupFactory() android.Module {
241 module := &ravenwoodLibgroup{}
242 module.AddProperties(&module.ravenwoodLibgroupProperties)
243
244 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
245 return module
246}
247
248func (r *ravenwoodLibgroup) InstallInTestcases() bool { return true }
249func (r *ravenwoodLibgroup) InstallForceOS() (*android.OsType, *android.ArchType) {
250 return &r.forceOSType, &r.forceArchType
251}
252func (r *ravenwoodLibgroup) TestSuites() []string {
Jeff Sharkey4bbf86f2023-11-30 09:29:50 -0700253 return []string{
254 "general-tests",
255 "ravenwood-tests",
256 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700257}
258
259func (r *ravenwoodLibgroup) DepsMutator(ctx android.BottomUpMutatorContext) {
260 // Always depends on our underlying libs
261 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000262 ctx.AddVariationDependencies(nil, ravenwoodLibContentTag, lib)
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700263 }
Makoto Onuki68676572024-02-02 13:29:01 -0800264 for _, lib := range r.ravenwoodLibgroupProperties.Jni_libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000265 ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
Makoto Onuki68676572024-02-02 13:29:01 -0800266 }
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700267 for _, data := range r.ravenwoodLibgroupProperties.Data {
268 ctx.AddVariationDependencies(nil, ravenwoodDataTag, data)
269 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700270}
271
272func (r *ravenwoodLibgroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
273 r.forceOSType = ctx.Config().BuildOS
274 r.forceArchType = ctx.Config().BuildArch
275
Makoto Onuki2ca84272024-02-10 00:15:21 +0000276 // Collect the JNI dependencies, including the transitive deps.
277 jniDepNames := make(map[string]bool)
278 jniLibs := collectTransitiveJniDeps(ctx)
279
280 for _, jni := range jniLibs {
281 jniDepNames[jni.name] = true
282 }
283 android.SetProvider(ctx, ravenwoodLibgroupJniDepProvider, ravenwoodLibgroupJniDepProviderInfo{
284 names: jniDepNames,
285 })
286
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700287 // Install our runtime into expected location for packaging
288 installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
289 for _, lib := range r.ravenwoodLibgroupProperties.Libs {
Makoto Onuki2ca84272024-02-10 00:15:21 +0000290 libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag)
Jerome Gaillard44fc5bf2024-07-30 16:11:59 +0000291 if libModule == nil {
292 if ctx.Config().AllowMissingDependencies() {
293 ctx.AddMissingDependencies([]string{lib})
294 } else {
295 ctx.PropertyErrorf("lib", "missing dependency %q", lib)
296 }
297 continue
298 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700299 libJar := android.OutputFileForModule(ctx, libModule, "")
300 ctx.InstallFile(installPath, lib+".jar", libJar)
301 }
Makoto Onuki68676572024-02-02 13:29:01 -0800302 soInstallPath := android.PathForModuleInstall(ctx, r.BaseModuleName()).Join(ctx, getLibPath(r.forceArchType))
Makoto Onuki2ca84272024-02-10 00:15:21 +0000303
304 for _, jniLib := range jniLibs {
305 ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
Makoto Onuki68676572024-02-02 13:29:01 -0800306 }
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700307
Makoto Onuki3380f6d2024-05-10 16:00:28 -0700308 dataInstallPath := installPath.Join(ctx, "ravenwood-data")
309 for _, data := range r.ravenwoodLibgroupProperties.Data {
310 libModule := ctx.GetDirectDepWithTag(data, ravenwoodDataTag)
311 file := android.OutputFileForModule(ctx, libModule, "")
312 ctx.InstallFile(dataInstallPath, file.Base(), file)
313 }
314
Makoto Onuki4a9869d2023-10-20 10:42:47 -0700315 // Normal build should perform install steps
316 ctx.Phony(r.BaseModuleName(), android.PathForPhony(ctx, r.BaseModuleName()+"-install"))
317}
Makoto Onuki2ca84272024-02-10 00:15:21 +0000318
319// collectTransitiveJniDeps returns all JNI dependencies, including transitive
320// ones, including NDK / stub libs. (Because Ravenwood has no "preinstalled" libraries)
321func collectTransitiveJniDeps(ctx android.ModuleContext) []jniLib {
322 libs, _ := collectJniDeps(ctx, true, false, nil)
323 return libs
324}