blob: 9f9b0b4d8abd1f66ee8a7b34dbd479ca5ef4f327 [file] [log] [blame]
Paul Duffinb432df92021-03-22 22:09:42 +00001// Copyright (C) 2021 The Android Open Source Project
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.
14
15package apex
16
17import (
Paul Duffinffa83752021-06-09 14:32:53 +010018 "fmt"
19 "strings"
Paul Duffinb432df92021-03-22 22:09:42 +000020 "testing"
21
22 "android/soong/android"
Jiakai Zhangb95998b2023-05-11 16:39:27 +010023 "android/soong/dexpreopt"
Paul Duffinb432df92021-03-22 22:09:42 +000024 "android/soong/java"
Martin Stjernholmb1e61cb2021-09-08 21:56:18 +010025
Paul Duffinb432df92021-03-22 22:09:42 +000026 "github.com/google/blueprint"
Paul Duffin7487a7a2021-05-19 09:36:09 +010027 "github.com/google/blueprint/proptools"
Paul Duffinb432df92021-03-22 22:09:42 +000028)
29
30// Contains tests for platform_bootclasspath logic from java/platform_bootclasspath.go that requires
31// apexes.
32
33var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
Jiakai Zhangb95998b2023-05-11 16:39:27 +010034 java.PrepareForTestWithJavaDefaultModules,
Paul Duffinb432df92021-03-22 22:09:42 +000035 PrepareForTestWithApexBuildComponents,
36)
37
Paul Duffinffa83752021-06-09 14:32:53 +010038func TestPlatformBootclasspath_Fragments(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -070039 t.Parallel()
Paul Duffinffa83752021-06-09 14:32:53 +010040 result := android.GroupFixturePreparers(
41 prepareForTestWithPlatformBootclasspath,
Paul Duffindc3f9562021-06-09 15:31:05 +010042 prepareForTestWithMyapex,
Paul Duffinffa83752021-06-09 14:32:53 +010043 java.PrepareForTestWithJavaSdkLibraryFiles,
44 java.FixtureWithLastReleaseApis("foo"),
satayevabcd5972021-08-06 17:49:46 +010045 java.FixtureConfigureApexBootJars("myapex:bar"),
Paul Duffinffa83752021-06-09 14:32:53 +010046 android.FixtureWithRootAndroidBp(`
47 platform_bootclasspath {
48 name: "platform-bootclasspath",
49 fragments: [
Paul Duffindc3f9562021-06-09 15:31:05 +010050 {
51 apex: "myapex",
52 module:"bar-fragment",
53 },
Paul Duffinffa83752021-06-09 14:32:53 +010054 ],
55 hidden_api: {
56 unsupported: [
57 "unsupported.txt",
58 ],
59 removed: [
60 "removed.txt",
61 ],
62 max_target_r_low_priority: [
63 "max-target-r-low-priority.txt",
64 ],
65 max_target_q: [
66 "max-target-q.txt",
67 ],
68 max_target_p: [
69 "max-target-p.txt",
70 ],
71 max_target_o_low_priority: [
72 "max-target-o-low-priority.txt",
73 ],
74 blocked: [
75 "blocked.txt",
76 ],
77 unsupported_packages: [
78 "unsupported-packages.txt",
79 ],
80 },
81 }
82
Paul Duffindc3f9562021-06-09 15:31:05 +010083 apex {
84 name: "myapex",
85 key: "myapex.key",
86 bootclasspath_fragments: [
87 "bar-fragment",
88 ],
89 updatable: false,
Spandan Das38c64f62024-02-12 15:00:15 +000090 min_sdk_version: "30", // R
Paul Duffindc3f9562021-06-09 15:31:05 +010091 }
92
93 apex_key {
94 name: "myapex.key",
95 public_key: "testkey.avbpubkey",
96 private_key: "testkey.pem",
97 }
98
Paul Duffinffa83752021-06-09 14:32:53 +010099 bootclasspath_fragment {
100 name: "bar-fragment",
101 contents: ["bar"],
Paul Duffindc3f9562021-06-09 15:31:05 +0100102 apex_available: ["myapex"],
Paul Duffinffa83752021-06-09 14:32:53 +0100103 api: {
104 stub_libs: ["foo"],
105 },
106 hidden_api: {
107 unsupported: [
108 "bar-unsupported.txt",
109 ],
110 removed: [
111 "bar-removed.txt",
112 ],
113 max_target_r_low_priority: [
114 "bar-max-target-r-low-priority.txt",
115 ],
116 max_target_q: [
117 "bar-max-target-q.txt",
118 ],
119 max_target_p: [
120 "bar-max-target-p.txt",
121 ],
122 max_target_o_low_priority: [
123 "bar-max-target-o-low-priority.txt",
124 ],
125 blocked: [
126 "bar-blocked.txt",
127 ],
128 unsupported_packages: [
129 "bar-unsupported-packages.txt",
130 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100131 split_packages: ["*"],
Paul Duffinffa83752021-06-09 14:32:53 +0100132 },
133 }
134
135 java_library {
136 name: "bar",
Paul Duffindc3f9562021-06-09 15:31:05 +0100137 apex_available: ["myapex"],
Paul Duffinffa83752021-06-09 14:32:53 +0100138 srcs: ["a.java"],
139 system_modules: "none",
140 sdk_version: "none",
141 compile_dex: true,
Paul Duffindc3f9562021-06-09 15:31:05 +0100142 permitted_packages: ["bar"],
Spandan Das38c64f62024-02-12 15:00:15 +0000143 min_sdk_version: "30", // R
Paul Duffinffa83752021-06-09 14:32:53 +0100144 }
145
146 java_sdk_library {
147 name: "foo",
148 srcs: ["a.java"],
149 public: {
150 enabled: true,
151 },
152 compile_dex: true,
153 }
154 `),
155 ).RunTest(t)
156
157 pbcp := result.Module("platform-bootclasspath", "android_common")
Yu Liu663e4502024-08-12 18:23:59 +0000158 info, _ := android.OtherModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider)
Paul Duffinffa83752021-06-09 14:32:53 +0100159
160 for _, category := range java.HiddenAPIFlagFileCategories {
Cole Faust22e8abc2024-01-23 17:52:13 -0800161 name := category.PropertyName()
Paul Duffinffa83752021-06-09 14:32:53 +0100162 message := fmt.Sprintf("category %s", name)
163 filename := strings.ReplaceAll(name, "_", "-")
164 expected := []string{fmt.Sprintf("%s.txt", filename), fmt.Sprintf("bar-%s.txt", filename)}
165 android.AssertPathsRelativeToTopEquals(t, message, expected, info.FlagsFilesByCategory[category])
166 }
167
Spandan Das38c64f62024-02-12 15:00:15 +0000168 android.AssertPathsRelativeToTopEquals(t, "annotation flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/annotation-flags.csv"}, info.AnnotationFlagsPaths)
169 android.AssertPathsRelativeToTopEquals(t, "metadata flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/metadata.csv"}, info.MetadataPaths)
170 android.AssertPathsRelativeToTopEquals(t, "index flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/index.csv"}, info.IndexPaths)
Paul Duffin67b9d612021-07-21 17:38:47 +0100171
Spandan Das38c64f62024-02-12 15:00:15 +0000172 android.AssertArrayString(t, "stub flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/filtered-stub-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
173 android.AssertArrayString(t, "all flags", []string{"out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/filtered-flags.csv:out/soong/.intermediates/bar-fragment/android_common_apex30/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
Paul Duffinffa83752021-06-09 14:32:53 +0100174}
175
Paul Duffin191be3a2021-08-10 16:14:16 +0100176// TestPlatformBootclasspath_LegacyPrebuiltFragment verifies that the
177// prebuilt_bootclasspath_fragment falls back to using the complete stub-flags/all-flags if the
178// filtered files are not provided.
179//
180// TODO: Remove once all prebuilts use the filtered_... properties.
181func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700182 t.Parallel()
Paul Duffin191be3a2021-08-10 16:14:16 +0100183 result := android.GroupFixturePreparers(
184 prepareForTestWithPlatformBootclasspath,
185 java.FixtureConfigureApexBootJars("myapex:foo"),
186 java.PrepareForTestWithJavaSdkLibraryFiles,
187 ).RunTestWithBp(t, `
188 prebuilt_apex {
189 name: "myapex",
190 src: "myapex.apex",
191 exported_bootclasspath_fragments: ["mybootclasspath-fragment"],
192 }
193
194 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
195 // because AlwaysUsePrebuiltSdks() is true.
196 java_sdk_library_import {
197 name: "foo",
198 prefer: false,
199 shared_library: false,
200 permitted_packages: ["foo"],
201 public: {
202 jars: ["sdk_library/public/foo-stubs.jar"],
203 stub_srcs: ["sdk_library/public/foo_stub_sources"],
204 current_api: "sdk_library/public/foo.txt",
205 removed_api: "sdk_library/public/foo-removed.txt",
206 sdk_version: "current",
207 },
208 apex_available: ["myapex"],
209 }
210
211 prebuilt_bootclasspath_fragment {
212 name: "mybootclasspath-fragment",
213 apex_available: [
214 "myapex",
215 ],
216 contents: [
217 "foo",
218 ],
219 hidden_api: {
220 stub_flags: "prebuilt-stub-flags.csv",
221 annotation_flags: "prebuilt-annotation-flags.csv",
222 metadata: "prebuilt-metadata.csv",
223 index: "prebuilt-index.csv",
224 all_flags: "prebuilt-all-flags.csv",
225 },
226 }
227
228 platform_bootclasspath {
229 name: "myplatform-bootclasspath",
230 fragments: [
231 {
232 apex: "myapex",
233 module:"mybootclasspath-fragment",
234 },
235 ],
236 }
237`,
238 )
239
240 pbcp := result.Module("myplatform-bootclasspath", "android_common")
Yu Liu663e4502024-08-12 18:23:59 +0000241 info, _ := android.OtherModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider)
Paul Duffin191be3a2021-08-10 16:14:16 +0100242
243 android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop())
244 android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop())
245}
246
Paul Duffinb432df92021-03-22 22:09:42 +0000247func TestPlatformBootclasspathDependencies(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700248 t.Parallel()
Paul Duffinb432df92021-03-22 22:09:42 +0000249 result := android.GroupFixturePreparers(
250 prepareForTestWithPlatformBootclasspath,
251 prepareForTestWithArtApex,
252 prepareForTestWithMyapex,
253 // Configure some libraries in the art and framework boot images.
Paul Duffin60264a02021-04-12 20:02:36 +0100254 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"),
satayevd604b212021-07-21 14:23:52 +0100255 java.FixtureConfigureApexBootJars("myapex:bar"),
Paul Duffinb432df92021-03-22 22:09:42 +0000256 java.PrepareForTestWithJavaSdkLibraryFiles,
257 java.FixtureWithLastReleaseApis("foo"),
Jiakai Zhangb95998b2023-05-11 16:39:27 +0100258 java.PrepareForTestWithDexpreopt,
259 dexpreopt.FixtureDisableDexpreoptBootImages(false),
Colin Crossa66b4632024-08-08 15:50:47 -0700260 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
Paul Duffinb432df92021-03-22 22:09:42 +0000261 ).RunTestWithBp(t, `
262 apex {
263 name: "com.android.art",
264 key: "com.android.art.key",
265 bootclasspath_fragments: [
266 "art-bootclasspath-fragment",
267 ],
268 updatable: false,
269 }
270
271 apex_key {
272 name: "com.android.art.key",
273 public_key: "com.android.art.avbpubkey",
274 private_key: "com.android.art.pem",
275 }
276
277 bootclasspath_fragment {
278 name: "art-bootclasspath-fragment",
satayevabcd5972021-08-06 17:49:46 +0100279 image_name: "art",
Paul Duffinb432df92021-03-22 22:09:42 +0000280 apex_available: [
281 "com.android.art",
282 ],
283 contents: [
284 "baz",
285 "quuz",
286 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100287 hidden_api: {
288 split_packages: ["*"],
289 },
Paul Duffinb432df92021-03-22 22:09:42 +0000290 }
291
292 java_library {
293 name: "baz",
294 apex_available: [
295 "com.android.art",
296 ],
297 srcs: ["b.java"],
298 installable: true,
Jihoon Kang85bc1932024-07-01 17:04:46 +0000299 sdk_version: "core_current",
Paul Duffinb432df92021-03-22 22:09:42 +0000300 }
301
302 // Add a java_import that is not preferred and so won't have an appropriate apex variant created
303 // for it to make sure that the platform_bootclasspath doesn't try and add a dependency onto it.
304 java_import {
305 name: "baz",
306 apex_available: [
307 "com.android.art",
308 ],
309 jars: ["b.jar"],
310 }
311
312 java_library {
313 name: "quuz",
314 apex_available: [
315 "com.android.art",
316 ],
317 srcs: ["b.java"],
318 installable: true,
319 }
320
321 apex {
322 name: "myapex",
323 key: "myapex.key",
Paul Duffin89f570a2021-06-16 01:42:33 +0100324 bootclasspath_fragments: [
325 "my-bootclasspath-fragment",
Paul Duffinb432df92021-03-22 22:09:42 +0000326 ],
327 updatable: false,
328 }
329
Paul Duffin89f570a2021-06-16 01:42:33 +0100330 bootclasspath_fragment {
331 name: "my-bootclasspath-fragment",
332 contents: ["bar"],
333 apex_available: ["myapex"],
Paul Duffin9fd56472022-03-31 15:42:30 +0100334 hidden_api: {
335 split_packages: ["*"],
336 },
Paul Duffin89f570a2021-06-16 01:42:33 +0100337 }
338
Paul Duffinb432df92021-03-22 22:09:42 +0000339 apex_key {
340 name: "myapex.key",
341 public_key: "testkey.avbpubkey",
342 private_key: "testkey.pem",
343 }
344
345 java_sdk_library {
346 name: "foo",
347 srcs: ["b.java"],
348 }
349
350 java_library {
351 name: "bar",
352 srcs: ["b.java"],
353 installable: true,
354 apex_available: ["myapex"],
355 permitted_packages: ["bar"],
356 }
357
358 platform_bootclasspath {
359 name: "myplatform-bootclasspath",
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100360
361 fragments: [
362 {
363 apex: "com.android.art",
364 module: "art-bootclasspath-fragment",
365 },
Paul Duffin89f570a2021-06-16 01:42:33 +0100366 {
367 apex: "myapex",
368 module: "my-bootclasspath-fragment",
369 },
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100370 ],
Paul Duffinb432df92021-03-22 22:09:42 +0000371 }
372`,
373 )
374
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100375 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
Paul Duffin74431d52021-04-21 14:10:42 +0100376 // The configured contents of BootJars.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100377 "com.android.art:baz",
378 "com.android.art:quuz",
379 "platform:foo",
Paul Duffin74431d52021-04-21 14:10:42 +0100380
satayevd604b212021-07-21 14:23:52 +0100381 // The configured contents of ApexBootJars.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100382 "myapex:bar",
383 })
384
385 java.CheckPlatformBootclasspathFragments(t, result, "myplatform-bootclasspath", []string{
Paul Duffin89f570a2021-06-16 01:42:33 +0100386 "com.android.art:art-bootclasspath-fragment",
387 "myapex:my-bootclasspath-fragment",
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100388 })
389
Paul Duffinb432df92021-03-22 22:09:42 +0000390 // Make sure that the myplatform-bootclasspath has the correct dependencies.
391 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
Spandan Das64c9e0c2023-12-20 20:13:34 +0000392 // source vs prebuilt selection metadata module
393 `platform:all_apex_contributions`,
394
Paul Duffin74431d52021-04-21 14:10:42 +0100395 // The following are stubs.
Jihoon Kangbd093452023-12-26 19:08:01 +0000396 `platform:android_stubs_current_exportable`,
397 `platform:android_system_stubs_current_exportable`,
398 `platform:android_test_stubs_current_exportable`,
399 `platform:legacy.core.platform.api.stubs.exportable`,
Paul Duffin74431d52021-04-21 14:10:42 +0100400
401 // Needed for generating the boot image.
Paul Duffinb432df92021-03-22 22:09:42 +0000402 `platform:dex2oatd`,
Paul Duffin74431d52021-04-21 14:10:42 +0100403
404 // The configured contents of BootJars.
Paul Duffinb432df92021-03-22 22:09:42 +0000405 `com.android.art:baz`,
406 `com.android.art:quuz`,
407 `platform:foo`,
Paul Duffin74431d52021-04-21 14:10:42 +0100408
satayevd604b212021-07-21 14:23:52 +0100409 // The configured contents of ApexBootJars.
Paul Duffinb432df92021-03-22 22:09:42 +0000410 `myapex:bar`,
Paul Duffin74431d52021-04-21 14:10:42 +0100411
412 // The fragments.
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100413 `com.android.art:art-bootclasspath-fragment`,
Paul Duffin89f570a2021-06-16 01:42:33 +0100414 `myapex:my-bootclasspath-fragment`,
Jihoon Kanga6d0aa82024-09-24 00:34:49 +0000415
416 // Impl lib of sdk_library for transitive srcjar generation
417 `platform:foo.impl`,
Paul Duffinb432df92021-03-22 22:09:42 +0000418 })
419}
420
Paul Duffin7487a7a2021-05-19 09:36:09 +0100421// TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when
Martin Stjernholmb1e61cb2021-09-08 21:56:18 +0100422// AlwaysUsePrebuiltSdk() returns true.
Paul Duffin7487a7a2021-05-19 09:36:09 +0100423func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700424 t.Parallel()
Paul Duffin7487a7a2021-05-19 09:36:09 +0100425 result := android.GroupFixturePreparers(
426 prepareForTestWithPlatformBootclasspath,
427 prepareForTestWithMyapex,
428 // Configure two libraries, the first is a java_sdk_library whose prebuilt will be used because
Martin Stjernholmb1e61cb2021-09-08 21:56:18 +0100429 // of AlwaysUsePrebuiltsSdk(). The second is a normal library that is unaffected. The order
430 // matters, so that the dependencies resolved by the platform_bootclasspath matches the
431 // configured list.
satayevd604b212021-07-21 14:23:52 +0100432 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
Paul Duffin7487a7a2021-05-19 09:36:09 +0100433 java.PrepareForTestWithJavaSdkLibraryFiles,
434 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
435 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
436 }),
Colin Crossa66b4632024-08-08 15:50:47 -0700437 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
438
Paul Duffin7487a7a2021-05-19 09:36:09 +0100439 java.FixtureWithPrebuiltApis(map[string][]string{
440 "current": {},
441 "30": {"foo"},
442 }),
443 ).RunTestWithBp(t, `
444 apex {
445 name: "myapex",
446 key: "myapex.key",
447 bootclasspath_fragments: [
448 "mybootclasspath-fragment",
449 ],
450 updatable: false,
451 }
452
453 apex_key {
454 name: "myapex.key",
455 public_key: "testkey.avbpubkey",
456 private_key: "testkey.pem",
457 }
458
459 java_library {
460 name: "bar",
461 srcs: ["b.java"],
462 installable: true,
463 apex_available: ["myapex"],
464 permitted_packages: ["bar"],
465 }
466
467 java_sdk_library {
468 name: "foo",
469 srcs: ["b.java"],
470 shared_library: false,
471 public: {
472 enabled: true,
473 },
474 apex_available: ["myapex"],
475 permitted_packages: ["foo"],
476 }
477
Martin Stjernholmb1e61cb2021-09-08 21:56:18 +0100478 prebuilt_apex {
479 name: "myapex",
480 src: "myapex.apex",
481 exported_bootclasspath_fragments: ["mybootclasspath-fragment"],
482 }
483
Paul Duffin7487a7a2021-05-19 09:36:09 +0100484 // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
485 // because AlwaysUsePrebuiltSdks() is true.
486 java_sdk_library_import {
487 name: "foo",
488 prefer: false,
489 shared_library: false,
Paul Duffin630b11e2021-07-15 13:35:26 +0100490 permitted_packages: ["foo"],
Paul Duffin7487a7a2021-05-19 09:36:09 +0100491 public: {
492 jars: ["sdk_library/public/foo-stubs.jar"],
493 stub_srcs: ["sdk_library/public/foo_stub_sources"],
494 current_api: "sdk_library/public/foo.txt",
495 removed_api: "sdk_library/public/foo-removed.txt",
496 sdk_version: "current",
497 },
498 apex_available: ["myapex"],
499 }
500
501 // This always depends on the source foo module, its dependencies are not affected by the
502 // AlwaysUsePrebuiltSdks().
503 bootclasspath_fragment {
504 name: "mybootclasspath-fragment",
505 apex_available: [
506 "myapex",
507 ],
508 contents: [
509 "foo", "bar",
510 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100511 hidden_api: {
512 split_packages: ["*"],
513 },
Paul Duffin7487a7a2021-05-19 09:36:09 +0100514 }
515
Martin Stjernholmb1e61cb2021-09-08 21:56:18 +0100516 prebuilt_bootclasspath_fragment {
517 name: "mybootclasspath-fragment",
518 apex_available: [
519 "myapex",
520 ],
521 contents: [
522 "foo",
523 ],
524 hidden_api: {
525 stub_flags: "",
526 annotation_flags: "",
527 metadata: "",
528 index: "",
529 all_flags: "",
530 },
531 }
532
Paul Duffin7487a7a2021-05-19 09:36:09 +0100533 platform_bootclasspath {
534 name: "myplatform-bootclasspath",
Paul Duffin89f570a2021-06-16 01:42:33 +0100535 fragments: [
536 {
537 apex: "myapex",
538 module:"mybootclasspath-fragment",
539 },
540 ],
Paul Duffin7487a7a2021-05-19 09:36:09 +0100541 }
542`,
543 )
544
545 java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
546 // The configured contents of BootJars.
Martin Stjernholmb1e61cb2021-09-08 21:56:18 +0100547 "myapex:prebuilt_foo",
Paul Duffin7487a7a2021-05-19 09:36:09 +0100548 "myapex:bar",
549 })
550
551 // Make sure that the myplatform-bootclasspath has the correct dependencies.
552 CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
Spandan Das64c9e0c2023-12-20 20:13:34 +0000553 // source vs prebuilt selection metadata module
554 `platform:all_apex_contributions`,
555
Paul Duffin7487a7a2021-05-19 09:36:09 +0100556 // The following are stubs.
557 "platform:prebuilt_sdk_public_current_android",
558 "platform:prebuilt_sdk_system_current_android",
559 "platform:prebuilt_sdk_test_current_android",
560
561 // Not a prebuilt as no prebuilt existed when it was added.
Jihoon Kangbd093452023-12-26 19:08:01 +0000562 "platform:legacy.core.platform.api.stubs.exportable",
Paul Duffin7487a7a2021-05-19 09:36:09 +0100563
Paul Duffin7487a7a2021-05-19 09:36:09 +0100564 // The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
565 // modules when available as it does not know which one will be preferred.
Paul Duffin7487a7a2021-05-19 09:36:09 +0100566 "myapex:foo",
Martin Stjernholmb1e61cb2021-09-08 21:56:18 +0100567 "myapex:prebuilt_foo",
Paul Duffin7487a7a2021-05-19 09:36:09 +0100568
569 // Only a source module exists.
570 "myapex:bar",
Paul Duffin89f570a2021-06-16 01:42:33 +0100571
572 // The fragments.
573 "myapex:mybootclasspath-fragment",
Martin Stjernholmb1e61cb2021-09-08 21:56:18 +0100574 "myapex:prebuilt_mybootclasspath-fragment",
Jihoon Kanga6d0aa82024-09-24 00:34:49 +0000575
576 // Impl lib of sdk_library for transitive srcjar generation
577 "platform:foo.impl",
Paul Duffin7487a7a2021-05-19 09:36:09 +0100578 })
579}
580
Paul Duffinb432df92021-03-22 22:09:42 +0000581// CheckModuleDependencies checks the dependencies of the selected module against the expected list.
582//
583// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
584// name of the apex, or platform is it is not part of an apex and <module> is the module name.
585func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
586 t.Helper()
587 module := ctx.ModuleForTests(name, variant).Module()
588 modules := []android.Module{}
589 ctx.VisitDirectDeps(module, func(m blueprint.Module) {
590 modules = append(modules, m.(android.Module))
591 })
592
593 pairs := java.ApexNamePairsFromModules(ctx, modules)
594 android.AssertDeepEquals(t, "module dependencies", expected, pairs)
595}
satayevb3090502021-06-15 17:49:10 +0100596
597// TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in
598// platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config
599// by setting generate_classpaths_proto property to false.
600func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700601 t.Parallel()
satayevb3090502021-06-15 17:49:10 +0100602 result := android.GroupFixturePreparers(
603 prepareForTestWithPlatformBootclasspath,
604 prepareForTestWithMyapex,
satayevd604b212021-07-21 14:23:52 +0100605 java.FixtureConfigureApexBootJars("myapex:foo"),
satayevb3090502021-06-15 17:49:10 +0100606 android.FixtureWithRootAndroidBp(`
607 platform_bootclasspath {
608 name: "platform-bootclasspath",
609 fragments: [
610 {
611 apex: "myapex",
612 module:"foo-fragment",
613 },
614 ],
615 }
616
617 apex {
618 name: "myapex",
619 key: "myapex.key",
620 bootclasspath_fragments: ["foo-fragment"],
621 updatable: false,
622 }
623
624 apex_key {
625 name: "myapex.key",
626 public_key: "testkey.avbpubkey",
627 private_key: "testkey.pem",
628 }
629
630 bootclasspath_fragment {
631 name: "foo-fragment",
632 generate_classpaths_proto: false,
633 contents: ["foo"],
634 apex_available: ["myapex"],
Paul Duffin9fd56472022-03-31 15:42:30 +0100635 hidden_api: {
636 split_packages: ["*"],
637 },
satayevb3090502021-06-15 17:49:10 +0100638 }
639
640 java_library {
641 name: "foo",
642 srcs: ["a.java"],
643 system_modules: "none",
644 sdk_version: "none",
645 compile_dex: true,
646 apex_available: ["myapex"],
647 permitted_packages: ["foo"],
648 }
649 `),
650 ).RunTest(t)
651
652 java.CheckClasspathFragmentProtoContentInfoProvider(t, result,
653 true, // proto should be generated
654 "myapex:foo", // apex doesn't generate its own config, so must be in platform_bootclasspath
655 "bootclasspath.pb",
656 "out/soong/target/product/test_device/system/etc/classpaths",
657 )
658}
satayevd34eb0c2021-08-06 13:20:28 +0100659
660func TestBootJarNotInApex(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700661 t.Parallel()
satayevd34eb0c2021-08-06 13:20:28 +0100662 android.GroupFixturePreparers(
663 prepareForTestWithPlatformBootclasspath,
664 PrepareForTestWithApexBuildComponents,
665 prepareForTestWithMyapex,
666 java.FixtureConfigureApexBootJars("myapex:foo"),
667 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
668 `dependency "foo" of "myplatform-bootclasspath" missing variant`)).
669 RunTestWithBp(t, `
670 apex {
671 name: "myapex",
672 key: "myapex.key",
673 updatable: false,
674 }
675
676 apex_key {
677 name: "myapex.key",
678 public_key: "testkey.avbpubkey",
679 private_key: "testkey.pem",
680 }
681
682 java_library {
683 name: "foo",
684 srcs: ["b.java"],
685 installable: true,
686 apex_available: [
687 "myapex",
688 ],
689 }
690
691 bootclasspath_fragment {
692 name: "not-in-apex-fragment",
693 contents: [
694 "foo",
695 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100696 hidden_api: {
697 split_packages: ["*"],
698 },
satayevd34eb0c2021-08-06 13:20:28 +0100699 }
700
701 platform_bootclasspath {
702 name: "myplatform-bootclasspath",
703 }
704 `)
705}
706
707func TestBootFragmentNotInApex(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700708 t.Parallel()
satayevd34eb0c2021-08-06 13:20:28 +0100709 android.GroupFixturePreparers(
710 prepareForTestWithPlatformBootclasspath,
711 PrepareForTestWithApexBuildComponents,
712 prepareForTestWithMyapex,
713 java.FixtureConfigureApexBootJars("myapex:foo"),
714 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
715 `library foo.*have no corresponding fragment.*`)).RunTestWithBp(t, `
716 apex {
717 name: "myapex",
718 key: "myapex.key",
719 java_libs: ["foo"],
720 updatable: false,
721 }
722
723 apex_key {
724 name: "myapex.key",
725 public_key: "testkey.avbpubkey",
726 private_key: "testkey.pem",
727 }
728
729 java_library {
730 name: "foo",
731 srcs: ["b.java"],
732 installable: true,
733 apex_available: ["myapex"],
734 permitted_packages: ["foo"],
735 }
736
737 bootclasspath_fragment {
738 name: "not-in-apex-fragment",
739 contents: ["foo"],
Paul Duffin9fd56472022-03-31 15:42:30 +0100740 hidden_api: {
741 split_packages: ["*"],
742 },
satayevd34eb0c2021-08-06 13:20:28 +0100743 }
744
745 platform_bootclasspath {
746 name: "myplatform-bootclasspath",
747 }
748 `)
749}
750
751func TestNonBootJarInFragment(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700752 t.Parallel()
satayevd34eb0c2021-08-06 13:20:28 +0100753 android.GroupFixturePreparers(
754 prepareForTestWithPlatformBootclasspath,
755 PrepareForTestWithApexBuildComponents,
756 prepareForTestWithMyapex,
757 java.FixtureConfigureApexBootJars("myapex:foo"),
758 ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
759 `in contents must also be declared in PRODUCT_APEX_BOOT_JARS`)).
760 RunTestWithBp(t, `
761 apex {
762 name: "myapex",
763 key: "myapex.key",
764 bootclasspath_fragments: ["apex-fragment"],
765 updatable: false,
766 }
767
768 apex_key {
769 name: "myapex.key",
770 public_key: "testkey.avbpubkey",
771 private_key: "testkey.pem",
772 }
773
774 java_library {
775 name: "foo",
776 srcs: ["b.java"],
777 installable: true,
778 apex_available: ["myapex"],
779 permitted_packages: ["foo"],
780 }
781
782 java_library {
783 name: "bar",
784 srcs: ["b.java"],
785 installable: true,
786 apex_available: ["myapex"],
787 permitted_packages: ["bar"],
788 }
789
790 bootclasspath_fragment {
791 name: "apex-fragment",
792 contents: ["foo", "bar"],
793 apex_available:[ "myapex" ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100794 hidden_api: {
795 split_packages: ["*"],
796 },
satayevd34eb0c2021-08-06 13:20:28 +0100797 }
798
799 platform_bootclasspath {
800 name: "myplatform-bootclasspath",
801 fragments: [{
802 apex: "myapex",
803 module:"apex-fragment",
804 }],
805 }
806 `)
807}
Spandan Das3d0d31a2024-05-03 21:36:48 +0000808
Spandan Dased7a0302024-08-26 18:06:25 +0000809// Skip bcp_fragment content validation of source apexes if prebuilts are active.
810func TestNonBootJarInPrebuilts(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700811 t.Parallel()
Spandan Dased7a0302024-08-26 18:06:25 +0000812 testCases := []struct {
813 description string
814 selectedApexContributions string
815 expectedError string
816 }{
817 {
818 description: "source is active",
819 selectedApexContributions: "",
820 expectedError: "in contents must also be declared in PRODUCT_APEX_BOOT_JARS",
821 },
822 {
823 description: "prebuilts are active",
824 selectedApexContributions: "myapex.prebuilt.contributions",
825 expectedError: "", // skip content validation of source bcp fragment
826 },
827 }
828 bp := `
829// Source
830apex {
831 name: "myapex",
832 key: "myapex.key",
833 bootclasspath_fragments: ["apex-fragment"],
834 updatable: false,
835 min_sdk_version: "29",
836}
837
838override_apex {
839 name: "myapex.override", // overrides the min_sdk_version, thereby creating different variants of its transitive deps
840 base: "myapex",
841 min_sdk_version: "34",
842}
843
844apex_key {
845 name: "myapex.key",
846 public_key: "testkey.avbpubkey",
847 private_key: "testkey.pem",
848}
849
850java_library {
851 name: "foo",
852 srcs: ["b.java"],
853 installable: true,
854 apex_available: ["myapex"],
855 permitted_packages: ["foo"],
856 min_sdk_version: "29",
857}
858
859java_library {
860 name: "bar",
861 srcs: ["b.java"],
862 installable: true,
863 apex_available: ["myapex"],
864 permitted_packages: ["bar"],
865 min_sdk_version: "29",
866}
867
868bootclasspath_fragment {
869 name: "apex-fragment",
870 contents: ["foo", "bar"],
871 apex_available:[ "myapex" ],
872 hidden_api: {
873 split_packages: ["*"],
874 },
875}
876
877platform_bootclasspath {
878 name: "myplatform-bootclasspath",
879 fragments: [{
880 apex: "myapex",
881 module:"apex-fragment",
882 }],
883}
884
885// prebuilts
886prebuilt_apex {
887 name: "myapex",
888 apex_name: "myapex",
889 src: "myapex.apex",
890 exported_bootclasspath_fragments: ["apex-fragment"],
891 }
892
893 prebuilt_bootclasspath_fragment {
894 name: "apex-fragment",
895 contents: ["foo"],
896 hidden_api: {
897 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
898 metadata: "my-bootclasspath-fragment/metadata.csv",
899 index: "my-bootclasspath-fragment/index.csv",
900 stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
901 all_flags: "my-bootclasspath-fragment/all-flags.csv",
902 },
903 }
904 java_import {
905 name: "foo",
906 jars: ["foo.jar"],
907 }
908
909apex_contributions {
910 name: "myapex.prebuilt.contributions",
911 api_domain: "myapex",
912 contents: ["prebuilt_myapex"],
913}
914`
915
916 for _, tc := range testCases {
917 fixture := android.GroupFixturePreparers(
918 prepareForTestWithPlatformBootclasspath,
919 PrepareForTestWithApexBuildComponents,
920 prepareForTestWithMyapex,
921 java.FixtureConfigureApexBootJars("myapex:foo"),
922 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ADSERVICES", tc.selectedApexContributions),
923 )
924 if tc.expectedError != "" {
925 fixture = fixture.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError))
926 }
927 fixture.RunTestWithBp(t, bp)
928 }
929
930}
931
Spandan Das3d0d31a2024-05-03 21:36:48 +0000932// Source and prebuilt apex provide different set of boot jars
933func TestNonBootJarMissingInPrebuiltFragment(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700934 t.Parallel()
Spandan Das3d0d31a2024-05-03 21:36:48 +0000935 bp := `
936 apex {
937 name: "myapex",
938 key: "myapex.key",
939 bootclasspath_fragments: ["apex-fragment"],
940 updatable: false,
941 }
942
943 apex_key {
944 name: "myapex.key",
945 public_key: "testkey.avbpubkey",
946 private_key: "testkey.pem",
947 }
948
949 java_library {
950 name: "foo",
951 srcs: ["b.java"],
952 installable: true,
953 apex_available: ["myapex"],
954 permitted_packages: ["foo"],
955 }
956
957 java_library {
958 name: "bar",
959 srcs: ["b.java"],
960 installable: true,
961 apex_available: ["myapex"],
962 permitted_packages: ["bar"],
963 }
964
965 bootclasspath_fragment {
966 name: "apex-fragment",
967 contents: ["foo", "bar"],
968 apex_available:[ "myapex" ],
969 hidden_api: {
970 split_packages: ["*"],
971 },
972 }
973
974 prebuilt_apex {
975 name: "com.google.android.myapex", // mainline prebuilt selection logic in soong relies on the naming convention com.google.android
976 apex_name: "myapex",
977 source_apex_name: "myapex",
978 src: "myapex.apex",
979 exported_bootclasspath_fragments: ["apex-fragment"],
980 }
981
982 java_import {
983 name: "foo",
984 jars: ["foo.jar"],
985 apex_available: ["myapex"],
986 permitted_packages: ["foo"],
987 }
988
989 prebuilt_bootclasspath_fragment {
990 name: "apex-fragment",
991 contents: ["foo"], // Unlike the source fragment, this is missing bar
992 apex_available:[ "myapex" ],
993 hidden_api: {
994 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
995 metadata: "my-bootclasspath-fragment/metadata.csv",
996 index: "my-bootclasspath-fragment/index.csv",
997 stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
998 all_flags: "my-bootclasspath-fragment/all-flags.csv",
999 },
1000 }
1001
Spandan Das5f1f9402024-05-21 18:59:23 +00001002 // Another prebuilt apex, but this is not selected during the build.
1003 prebuilt_apex {
1004 name: "com.google.android.myapex.v2", // mainline prebuilt selection logic in soong relies on the naming convention com.google.android
1005 apex_name: "myapex",
1006 source_apex_name: "myapex",
1007 src: "myapex.apex",
1008 exported_bootclasspath_fragments: ["apex-fragment.v2"],
1009 }
1010
1011 java_import {
1012 name: "bar",
1013 jars: ["bar.jar"],
1014 apex_available: ["myapex"],
1015 permitted_packages: ["bar"],
1016 }
1017
1018 prebuilt_bootclasspath_fragment {
1019 name: "apex-fragment.v2",
1020 contents: ["bar"], // Unlike the source fragment, this is missing foo
1021 apex_available:[ "myapex" ],
1022 hidden_api: {
1023 annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
1024 metadata: "my-bootclasspath-fragment/metadata.csv",
1025 index: "my-bootclasspath-fragment/index.csv",
1026 stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
1027 all_flags: "my-bootclasspath-fragment/all-flags.csv",
1028 },
1029 }
1030
1031
Spandan Das3d0d31a2024-05-03 21:36:48 +00001032 apex_contributions {
1033 name: "my_apex_contributions",
1034 api_domain: "myapex",
1035 contents: [%v],
1036 }
1037 `
1038 testCases := []struct {
1039 desc string
1040 configuredBootJars []string
1041 apexContributionContents string
1042 errorExpected bool
1043 }{
1044 {
1045 desc: "Source apex is selected, and APEX_BOOT_JARS is correctly configured for source apex builds",
1046 configuredBootJars: []string{"myapex:foo", "myapex:bar"},
1047 },
1048 {
1049 desc: "Source apex is selected, and APEX_BOOT_JARS is missing bar",
1050 configuredBootJars: []string{"myapex:foo"},
1051 errorExpected: true,
1052 },
1053 {
1054 desc: "Prebuilt apex is selected, and APEX_BOOT_JARS is correctly configured for prebuilt apex build",
1055 configuredBootJars: []string{"myapex:foo"},
1056 apexContributionContents: `"prebuilt_com.google.android.myapex"`,
1057 },
1058 {
1059 desc: "Prebuilt apex is selected, and APEX_BOOT_JARS is missing foo",
1060 configuredBootJars: []string{"myapex:bar"},
1061 apexContributionContents: `"prebuilt_com.google.android.myapex"`,
1062 errorExpected: true,
1063 },
1064 }
1065
1066 for _, tc := range testCases {
1067 fixture := android.GroupFixturePreparers(
1068 prepareForTestWithPlatformBootclasspath,
1069 PrepareForTestWithApexBuildComponents,
1070 prepareForTestWithMyapex,
1071 java.FixtureConfigureApexBootJars(tc.configuredBootJars...),
Colin Crossa66b4632024-08-08 15:50:47 -07001072 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "my_apex_contributions"),
Spandan Das3d0d31a2024-05-03 21:36:48 +00001073 )
1074 if tc.errorExpected {
1075 fixture = fixture.ExtendWithErrorHandler(
1076 android.FixtureExpectsAtLeastOneErrorMatchingPattern(`in contents.*must also be declared in PRODUCT_APEX_BOOT_JARS`),
1077 )
1078 }
1079 fixture.RunTestWithBp(t, fmt.Sprintf(bp, tc.apexContributionContents))
1080 }
1081}