blob: a650d11464976999b311bbe15d0b56e999580306 [file] [log] [blame]
Paul Duffin3451e162021-01-20 15:16:56 +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 Duffinba6afd02019-11-19 19:44:10 +000018 "fmt"
Jiakai Zhang7d3c9e02021-12-13 17:19:05 +000019 "path"
Paul Duffince918b02021-06-07 14:33:47 +010020 "sort"
Paul Duffina1d60252021-01-21 18:13:43 +000021 "strings"
Paul Duffin3451e162021-01-20 15:16:56 +000022 "testing"
23
24 "android/soong/android"
Jiakai Zhang49b1eb62021-11-26 18:09:27 +000025 "android/soong/dexpreopt"
Paul Duffin3451e162021-01-20 15:16:56 +000026 "android/soong/java"
Martin Stjernholm8be1e6d2021-09-15 03:34:04 +010027
Paul Duffin5cca7c42021-05-26 10:16:01 +010028 "github.com/google/blueprint/proptools"
Paul Duffin3451e162021-01-20 15:16:56 +000029)
30
Paul Duffin7771eba2021-04-23 14:25:28 +010031// Contains tests for bootclasspath_fragment logic from java/bootclasspath_fragment.go as the ART
32// bootclasspath_fragment requires modules from the ART apex.
Paul Duffin3451e162021-01-20 15:16:56 +000033
Paul Duffin94f19632021-04-20 12:40:07 +010034var prepareForTestWithBootclasspathFragment = android.GroupFixturePreparers(
Paul Duffin52bfaa42021-03-23 23:40:12 +000035 java.PrepareForTestWithDexpreopt,
36 PrepareForTestWithApexBuildComponents,
37)
38
39// Some additional files needed for the art apex.
Jiakai Zhang49b1eb62021-11-26 18:09:27 +000040var prepareForTestWithArtApex = android.GroupFixturePreparers(
41 android.FixtureMergeMockFs(android.MockFS{
42 "com.android.art.avbpubkey": nil,
43 "com.android.art.pem": nil,
44 "system/sepolicy/apex/com.android.art-file_contexts": nil,
45 }),
46 dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"),
47)
Paul Duffin52bfaa42021-03-23 23:40:12 +000048
Paul Duffinf1b358c2021-05-17 07:38:47 +010049func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -070050 t.Parallel()
Paul Duffinf1b358c2021-05-17 07:38:47 +010051 result := android.GroupFixturePreparers(
52 prepareForTestWithBootclasspathFragment,
53 // Configure some libraries in the art bootclasspath_fragment and platform_bootclasspath.
satayevabcd5972021-08-06 17:49:46 +010054 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
55 java.FixtureConfigureApexBootJars("someapex:foo", "someapex:bar"),
Paul Duffinf1b358c2021-05-17 07:38:47 +010056 prepareForTestWithArtApex,
Colin Crossa66b4632024-08-08 15:50:47 -070057 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
Paul Duffinf1b358c2021-05-17 07:38:47 +010058 java.PrepareForTestWithJavaSdkLibraryFiles,
59 java.FixtureWithLastReleaseApis("foo", "baz"),
60 ).RunTestWithBp(t, `
61 java_sdk_library {
62 name: "foo",
63 srcs: ["b.java"],
64 shared_library: false,
65 public: {
66 enabled: true,
67 },
68 system: {
69 enabled: true,
70 },
71 }
72
73 java_library {
74 name: "bar",
75 srcs: ["b.java"],
76 installable: true,
77 }
78
79 apex {
80 name: "com.android.art",
81 key: "com.android.art.key",
82 bootclasspath_fragments: ["art-bootclasspath-fragment"],
83 updatable: false,
84 }
85
86 apex_key {
87 name: "com.android.art.key",
88 public_key: "com.android.art.avbpubkey",
89 private_key: "com.android.art.pem",
90 }
91
92 java_sdk_library {
93 name: "baz",
94 apex_available: [
95 "com.android.art",
96 ],
97 srcs: ["b.java"],
98 shared_library: false,
99 public: {
100 enabled: true,
101 },
102 system: {
103 enabled: true,
104 },
105 test: {
106 enabled: true,
107 },
Jihoon Kang85bc1932024-07-01 17:04:46 +0000108 sdk_version: "core_current",
Paul Duffinf1b358c2021-05-17 07:38:47 +0100109 }
110
111 java_library {
112 name: "quuz",
113 apex_available: [
114 "com.android.art",
115 ],
116 srcs: ["b.java"],
117 compile_dex: true,
118 }
119
120 bootclasspath_fragment {
121 name: "art-bootclasspath-fragment",
122 image_name: "art",
123 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
124 contents: ["baz", "quuz"],
125 apex_available: [
126 "com.android.art",
127 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100128 hidden_api: {
129 split_packages: ["*"],
130 },
Paul Duffinf1b358c2021-05-17 07:38:47 +0100131 }
132
133 bootclasspath_fragment {
134 name: "other-bootclasspath-fragment",
135 contents: ["foo", "bar"],
136 fragments: [
137 {
138 apex: "com.android.art",
139 module: "art-bootclasspath-fragment",
140 },
141 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100142 hidden_api: {
143 split_packages: ["*"],
144 },
Paul Duffinf1b358c2021-05-17 07:38:47 +0100145 }
146`,
147 )
148
Paul Duffin31fad802021-06-18 18:14:25 +0100149 checkAPIScopeStubs := func(message string, info java.HiddenAPIInfo, apiScope *java.HiddenAPIScope, expectedPaths ...string) {
Paul Duffinf1b358c2021-05-17 07:38:47 +0100150 t.Helper()
Paul Duffin280a31a2021-06-27 20:28:29 +0100151 paths := info.TransitiveStubDexJarsByScope.StubDexJarsForScope(apiScope)
152 android.AssertPathsRelativeToTopEquals(t, fmt.Sprintf("%s %s", message, apiScope), expectedPaths, paths)
Paul Duffinf1b358c2021-05-17 07:38:47 +0100153 }
154
155 // Check stub dex paths exported by art.
156 artFragment := result.Module("art-bootclasspath-fragment", "android_common")
Yu Liu663e4502024-08-12 18:23:59 +0000157 artInfo, _ := android.OtherModuleProvider(result, artFragment, java.HiddenAPIInfoProvider)
Paul Duffinf1b358c2021-05-17 07:38:47 +0100158
Jihoon Kangbd093452023-12-26 19:08:01 +0000159 bazPublicStubs := "out/soong/.intermediates/baz.stubs.exportable/android_common/dex/baz.stubs.exportable.jar"
160 bazSystemStubs := "out/soong/.intermediates/baz.stubs.exportable.system/android_common/dex/baz.stubs.exportable.system.jar"
161 bazTestStubs := "out/soong/.intermediates/baz.stubs.exportable.test/android_common/dex/baz.stubs.exportable.test.jar"
Paul Duffinf1b358c2021-05-17 07:38:47 +0100162
Paul Duffin31fad802021-06-18 18:14:25 +0100163 checkAPIScopeStubs("art", artInfo, java.PublicHiddenAPIScope, bazPublicStubs)
164 checkAPIScopeStubs("art", artInfo, java.SystemHiddenAPIScope, bazSystemStubs)
165 checkAPIScopeStubs("art", artInfo, java.TestHiddenAPIScope, bazTestStubs)
166 checkAPIScopeStubs("art", artInfo, java.CorePlatformHiddenAPIScope)
Paul Duffinf1b358c2021-05-17 07:38:47 +0100167
168 // Check stub dex paths exported by other.
169 otherFragment := result.Module("other-bootclasspath-fragment", "android_common")
Yu Liu663e4502024-08-12 18:23:59 +0000170 otherInfo, _ := android.OtherModuleProvider(result, otherFragment, java.HiddenAPIInfoProvider)
Paul Duffinf1b358c2021-05-17 07:38:47 +0100171
Jihoon Kangbd093452023-12-26 19:08:01 +0000172 fooPublicStubs := "out/soong/.intermediates/foo.stubs.exportable/android_common/dex/foo.stubs.exportable.jar"
173 fooSystemStubs := "out/soong/.intermediates/foo.stubs.exportable.system/android_common/dex/foo.stubs.exportable.system.jar"
Paul Duffinf1b358c2021-05-17 07:38:47 +0100174
Paul Duffin31fad802021-06-18 18:14:25 +0100175 checkAPIScopeStubs("other", otherInfo, java.PublicHiddenAPIScope, bazPublicStubs, fooPublicStubs)
176 checkAPIScopeStubs("other", otherInfo, java.SystemHiddenAPIScope, bazSystemStubs, fooSystemStubs)
177 checkAPIScopeStubs("other", otherInfo, java.TestHiddenAPIScope, bazTestStubs, fooSystemStubs)
178 checkAPIScopeStubs("other", otherInfo, java.CorePlatformHiddenAPIScope)
Paul Duffinf1b358c2021-05-17 07:38:47 +0100179}
180
Paul Duffin94f19632021-04-20 12:40:07 +0100181func TestBootclasspathFragmentInArtApex(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700182 t.Parallel()
Paul Duffinba6afd02019-11-19 19:44:10 +0000183 commonPreparer := android.GroupFixturePreparers(
Paul Duffin94f19632021-04-20 12:40:07 +0100184 prepareForTestWithBootclasspathFragment,
Paul Duffin9ea71c02021-03-23 22:53:07 +0000185 prepareForTestWithArtApex,
186
Paul Duffinba6afd02019-11-19 19:44:10 +0000187 android.FixtureWithRootAndroidBp(`
Paul Duffina1d60252021-01-21 18:13:43 +0000188 apex {
Paul Duffin9ea71c02021-03-23 22:53:07 +0000189 name: "com.android.art",
190 key: "com.android.art.key",
Paul Duffin94f19632021-04-20 12:40:07 +0100191 bootclasspath_fragments: [
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100192 "art-bootclasspath-fragment",
Paul Duffina1d60252021-01-21 18:13:43 +0000193 ],
Paul Duffin4d101b62021-03-24 15:42:20 +0000194 // bar (like foo) should be transitively included in this apex because it is part of the
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100195 // art-bootclasspath-fragment bootclasspath_fragment.
Mathew Inwoodf8dcf5e2021-02-16 11:40:16 +0000196 updatable: false,
Paul Duffina1d60252021-01-21 18:13:43 +0000197 }
198
Spandan Das7fd531f2024-06-05 19:27:18 +0000199 override_apex {
200 name: "com.mycompany.android.art",
201 base: "com.android.art",
202 min_sdk_version: "33", // mycompany overrides the min_sdk_version
203 }
204
Paul Duffina1d60252021-01-21 18:13:43 +0000205 apex_key {
Paul Duffin9ea71c02021-03-23 22:53:07 +0000206 name: "com.android.art.key",
Paul Duffina1d60252021-01-21 18:13:43 +0000207 public_key: "testkey.avbpubkey",
208 private_key: "testkey.pem",
209 }
Paul Duffinba6afd02019-11-19 19:44:10 +0000210 `),
211 )
Paul Duffin65898052021-04-20 22:47:03 +0100212
Paul Duffinba6afd02019-11-19 19:44:10 +0000213 contentsInsert := func(contents []string) string {
214 insert := ""
215 if contents != nil {
216 insert = fmt.Sprintf(`contents: ["%s"],`, strings.Join(contents, `", "`))
Paul Duffin396229f2021-03-18 18:30:31 +0000217 }
Paul Duffinba6afd02019-11-19 19:44:10 +0000218 return insert
219 }
Paul Duffina1d60252021-01-21 18:13:43 +0000220
Paul Duffinba6afd02019-11-19 19:44:10 +0000221 addSource := func(contents ...string) android.FixturePreparer {
222 text := fmt.Sprintf(`
223 bootclasspath_fragment {
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100224 name: "art-bootclasspath-fragment",
Paul Duffinba6afd02019-11-19 19:44:10 +0000225 image_name: "art",
226 %s
227 apex_available: [
228 "com.android.art",
229 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100230 hidden_api: {
231 split_packages: ["*"],
232 },
Paul Duffinba6afd02019-11-19 19:44:10 +0000233 }
234 `, contentsInsert(contents))
235
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100236 for _, content := range contents {
237 text += fmt.Sprintf(`
238 java_library {
239 name: "%[1]s",
240 srcs: ["%[1]s.java"],
241 installable: true,
242 apex_available: [
243 "com.android.art",
244 ],
Colin Cross09dbc012024-12-18 13:45:58 -0800245 min_sdk_version: "33",
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100246 }
247 `, content)
248 }
249
Paul Duffinba6afd02019-11-19 19:44:10 +0000250 return android.FixtureAddTextFile("art/build/boot/Android.bp", text)
251 }
252
253 addPrebuilt := func(prefer bool, contents ...string) android.FixturePreparer {
254 text := fmt.Sprintf(`
Paul Duffince918b02021-06-07 14:33:47 +0100255 prebuilt_apex {
256 name: "com.android.art",
257 arch: {
258 arm64: {
259 src: "com.android.art-arm64.apex",
260 },
261 arm: {
262 src: "com.android.art-arm.apex",
263 },
264 },
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100265 exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
Paul Duffince918b02021-06-07 14:33:47 +0100266 }
267
Paul Duffinba6afd02019-11-19 19:44:10 +0000268 prebuilt_bootclasspath_fragment {
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100269 name: "art-bootclasspath-fragment",
Paul Duffinba6afd02019-11-19 19:44:10 +0000270 image_name: "art",
271 %s
272 prefer: %t,
273 apex_available: [
274 "com.android.art",
275 ],
Paul Duffin54e41972021-07-19 13:23:40 +0100276 hidden_api: {
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100277 annotation_flags: "hiddenapi/annotation-flags.csv",
278 metadata: "hiddenapi/metadata.csv",
279 index: "hiddenapi/index.csv",
280 stub_flags: "hiddenapi/stub-flags.csv",
281 all_flags: "hiddenapi/all-flags.csv",
Paul Duffin54e41972021-07-19 13:23:40 +0100282 },
Paul Duffinba6afd02019-11-19 19:44:10 +0000283 }
284 `, contentsInsert(contents), prefer)
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100285
286 for _, content := range contents {
287 text += fmt.Sprintf(`
288 java_import {
289 name: "%[1]s",
290 prefer: %[2]t,
291 jars: ["%[1]s.jar"],
292 apex_available: [
293 "com.android.art",
294 ],
295 compile_dex: true,
296 }
297 `, content, prefer)
298 }
299
Paul Duffinba6afd02019-11-19 19:44:10 +0000300 return android.FixtureAddTextFile("prebuilts/module_sdk/art/Android.bp", text)
301 }
302
Paul Duffince918b02021-06-07 14:33:47 +0100303 t.Run("boot image files from source", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700304 t.Parallel()
Paul Duffince918b02021-06-07 14:33:47 +0100305 result := android.GroupFixturePreparers(
306 commonPreparer,
307
308 // Configure some libraries in the art bootclasspath_fragment that match the source
309 // bootclasspath_fragment's contents property.
310 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
Jiakai Zhang556bdf82023-07-12 16:51:57 +0100311 dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
Paul Duffince918b02021-06-07 14:33:47 +0100312 addSource("foo", "bar"),
Jiakai Zhang6decef92022-01-12 17:56:19 +0000313 java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
Paul Duffince918b02021-06-07 14:33:47 +0100314 ).RunTest(t)
315
Jooyung Hana0503a52023-08-23 13:12:50 +0900316 ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
Jiakai Zhang49b1eb62021-11-26 18:09:27 +0000317 "etc/boot-image.prof",
Paul Duffince918b02021-06-07 14:33:47 +0100318 "etc/classpaths/bootclasspath.pb",
Paul Duffince918b02021-06-07 14:33:47 +0100319 "javalib/bar.jar",
320 "javalib/foo.jar",
321 })
322
Jooyung Hana0503a52023-08-23 13:12:50 +0900323 java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
Colin Cross388c6612025-01-28 14:00:12 -0800324 `all_apex_contributions`,
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100325 `art-bootclasspath-fragment`,
Paul Duffince918b02021-06-07 14:33:47 +0100326 `com.android.art.key`,
Spandan Dase21a8d42024-01-23 23:56:29 +0000327 `dex2oatd`,
Paul Duffince918b02021-06-07 14:33:47 +0100328 })
329
330 // Make sure that the source bootclasspath_fragment copies its dex files to the predefined
331 // locations for the art image.
Jiakai Zhangcb13b5d2023-07-13 11:03:38 +0100332 module := result.ModuleForTests("dex_bootjars", "android_common")
Paul Duffince918b02021-06-07 14:33:47 +0100333 checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
334 })
335
Spandan Das7fd531f2024-06-05 19:27:18 +0000336 t.Run("boot image files from source of override apex", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700337 t.Parallel()
Spandan Das7fd531f2024-06-05 19:27:18 +0000338 result := android.GroupFixturePreparers(
339 commonPreparer,
340
341 // Configure some libraries in the art bootclasspath_fragment that match the source
342 // bootclasspath_fragment's contents property.
343 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
344 dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
345 addSource("foo", "bar"),
346 java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
347 ).RunTest(t)
348
349 ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.mycompany.android.art_com.mycompany.android.art", []string{
350 "etc/boot-image.prof",
351 "etc/classpaths/bootclasspath.pb",
352 "javalib/bar.jar",
353 "javalib/foo.jar",
354 })
355 })
356
Jiakai Zhangbc698cd2023-05-08 16:28:38 +0000357 t.Run("generate boot image profile even if dexpreopt is disabled", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700358 t.Parallel()
Jiakai Zhangbc698cd2023-05-08 16:28:38 +0000359 result := android.GroupFixturePreparers(
360 commonPreparer,
361
362 // Configure some libraries in the art bootclasspath_fragment that match the source
363 // bootclasspath_fragment's contents property.
364 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
365 addSource("foo", "bar"),
366 java.FixtureSetBootImageInstallDirOnDevice("art", "system/framework"),
367 dexpreopt.FixtureDisableDexpreoptBootImages(true),
368 ).RunTest(t)
369
Jooyung Hana0503a52023-08-23 13:12:50 +0900370 ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
Jiakai Zhangbc698cd2023-05-08 16:28:38 +0000371 "etc/boot-image.prof",
372 "etc/classpaths/bootclasspath.pb",
373 "javalib/bar.jar",
374 "javalib/foo.jar",
375 })
376 })
377
Jiakai Zhang7d3c9e02021-12-13 17:19:05 +0000378 t.Run("boot image disable generate profile", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700379 t.Parallel()
Jiakai Zhang7d3c9e02021-12-13 17:19:05 +0000380 result := android.GroupFixturePreparers(
381 commonPreparer,
382
383 // Configure some libraries in the art bootclasspath_fragment that match the source
384 // bootclasspath_fragment's contents property.
385 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
386 addSource("foo", "bar"),
387 dexpreopt.FixtureDisableGenerateProfile(true),
388 ).RunTest(t)
389
Jooyung Hana0503a52023-08-23 13:12:50 +0900390 files := getFiles(t, result.TestContext, "com.android.art", "android_common_com.android.art")
Jiakai Zhang7d3c9e02021-12-13 17:19:05 +0000391 for _, file := range files {
392 matched, _ := path.Match("etc/boot-image.prof", file.path)
393 android.AssertBoolEquals(t, "\"etc/boot-image.prof\" should not be in the APEX", matched, false)
394 }
395 })
396
Paul Duffince918b02021-06-07 14:33:47 +0100397 t.Run("boot image files with preferred prebuilt", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700398 t.Parallel()
Paul Duffinba6afd02019-11-19 19:44:10 +0000399 result := android.GroupFixturePreparers(
400 commonPreparer,
401
402 // Configure some libraries in the art bootclasspath_fragment that match the source
403 // bootclasspath_fragment's contents property.
404 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
Jiakai Zhang556bdf82023-07-12 16:51:57 +0100405 dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
Paul Duffinba6afd02019-11-19 19:44:10 +0000406 addSource("foo", "bar"),
407
408 // Make sure that a preferred prebuilt with consistent contents doesn't affect the apex.
409 addPrebuilt(true, "foo", "bar"),
Spandan Das52c01a12024-09-20 01:09:48 +0000410 android.FixtureMergeMockFs(android.MockFS{
411 "apex_contributions/Android.bp": []byte(`
412 apex_contributions {
413 name: "prebuilt_art_contributions",
414 contents: ["prebuilt_com.android.art"],
415 api_domain: "com.android.art",
416 }
417 `)}),
418 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"),
Jiakai Zhang6decef92022-01-12 17:56:19 +0000419
420 java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
Paul Duffinba6afd02019-11-19 19:44:10 +0000421 ).RunTest(t)
422
Spandan Das52c01a12024-09-20 01:09:48 +0000423 ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common_com.android.art", []string{
Jiakai Zhang49b1eb62021-11-26 18:09:27 +0000424 "etc/boot-image.prof",
Paul Duffinba6afd02019-11-19 19:44:10 +0000425 "javalib/bar.jar",
426 "javalib/foo.jar",
427 })
428
Jooyung Hana0503a52023-08-23 13:12:50 +0900429 java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
Colin Cross388c6612025-01-28 14:00:12 -0800430 `all_apex_contributions`,
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100431 `art-bootclasspath-fragment`,
Paul Duffinba6afd02019-11-19 19:44:10 +0000432 `com.android.art.key`,
Spandan Dase21a8d42024-01-23 23:56:29 +0000433 `dex2oatd`,
Paul Duffince918b02021-06-07 14:33:47 +0100434 `prebuilt_com.android.art`,
Paul Duffinba6afd02019-11-19 19:44:10 +0000435 })
Paul Duffince918b02021-06-07 14:33:47 +0100436
437 // Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
438 // locations for the art image.
Jiakai Zhangcb13b5d2023-07-13 11:03:38 +0100439 module := result.ModuleForTests("dex_bootjars", "android_common")
Paul Duffince918b02021-06-07 14:33:47 +0100440 checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
Paul Duffina1d60252021-01-21 18:13:43 +0000441 })
Paul Duffin396229f2021-03-18 18:30:31 +0000442
Paul Duffinba6afd02019-11-19 19:44:10 +0000443 t.Run("source with inconsistency between config and contents", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700444 t.Parallel()
Paul Duffinba6afd02019-11-19 19:44:10 +0000445 android.GroupFixturePreparers(
446 commonPreparer,
447
448 // Create an inconsistency between the ArtApexJars configuration and the art source
449 // bootclasspath_fragment module's contents property.
450 java.FixtureConfigureBootJars("com.android.art:foo"),
451 addSource("foo", "bar"),
452 ).
453 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
454 RunTest(t)
455 })
456
457 t.Run("prebuilt with inconsistency between config and contents", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700458 t.Parallel()
Paul Duffinba6afd02019-11-19 19:44:10 +0000459 android.GroupFixturePreparers(
460 commonPreparer,
461
462 // Create an inconsistency between the ArtApexJars configuration and the art
463 // prebuilt_bootclasspath_fragment module's contents property.
464 java.FixtureConfigureBootJars("com.android.art:foo"),
465 addPrebuilt(false, "foo", "bar"),
466 ).
467 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
468 RunTest(t)
469 })
470
471 t.Run("preferred prebuilt with inconsistency between config and contents", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700472 t.Parallel()
Paul Duffinba6afd02019-11-19 19:44:10 +0000473 android.GroupFixturePreparers(
474 commonPreparer,
475
476 // Create an inconsistency between the ArtApexJars configuration and the art
477 // prebuilt_bootclasspath_fragment module's contents property.
478 java.FixtureConfigureBootJars("com.android.art:foo"),
479 addPrebuilt(true, "foo", "bar"),
480
481 // Source contents property is consistent with the config.
482 addSource("foo"),
483 ).
484 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`\QArtApexJars configuration specifies []string{"foo"}, contents property specifies []string{"foo", "bar"}\E`)).
485 RunTest(t)
486 })
487
488 t.Run("source preferred and prebuilt with inconsistency between config and contents", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700489 t.Parallel()
Paul Duffinba6afd02019-11-19 19:44:10 +0000490 android.GroupFixturePreparers(
491 commonPreparer,
492
493 // Create an inconsistency between the ArtApexJars configuration and the art
494 // prebuilt_bootclasspath_fragment module's contents property.
495 java.FixtureConfigureBootJars("com.android.art:foo"),
496 addPrebuilt(false, "foo", "bar"),
497
498 // Source contents property is consistent with the config.
499 addSource("foo"),
500
501 // This should pass because while the prebuilt is inconsistent with the configuration it is
502 // not actually used.
503 ).RunTest(t)
Paul Duffin396229f2021-03-18 18:30:31 +0000504 })
Paul Duffina1d60252021-01-21 18:13:43 +0000505}
506
Paul Duffin94f19632021-04-20 12:40:07 +0100507func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700508 t.Parallel()
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100509 preparers := android.GroupFixturePreparers(
Paul Duffin94f19632021-04-20 12:40:07 +0100510 prepareForTestWithBootclasspathFragment,
Paul Duffin9ea71c02021-03-23 22:53:07 +0000511 prepareForTestWithArtApex,
512
513 android.FixtureMergeMockFs(android.MockFS{
514 "com.android.art-arm64.apex": nil,
515 "com.android.art-arm.apex": nil,
516 }),
517
Paul Duffin7771eba2021-04-23 14:25:28 +0100518 // Configure some libraries in the art bootclasspath_fragment.
Paul Duffin60264a02021-04-12 20:02:36 +0100519 java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
Jiakai Zhang556bdf82023-07-12 16:51:57 +0100520 dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
Jiakai Zhange6e90db2022-01-28 14:58:56 +0000521 java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
Spandan Das52c01a12024-09-20 01:09:48 +0000522 android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"),
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100523 )
524
525 bp := `
Paul Duffin9ea71c02021-03-23 22:53:07 +0000526 prebuilt_apex {
527 name: "com.android.art",
528 arch: {
529 arm64: {
530 src: "com.android.art-arm64.apex",
531 },
532 arm: {
533 src: "com.android.art-arm.apex",
534 },
535 },
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100536 exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
Paul Duffin9ea71c02021-03-23 22:53:07 +0000537 }
538
539 java_import {
540 name: "foo",
541 jars: ["foo.jar"],
542 apex_available: [
543 "com.android.art",
544 ],
545 }
546
547 java_import {
548 name: "bar",
549 jars: ["bar.jar"],
550 apex_available: [
551 "com.android.art",
552 ],
553 }
554
Paul Duffin7771eba2021-04-23 14:25:28 +0100555 prebuilt_bootclasspath_fragment {
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100556 name: "art-bootclasspath-fragment",
Paul Duffin9ea71c02021-03-23 22:53:07 +0000557 image_name: "art",
Paul Duffinf23bc472021-04-27 12:42:20 +0100558 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
559 contents: ["foo", "bar"],
Paul Duffin9ea71c02021-03-23 22:53:07 +0000560 apex_available: [
561 "com.android.art",
562 ],
Paul Duffin54e41972021-07-19 13:23:40 +0100563 hidden_api: {
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100564 annotation_flags: "hiddenapi/annotation-flags.csv",
565 metadata: "hiddenapi/metadata.csv",
566 index: "hiddenapi/index.csv",
567 stub_flags: "hiddenapi/stub-flags.csv",
568 all_flags: "hiddenapi/all-flags.csv",
Paul Duffin54e41972021-07-19 13:23:40 +0100569 },
Paul Duffin9ea71c02021-03-23 22:53:07 +0000570 }
Paul Duffin9ea71c02021-03-23 22:53:07 +0000571
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100572 // A prebuilt apex with the same apex_name that shouldn't interfere when it isn't enabled.
573 prebuilt_apex {
574 name: "com.mycompany.android.art",
575 apex_name: "com.android.art",
576 %s
577 src: "com.mycompany.android.art.apex",
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100578 exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100579 }
Spandan Das52c01a12024-09-20 01:09:48 +0000580
581 apex_contributions {
582 name: "prebuilt_art_contributions",
583 contents: ["prebuilt_com.android.art"],
584 api_domain: "com.android.art",
585 }
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100586 `
587
588 t.Run("disabled alternative APEX", func(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700589 t.Parallel()
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100590 result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,"))
591
592 java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
Spandan Das85bd4622024-08-01 00:51:20 +0000593 `all_apex_contributions`,
Spandan Das2069c3f2023-12-06 19:40:24 +0000594 `dex2oatd`,
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100595 `prebuilt_art-bootclasspath-fragment`,
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100596 })
597
Jiakai Zhangb69e8952023-07-11 14:31:22 +0100598 java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{
Spandan Das85bd4622024-08-01 00:51:20 +0000599 `all_apex_contributions`,
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100600 `dex2oatd`,
601 `prebuilt_bar`,
602 `prebuilt_foo`,
603 })
604
Jiakai Zhangcb13b5d2023-07-13 11:03:38 +0100605 module := result.ModuleForTests("dex_bootjars", "android_common")
Martin Stjernholm43c44b02021-06-30 16:35:07 +0100606 checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
Paul Duffin9ea71c02021-03-23 22:53:07 +0000607 })
Paul Duffince918b02021-06-07 14:33:47 +0100608}
609
610// checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the
611// predefined locations of boot dex jars used as inputs for the ART boot image.
612func checkCopiesToPredefinedLocationForArt(t *testing.T, config android.Config, module android.TestingModule, modules ...string) {
613 t.Helper()
614 bootJarLocations := []string{}
615 for _, output := range module.AllOutputs() {
616 output = android.StringRelativeToTop(config, output)
Jeongik Cha4753b392023-04-19 23:25:41 +0900617 if strings.HasPrefix(output, "out/soong/dexpreopt_arm64/dex_artjars_input/") {
Paul Duffince918b02021-06-07 14:33:47 +0100618 bootJarLocations = append(bootJarLocations, output)
619 }
620 }
621
622 sort.Strings(bootJarLocations)
623 expected := []string{}
624 for _, m := range modules {
Jeongik Cha4753b392023-04-19 23:25:41 +0900625 expected = append(expected, fmt.Sprintf("out/soong/dexpreopt_arm64/dex_artjars_input/%s.jar", m))
Paul Duffince918b02021-06-07 14:33:47 +0100626 }
627 sort.Strings(expected)
628
629 android.AssertArrayString(t, "copies to predefined locations for art", expected, bootJarLocations)
Paul Duffin9ea71c02021-03-23 22:53:07 +0000630}
631
Paul Duffin94f19632021-04-20 12:40:07 +0100632func TestBootclasspathFragmentContentsNoName(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700633 t.Parallel()
Paul Duffin82886d62021-03-24 01:34:57 +0000634 result := android.GroupFixturePreparers(
Paul Duffin94f19632021-04-20 12:40:07 +0100635 prepareForTestWithBootclasspathFragment,
Paul Duffin82886d62021-03-24 01:34:57 +0000636 prepareForTestWithMyapex,
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100637 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
satayevabcd5972021-08-06 17:49:46 +0100638 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100639 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
640 // is disabled.
641 android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
642
643 java.PrepareForTestWithJavaSdkLibraryFiles,
644 java.FixtureWithLastReleaseApis("foo"),
Paul Duffin82886d62021-03-24 01:34:57 +0000645 ).RunTestWithBp(t, `
646 apex {
647 name: "myapex",
648 key: "myapex.key",
Paul Duffin94f19632021-04-20 12:40:07 +0100649 bootclasspath_fragments: [
650 "mybootclasspathfragment",
Paul Duffin82886d62021-03-24 01:34:57 +0000651 ],
652 updatable: false,
653 }
654
655 apex_key {
656 name: "myapex.key",
657 public_key: "testkey.avbpubkey",
658 private_key: "testkey.pem",
659 }
660
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100661 java_sdk_library {
Paul Duffin82886d62021-03-24 01:34:57 +0000662 name: "foo",
663 srcs: ["b.java"],
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100664 shared_library: false,
665 public: {enabled: true},
Paul Duffin82886d62021-03-24 01:34:57 +0000666 apex_available: [
667 "myapex",
668 ],
669 }
670
671 java_library {
672 name: "bar",
673 srcs: ["b.java"],
674 installable: true,
675 apex_available: [
676 "myapex",
677 ],
678 }
679
Paul Duffin7771eba2021-04-23 14:25:28 +0100680 bootclasspath_fragment {
Paul Duffin94f19632021-04-20 12:40:07 +0100681 name: "mybootclasspathfragment",
Paul Duffin82886d62021-03-24 01:34:57 +0000682 contents: [
683 "foo",
684 "bar",
685 ],
686 apex_available: [
687 "myapex",
688 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100689 hidden_api: {
690 split_packages: ["*"],
691 },
Paul Duffin82886d62021-03-24 01:34:57 +0000692 }
693 `)
694
Jooyung Hana0503a52023-08-23 13:12:50 +0900695 ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex", []string{
Paul Duffin4d101b62021-03-24 15:42:20 +0000696 // This does not include art, oat or vdex files as they are only included for the art boot
697 // image.
satayev227e7452021-05-20 21:35:06 +0100698 "etc/classpaths/bootclasspath.pb",
Paul Duffin4d101b62021-03-24 15:42:20 +0000699 "javalib/bar.jar",
700 "javalib/foo.jar",
701 })
Paul Duffin82886d62021-03-24 01:34:57 +0000702
Jooyung Hana0503a52023-08-23 13:12:50 +0900703 java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
Colin Cross388c6612025-01-28 14:00:12 -0800704 `all_apex_contributions`,
Spandan Dase21a8d42024-01-23 23:56:29 +0000705 `dex2oatd`,
Paul Duffin82886d62021-03-24 01:34:57 +0000706 `myapex.key`,
Paul Duffin94f19632021-04-20 12:40:07 +0100707 `mybootclasspathfragment`,
Paul Duffin82886d62021-03-24 01:34:57 +0000708 })
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100709
Jooyung Hana0503a52023-08-23 13:12:50 +0900710 apex := result.ModuleForTests("myapex", "android_common_myapex")
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100711 apexRule := apex.Rule("apexRule")
712 copyCommands := apexRule.Args["copy_commands"]
713
714 // Make sure that the fragment provides the hidden API encoded dex jars to the APEX.
715 fragment := result.Module("mybootclasspathfragment", "android_common_apex10000")
716
Yu Liu663e4502024-08-12 18:23:59 +0000717 info, _ := android.OtherModuleProvider(result, fragment, java.BootclasspathFragmentApexContentInfoProvider)
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100718
719 checkFragmentExportedDexJar := func(name string, expectedDexJar string) {
720 module := result.Module(name, "android_common_apex10000")
Paul Duffin1a8010a2021-05-15 12:39:23 +0100721 dexJar, err := info.DexBootJarPathForContentModule(module)
722 if err != nil {
723 t.Error(err)
724 }
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100725 android.AssertPathRelativeToTopEquals(t, name+" dex", expectedDexJar, dexJar)
726
Jooyung Hana0503a52023-08-23 13:12:50 +0900727 expectedCopyCommand := fmt.Sprintf("&& cp -f %s out/soong/.intermediates/myapex/android_common_myapex/image.apex/javalib/%s.jar", expectedDexJar, name)
Paul Duffinf2fa0b52021-05-14 18:21:45 +0100728 android.AssertStringDoesContain(t, name+" apex copy command", copyCommands, expectedCopyCommand)
729 }
730
Paul Duffin54c98f52021-05-15 08:54:30 +0100731 checkFragmentExportedDexJar("foo", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/foo.jar")
732 checkFragmentExportedDexJar("bar", "out/soong/.intermediates/mybootclasspathfragment/android_common_apex10000/hiddenapi-modular/encoded/bar.jar")
Paul Duffin82886d62021-03-24 01:34:57 +0000733}
734
Paul Duffin48b67412021-06-23 16:13:50 +0100735func getDexJarPath(result *android.TestResult, name string) string {
736 module := result.Module(name, "android_common")
Spandan Das59a4a2b2024-01-09 21:35:56 +0000737 return module.(java.UsesLibraryDependency).DexJarBuildPath(moduleErrorfTestCtx{}).Path().RelativeToTop().String()
Paul Duffin48b67412021-06-23 16:13:50 +0100738}
739
740// TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
741// passed to the hiddenapi list tool.
742func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700743 t.Parallel()
Paul Duffin48b67412021-06-23 16:13:50 +0100744 result := android.GroupFixturePreparers(
745 prepareForTestWithBootclasspathFragment,
746 prepareForTestWithArtApex,
747 prepareForTestWithMyapex,
748 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
749 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
satayevd604b212021-07-21 14:23:52 +0100750 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
Paul Duffin48b67412021-06-23 16:13:50 +0100751 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
752 // is disabled.
753 android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
754
755 java.PrepareForTestWithJavaSdkLibraryFiles,
756 java.FixtureWithLastReleaseApis("foo", "quuz"),
Colin Crossa66b4632024-08-08 15:50:47 -0700757 android.PrepareForTestWithBuildFlag("RELEASE_HIDDEN_API_EXPORTABLE_STUBS", "true"),
Paul Duffin48b67412021-06-23 16:13:50 +0100758 ).RunTestWithBp(t, `
759 apex {
760 name: "com.android.art",
761 key: "com.android.art.key",
762 bootclasspath_fragments: ["art-bootclasspath-fragment"],
763 updatable: false,
764 }
765
766 apex_key {
767 name: "com.android.art.key",
768 public_key: "com.android.art.avbpubkey",
769 private_key: "com.android.art.pem",
770 }
771
772 java_library {
773 name: "baz",
774 apex_available: [
775 "com.android.art",
776 ],
777 srcs: ["b.java"],
778 compile_dex: true,
Jihoon Kang85bc1932024-07-01 17:04:46 +0000779 sdk_version: "core_current",
Paul Duffin48b67412021-06-23 16:13:50 +0100780 }
781
782 java_sdk_library {
783 name: "quuz",
784 apex_available: [
785 "com.android.art",
786 ],
787 srcs: ["b.java"],
788 compile_dex: true,
789 public: {enabled: true},
790 system: {enabled: true},
791 test: {enabled: true},
792 module_lib: {enabled: true},
793 }
794
795 bootclasspath_fragment {
796 name: "art-bootclasspath-fragment",
797 image_name: "art",
798 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
799 contents: ["baz", "quuz"],
800 apex_available: [
801 "com.android.art",
802 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100803 hidden_api: {
804 split_packages: ["*"],
805 },
Paul Duffin48b67412021-06-23 16:13:50 +0100806 }
807
808 apex {
809 name: "myapex",
810 key: "myapex.key",
811 bootclasspath_fragments: [
812 "mybootclasspathfragment",
813 ],
814 updatable: false,
815 }
816
817 apex_key {
818 name: "myapex.key",
819 public_key: "testkey.avbpubkey",
820 private_key: "testkey.pem",
821 }
822
823 java_sdk_library {
824 name: "foo",
825 srcs: ["b.java"],
826 shared_library: false,
827 public: {enabled: true},
828 apex_available: [
829 "myapex",
830 ],
831 }
832
833 java_library {
834 name: "bar",
835 srcs: ["b.java"],
836 installable: true,
837 apex_available: [
838 "myapex",
839 ],
840 }
841
842 bootclasspath_fragment {
843 name: "mybootclasspathfragment",
844 contents: [
845 "foo",
846 "bar",
847 ],
848 apex_available: [
849 "myapex",
850 ],
851 fragments: [
852 {
853 apex: "com.android.art",
854 module: "art-bootclasspath-fragment",
855 },
856 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100857 hidden_api: {
858 split_packages: ["*"],
859 },
Paul Duffin48b67412021-06-23 16:13:50 +0100860 }
861 `)
862
863 java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
Spandan Das16791922024-09-06 00:49:31 +0000864 "all_apex_contributions",
Paul Duffin48b67412021-06-23 16:13:50 +0100865 "art-bootclasspath-fragment",
866 "bar",
867 "dex2oatd",
868 "foo",
869 })
870
Jihoon Kangbd093452023-12-26 19:08:01 +0000871 fooStubs := getDexJarPath(result, "foo.stubs.exportable")
872 quuzPublicStubs := getDexJarPath(result, "quuz.stubs.exportable")
873 quuzSystemStubs := getDexJarPath(result, "quuz.stubs.exportable.system")
874 quuzTestStubs := getDexJarPath(result, "quuz.stubs.exportable.test")
875 quuzModuleLibStubs := getDexJarPath(result, "quuz.stubs.exportable.module_lib")
Paul Duffin48b67412021-06-23 16:13:50 +0100876
877 // Make sure that the fragment uses the quuz stub dex jars when generating the hidden API flags.
878 fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
879
880 rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
881 command := rule.RuleParams.Command
882 android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
883
884 // Make sure that the quuz stubs are available for resolving references from the implementation
885 // boot dex jars provided by this module.
Paul Duffinb51db2e2021-06-21 14:08:08 +0100886 android.AssertStringDoesContain(t, "quuz widest", command, "--dependency-stub-dex="+quuzModuleLibStubs)
Paul Duffin48b67412021-06-23 16:13:50 +0100887
888 // Make sure that the quuz stubs are available for resolving references from the different API
889 // stubs provided by this module.
890 android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+quuzPublicStubs+":"+fooStubs)
891 android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+quuzSystemStubs+":"+fooStubs)
892 android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+quuzTestStubs+":"+fooStubs)
893}
894
Paul Duffin5cca7c42021-05-26 10:16:01 +0100895// TestBootclasspathFragment_AndroidNonUpdatable checks to make sure that setting
896// additional_stubs: ["android-non-updatable"] causes the source android-non-updatable modules to be
897// added to the hiddenapi list tool.
Jihoon Kangcc9e2182023-10-16 23:13:33 +0000898func TestBootclasspathFragment_AndroidNonUpdatable_FromSource(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -0700899 t.Parallel()
Paul Duffin5cca7c42021-05-26 10:16:01 +0100900 result := android.GroupFixturePreparers(
901 prepareForTestWithBootclasspathFragment,
902 prepareForTestWithArtApex,
903 prepareForTestWithMyapex,
904 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
satayevabcd5972021-08-06 17:49:46 +0100905 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
906 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
Paul Duffin5cca7c42021-05-26 10:16:01 +0100907 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
908 // is disabled.
909 android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
Jihoon Kangcc9e2182023-10-16 23:13:33 +0000910 android.FixtureModifyConfig(func(config android.Config) {
911 config.SetBuildFromTextStub(false)
912 }),
Paul Duffin5cca7c42021-05-26 10:16:01 +0100913
914 java.PrepareForTestWithJavaSdkLibraryFiles,
915 java.FixtureWithLastReleaseApis("foo", "android-non-updatable"),
916 ).RunTestWithBp(t, `
917 java_sdk_library {
918 name: "android-non-updatable",
919 srcs: ["b.java"],
920 compile_dex: true,
921 public: {
922 enabled: true,
923 },
924 system: {
925 enabled: true,
926 },
927 test: {
928 enabled: true,
929 },
930 module_lib: {
931 enabled: true,
932 },
933 }
934
935 apex {
936 name: "com.android.art",
937 key: "com.android.art.key",
938 bootclasspath_fragments: ["art-bootclasspath-fragment"],
Paul Duffin5cca7c42021-05-26 10:16:01 +0100939 updatable: false,
940 }
941
942 apex_key {
943 name: "com.android.art.key",
944 public_key: "com.android.art.avbpubkey",
945 private_key: "com.android.art.pem",
946 }
947
948 java_library {
949 name: "baz",
950 apex_available: [
951 "com.android.art",
952 ],
953 srcs: ["b.java"],
954 compile_dex: true,
Jihoon Kang85bc1932024-07-01 17:04:46 +0000955 sdk_version: "core_current",
Paul Duffin5cca7c42021-05-26 10:16:01 +0100956 }
957
958 java_library {
959 name: "quuz",
960 apex_available: [
961 "com.android.art",
962 ],
963 srcs: ["b.java"],
964 compile_dex: true,
965 }
966
967 bootclasspath_fragment {
968 name: "art-bootclasspath-fragment",
969 image_name: "art",
970 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
971 contents: ["baz", "quuz"],
972 apex_available: [
973 "com.android.art",
974 ],
Paul Duffin9fd56472022-03-31 15:42:30 +0100975 hidden_api: {
976 split_packages: ["*"],
977 },
Paul Duffin5cca7c42021-05-26 10:16:01 +0100978 }
979
980 apex {
981 name: "myapex",
982 key: "myapex.key",
983 bootclasspath_fragments: [
984 "mybootclasspathfragment",
985 ],
986 updatable: false,
987 }
988
989 apex_key {
990 name: "myapex.key",
991 public_key: "testkey.avbpubkey",
992 private_key: "testkey.pem",
993 }
994
995 java_sdk_library {
996 name: "foo",
997 srcs: ["b.java"],
998 shared_library: false,
999 public: {enabled: true},
1000 apex_available: [
1001 "myapex",
1002 ],
1003 }
1004
1005 java_library {
1006 name: "bar",
1007 srcs: ["b.java"],
1008 installable: true,
1009 apex_available: [
1010 "myapex",
1011 ],
1012 }
1013
1014 bootclasspath_fragment {
1015 name: "mybootclasspathfragment",
1016 contents: [
1017 "foo",
1018 "bar",
1019 ],
1020 apex_available: [
1021 "myapex",
1022 ],
1023 additional_stubs: ["android-non-updatable"],
1024 fragments: [
1025 {
1026 apex: "com.android.art",
1027 module: "art-bootclasspath-fragment",
1028 },
1029 ],
Paul Duffin9fd56472022-03-31 15:42:30 +01001030 hidden_api: {
1031 split_packages: ["*"],
1032 },
Paul Duffin5cca7c42021-05-26 10:16:01 +01001033 }
1034 `)
1035
1036 java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
Spandan Das16791922024-09-06 00:49:31 +00001037 "all_apex_contributions",
Paul Duffin5cca7c42021-05-26 10:16:01 +01001038 "android-non-updatable.stubs",
1039 "android-non-updatable.stubs.module_lib",
1040 "android-non-updatable.stubs.system",
1041 "android-non-updatable.stubs.test",
1042 "art-bootclasspath-fragment",
1043 "bar",
1044 "dex2oatd",
1045 "foo",
1046 })
1047
1048 nonUpdatablePublicStubs := getDexJarPath(result, "android-non-updatable.stubs")
1049 nonUpdatableSystemStubs := getDexJarPath(result, "android-non-updatable.stubs.system")
1050 nonUpdatableTestStubs := getDexJarPath(result, "android-non-updatable.stubs.test")
1051 nonUpdatableModuleLibStubs := getDexJarPath(result, "android-non-updatable.stubs.module_lib")
1052
1053 // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
1054 // API flags.
1055 fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
1056
1057 rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
1058 command := rule.RuleParams.Command
1059 android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
1060
1061 // Make sure that the module_lib non-updatable stubs are available for resolving references from
1062 // the implementation boot dex jars provided by this module.
1063 android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
1064
1065 // Make sure that the appropriate non-updatable stubs are available for resolving references from
1066 // the different API stubs provided by this module.
1067 android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
1068 android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
1069 android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
1070}
1071
Jihoon Kangcc9e2182023-10-16 23:13:33 +00001072func TestBootclasspathFragment_AndroidNonUpdatable_FromText(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -07001073 t.Parallel()
Jihoon Kangcc9e2182023-10-16 23:13:33 +00001074 result := android.GroupFixturePreparers(
1075 prepareForTestWithBootclasspathFragment,
1076 prepareForTestWithArtApex,
1077 prepareForTestWithMyapex,
1078 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
1079 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
1080 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
1081 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
1082 // is disabled.
1083 android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
1084 android.FixtureModifyConfig(func(config android.Config) {
1085 config.SetBuildFromTextStub(true)
1086 }),
1087
1088 java.PrepareForTestWithJavaSdkLibraryFiles,
1089 java.FixtureWithLastReleaseApis("foo", "android-non-updatable"),
1090 ).RunTestWithBp(t, `
1091 java_sdk_library {
1092 name: "android-non-updatable",
1093 srcs: ["b.java"],
1094 compile_dex: true,
1095 public: {
1096 enabled: true,
1097 },
1098 system: {
1099 enabled: true,
1100 },
1101 test: {
1102 enabled: true,
1103 },
1104 module_lib: {
1105 enabled: true,
1106 },
1107 }
1108
1109 apex {
1110 name: "com.android.art",
1111 key: "com.android.art.key",
1112 bootclasspath_fragments: ["art-bootclasspath-fragment"],
1113 updatable: false,
1114 }
1115
1116 apex_key {
1117 name: "com.android.art.key",
1118 public_key: "com.android.art.avbpubkey",
1119 private_key: "com.android.art.pem",
1120 }
1121
1122 java_library {
1123 name: "baz",
1124 apex_available: [
1125 "com.android.art",
1126 ],
1127 srcs: ["b.java"],
1128 compile_dex: true,
Jihoon Kang85bc1932024-07-01 17:04:46 +00001129 sdk_version: "core_current",
Jihoon Kangcc9e2182023-10-16 23:13:33 +00001130 }
1131
1132 java_library {
1133 name: "quuz",
1134 apex_available: [
1135 "com.android.art",
1136 ],
1137 srcs: ["b.java"],
1138 compile_dex: true,
1139 }
1140
1141 bootclasspath_fragment {
1142 name: "art-bootclasspath-fragment",
1143 image_name: "art",
1144 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
1145 contents: ["baz", "quuz"],
1146 apex_available: [
1147 "com.android.art",
1148 ],
1149 hidden_api: {
1150 split_packages: ["*"],
1151 },
1152 }
1153
1154 apex {
1155 name: "myapex",
1156 key: "myapex.key",
1157 bootclasspath_fragments: [
1158 "mybootclasspathfragment",
1159 ],
1160 updatable: false,
1161 }
1162
1163 apex_key {
1164 name: "myapex.key",
1165 public_key: "testkey.avbpubkey",
1166 private_key: "testkey.pem",
1167 }
1168
1169 java_sdk_library {
1170 name: "foo",
1171 srcs: ["b.java"],
1172 shared_library: false,
1173 public: {enabled: true},
1174 apex_available: [
1175 "myapex",
1176 ],
1177 }
1178
1179 java_library {
1180 name: "bar",
1181 srcs: ["b.java"],
1182 installable: true,
1183 apex_available: [
1184 "myapex",
1185 ],
1186 }
1187
1188 bootclasspath_fragment {
1189 name: "mybootclasspathfragment",
1190 contents: [
1191 "foo",
1192 "bar",
1193 ],
1194 apex_available: [
1195 "myapex",
1196 ],
1197 additional_stubs: ["android-non-updatable"],
1198 fragments: [
1199 {
1200 apex: "com.android.art",
1201 module: "art-bootclasspath-fragment",
1202 },
1203 ],
1204 hidden_api: {
1205 split_packages: ["*"],
1206 },
1207 }
1208 `)
1209
1210 java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
Spandan Das16791922024-09-06 00:49:31 +00001211 "all_apex_contributions",
Jihoon Kangcc9e2182023-10-16 23:13:33 +00001212 "android-non-updatable.stubs",
1213 "android-non-updatable.stubs.system",
1214 "android-non-updatable.stubs.test",
1215 "android-non-updatable.stubs.test_module_lib",
1216 "art-bootclasspath-fragment",
1217 "bar",
1218 "dex2oatd",
1219 "foo",
1220 })
1221
1222 nonUpdatableTestModuleLibStubs := getDexJarPath(result, "android-non-updatable.stubs.test_module_lib")
1223
1224 // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
1225 // API flags.
1226 fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
1227
1228 rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
1229 command := rule.RuleParams.Command
1230 android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
1231
1232 // Make sure that the test_module_lib non-updatable stubs are available for resolving references from
1233 // the implementation boot dex jars provided by this module.
1234 android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableTestModuleLibStubs)
1235}
1236
Paul Duffin5cca7c42021-05-26 10:16:01 +01001237// TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks checks to make sure that
1238// setting additional_stubs: ["android-non-updatable"] causes the prebuilt android-non-updatable
1239// modules to be added to the hiddenapi list tool.
1240func TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -07001241 t.Parallel()
Paul Duffin5cca7c42021-05-26 10:16:01 +01001242 result := android.GroupFixturePreparers(
1243 prepareForTestWithBootclasspathFragment,
Jiakai Zhangb95998b2023-05-11 16:39:27 +01001244 java.PrepareForTestWithDexpreopt,
Paul Duffin5cca7c42021-05-26 10:16:01 +01001245 prepareForTestWithArtApex,
1246 prepareForTestWithMyapex,
1247 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
satayevabcd5972021-08-06 17:49:46 +01001248 java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz"),
1249 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
Paul Duffin5cca7c42021-05-26 10:16:01 +01001250 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
1251 // is disabled.
1252 android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
1253
1254 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
1255 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
1256 }),
1257
1258 java.PrepareForTestWithJavaSdkLibraryFiles,
1259 java.FixtureWithPrebuiltApis(map[string][]string{
1260 "current": {"android-non-updatable"},
1261 "30": {"foo"},
1262 }),
1263 ).RunTestWithBp(t, `
1264 apex {
1265 name: "com.android.art",
1266 key: "com.android.art.key",
1267 bootclasspath_fragments: ["art-bootclasspath-fragment"],
Paul Duffin5cca7c42021-05-26 10:16:01 +01001268 updatable: false,
1269 }
1270
1271 apex_key {
1272 name: "com.android.art.key",
1273 public_key: "com.android.art.avbpubkey",
1274 private_key: "com.android.art.pem",
1275 }
1276
1277 java_library {
1278 name: "baz",
1279 apex_available: [
1280 "com.android.art",
1281 ],
1282 srcs: ["b.java"],
1283 compile_dex: true,
Jihoon Kang85bc1932024-07-01 17:04:46 +00001284 sdk_version: "core_current",
Paul Duffin5cca7c42021-05-26 10:16:01 +01001285 }
1286
1287 java_library {
1288 name: "quuz",
1289 apex_available: [
1290 "com.android.art",
1291 ],
1292 srcs: ["b.java"],
1293 compile_dex: true,
1294 }
1295
1296 bootclasspath_fragment {
1297 name: "art-bootclasspath-fragment",
1298 image_name: "art",
1299 // Must match the "com.android.art:" entries passed to FixtureConfigureBootJars above.
1300 contents: ["baz", "quuz"],
1301 apex_available: [
1302 "com.android.art",
1303 ],
Paul Duffin9fd56472022-03-31 15:42:30 +01001304 hidden_api: {
1305 split_packages: ["*"],
1306 },
Paul Duffin5cca7c42021-05-26 10:16:01 +01001307 }
1308
1309 apex {
1310 name: "myapex",
1311 key: "myapex.key",
1312 bootclasspath_fragments: [
1313 "mybootclasspathfragment",
1314 ],
1315 updatable: false,
1316 }
1317
1318 apex_key {
1319 name: "myapex.key",
1320 public_key: "testkey.avbpubkey",
1321 private_key: "testkey.pem",
1322 }
1323
1324 java_sdk_library {
1325 name: "foo",
1326 srcs: ["b.java"],
1327 shared_library: false,
1328 public: {enabled: true},
1329 apex_available: [
1330 "myapex",
1331 ],
1332 }
1333
1334 java_library {
1335 name: "bar",
1336 srcs: ["b.java"],
1337 installable: true,
1338 apex_available: [
1339 "myapex",
1340 ],
1341 }
1342
1343 bootclasspath_fragment {
1344 name: "mybootclasspathfragment",
1345 contents: [
1346 "foo",
1347 "bar",
1348 ],
1349 apex_available: [
1350 "myapex",
1351 ],
1352 additional_stubs: ["android-non-updatable"],
1353 fragments: [
1354 {
1355 apex: "com.android.art",
1356 module: "art-bootclasspath-fragment",
1357 },
1358 ],
Paul Duffin9fd56472022-03-31 15:42:30 +01001359 hidden_api: {
1360 split_packages: ["*"],
1361 },
Paul Duffin5cca7c42021-05-26 10:16:01 +01001362 }
1363 `)
1364
1365 java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_apex10000", []string{
Spandan Das16791922024-09-06 00:49:31 +00001366 "all_apex_contributions",
Paul Duffin5cca7c42021-05-26 10:16:01 +01001367 "art-bootclasspath-fragment",
1368 "bar",
1369 "dex2oatd",
1370 "foo",
1371 "prebuilt_sdk_module-lib_current_android-non-updatable",
1372 "prebuilt_sdk_public_current_android-non-updatable",
1373 "prebuilt_sdk_system_current_android-non-updatable",
1374 "prebuilt_sdk_test_current_android-non-updatable",
1375 })
1376
1377 nonUpdatablePublicStubs := getDexJarPath(result, "sdk_public_current_android-non-updatable")
1378 nonUpdatableSystemStubs := getDexJarPath(result, "sdk_system_current_android-non-updatable")
1379 nonUpdatableTestStubs := getDexJarPath(result, "sdk_test_current_android-non-updatable")
1380 nonUpdatableModuleLibStubs := getDexJarPath(result, "sdk_module-lib_current_android-non-updatable")
1381
1382 // Make sure that the fragment uses the android-non-updatable modules when generating the hidden
1383 // API flags.
1384 fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
1385
1386 rule := fragment.Rule("modularHiddenAPIStubFlagsFile")
1387 command := rule.RuleParams.Command
1388 android.AssertStringDoesContain(t, "check correct rule", command, "hiddenapi list")
1389
1390 // Make sure that the module_lib non-updatable stubs are available for resolving references from
1391 // the implementation boot dex jars provided by this module.
1392 android.AssertStringDoesContain(t, "android-non-updatable widest", command, "--dependency-stub-dex="+nonUpdatableModuleLibStubs)
1393
1394 // Make sure that the appropriate non-updatable stubs are available for resolving references from
1395 // the different API stubs provided by this module.
1396 android.AssertStringDoesContain(t, "public", command, "--public-stub-classpath="+nonUpdatablePublicStubs)
1397 android.AssertStringDoesContain(t, "system", command, "--system-stub-classpath="+nonUpdatableSystemStubs)
1398 android.AssertStringDoesContain(t, "test", command, "--test-stub-classpath="+nonUpdatableTestStubs)
1399}
1400
Spandan Dasfcea0a82024-06-12 18:22:46 +00001401func TestBootclasspathFragmentProtoContainsMinSdkVersion(t *testing.T) {
Colin Crossa2fdb612024-10-11 12:52:56 -07001402 t.Parallel()
Spandan Dasfcea0a82024-06-12 18:22:46 +00001403 result := android.GroupFixturePreparers(
1404 prepareForTestWithBootclasspathFragment,
1405 prepareForTestWithMyapex,
1406 // Configure bootclasspath jars to ensure that hidden API encoding is performed on them.
1407 java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"),
1408 // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
1409 // is disabled.
1410 android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
1411
1412 java.PrepareForTestWithJavaSdkLibraryFiles,
1413 java.FixtureWithLastReleaseApis("foo", "bar"),
1414 ).RunTestWithBp(t, `
1415 apex {
1416 name: "myapex",
1417 key: "myapex.key",
1418 bootclasspath_fragments: [
1419 "mybootclasspathfragment",
1420 ],
1421 updatable: false,
1422 }
1423
1424 apex_key {
1425 name: "myapex.key",
1426 public_key: "testkey.avbpubkey",
1427 private_key: "testkey.pem",
1428 }
1429
1430 java_sdk_library {
1431 name: "foo",
1432 srcs: ["b.java"],
1433 shared_library: false,
1434 public: {enabled: true},
1435 apex_available: [
1436 "myapex",
1437 ],
1438 min_sdk_version: "33",
1439 }
1440
1441 java_sdk_library {
1442 name: "bar",
1443 srcs: ["b.java"],
1444 shared_library: false,
1445 public: {enabled: true},
1446 apex_available: [
1447 "myapex",
1448 ],
1449 min_sdk_version: "34",
1450 }
1451
1452 bootclasspath_fragment {
1453 name: "mybootclasspathfragment",
1454 contents: [
1455 "foo",
1456 "bar",
1457 ],
1458 apex_available: [
1459 "myapex",
1460 ],
1461 hidden_api: {
1462 split_packages: ["*"],
1463 },
1464 }
1465 `)
1466
1467 fragment := result.ModuleForTests("mybootclasspathfragment", "android_common_apex10000")
1468 classPathProtoContent := android.ContentFromFileRuleForTests(t, result.TestContext, fragment.Output("bootclasspath.pb.textproto"))
1469 // foo
1470 ensureContains(t, classPathProtoContent, `jars {
1471path: "/apex/myapex/javalib/foo.jar"
1472classpath: BOOTCLASSPATH
1473min_sdk_version: "33"
1474max_sdk_version: ""
1475}
1476`)
1477 // bar
1478 ensureContains(t, classPathProtoContent, `jars {
1479path: "/apex/myapex/javalib/bar.jar"
1480classpath: BOOTCLASSPATH
1481min_sdk_version: "34"
1482max_sdk_version: ""
1483}
1484`)
1485}
1486
Paul Duffina1d60252021-01-21 18:13:43 +00001487// TODO(b/177892522) - add test for host apex.